//
//*******
//
//	filename: drag_and_drop.js
//	author: Zack Brown
//	date: 11th September 2008
//
//	written, with help from: http://aymanh.com/drag-drop-portal-interface-with-scriptaculous
//
//*******
//

//instantiate a new drag and drop class
var DragAndDrop = Class.create();

//create a new class
DragAndDrop.prototype = {

	//wrapper function for init
	initialize: function(options)
	{
		//array of elements
		var droppable_elements = [];
		var draggable_elements = [];
		
		//set options
		this.set_options(options);
		
		//gather all droppable elements
		droppable_elements = parse_array($(this.options.drag_and_drop_wrapper).getElementsByClassName(this.options.droppable));
		
		//iterate through droppable elements
		droppable_elements.each(function(element)
		{
			//create a new sortable from this element
			Sortable.create(element,
			{
				containment: droppable_elements,
				constraint: false,
				tag: 'div',
				only: this.options.draggable,
				dropOnEmpty: true,
				handle: this.options.handle,
				hoverclass: this.options.hover_class,
				onUpdate: function(container)
				{
					//check save url
					if(!this.options.save_url)
					{
						//perish
						return;
					}
					
					//save url to send ajax request
					save_url = this.options.save_url;
					
					//body of content to send via ajax
					var contentBody = container.id + ":";
					
					//gather all draggable elements
					var draggable_elements = parse_array($(container).getElementsByClassName(this.options.draggable));
					
					//compile content
					contentBody += draggable_elements.pluck('id').join(',');
					
					//escape content
					contentBody = 'drag_and_drop=' + escape(contentBody);
					
					//create new ajax request
					new Ajax.Request(save_url, {method: 'post', postBody: contentBody});
					
					//resize droppable element when droppable is added/removed from column
					resize_droppable_area($(container));
				}.bind(this)
			});
		}.bind(this));
		
		//gather all draggable elements
		draggable_elements = parse_array($(this.options.drag_and_drop_wrapper).getElementsByClassName(this.options.draggable));
		
		//iterate through draggable elements
		draggable_elements.each(function(element)
		{
			//gather content for this element
			var content = $(element).getElementsByClassName(this.options.content);
			
			//gather toggler for this element
			var toggle = $(element).getElementsByClassName(this.options.toggle);
			
			//check toggle
			if(toggle == null || toggle == undefined)
			{
				//perish
				return;
			}
			
			//save first elements in arrays
			content = content[0];
			toggle = toggle[0];
			
			//set parent element of content
			content.draggable = $(element).id;
			
			//save url to send ajax request
			save_url = this.options.save_url;
			
			//gather toggle image for this element
			var toggle_image = $(toggle.id);
			
			//check content
			if((trim_whitespace(content.innerHTML) != '<p>&nbsp;</p>' && trim_whitespace(content.innerHTML) != '' && trim_whitespace(content.innerHTML).length > 0) || (content.innerHTML != '<p>&nbsp;</p>' && content.innerHTML != '' && content.length > 0))
			{
				//add event listener
				Event.observe(toggle, 'click', function(event)
				{
					//toggle content
					Effect.toggle(content, 'Slide');
					
					//check content toggle status
					if(content.toggle == 'hide')
					{
						//set content toggle status to display
						content.toggle = 'show';
						
						//switch toggle image
						toggle_image.src = '/images/blue_arrow_toggle_show.gif';
					}
					else
					{
						//set content toggle status to hidden
						content.toggle = 'hide';
						
						//switch toggle image
						toggle_image.src = '/images/blue_arrow_toggle_hide.gif'; 
					}
					
					//body of content to send via ajax
					var contentBody = content.draggable + ":" + content.toggle;
					
					//escape content
					contentBody = 'drag_and_drop_toggle=' + escape(contentBody);
					
					//create new ajax request
					new Ajax.Request(save_url, {method: 'post', postBody: contentBody});
				}, false);
			}
		}.bind(this));
	},
	
	//wrapper function for setting options
	set_options: function(options)
	{
		//set options
		this.options = {
			drag_and_drop_wrapper: 'drag_and_drop_wrapper',
			droppable: 'droppable_wrapper',
			draggable: 'draggable_wrapper',
			content: 'draggable_wrapper_content',
			handle: 'handle',
			hover_class: 'drag_hover',
			toggle: 'draggable_toggle',
			//save_url: '/drag_and_drop_receiver.php'
			//save_url: 'http://hqn.local/drag_and_drop_receiver.php'
            save_url: 'http://' + window.location.hostname + '/drag_and_drop_receiver.php'
		};
		
		//extend options
		Object.extend(this.options, options || {});
	},
	
	//wrapper function for applying settings
	apply_settings: function(settings)
	{
		//save content selector
		content_selector = this.options.content;
		
		//save toggle selector
		toggle_selector = this.options.toggle;
		
		//loop through settings
		for(var container in settings)
		{
			//total height of draggables
			var total_height = 0;
			
			//loop though array of elements
			settings[container].each(function(block)
			{
				//check draggable element block for semicolon seperator
				if(block.indexOf(':') != -1)
				{
					//split draggable element block
					var result = block.split(':');
					
					//reassign draggble element block
					block = result[0];
					
					//save draggable element block toggle status
					var toggle_status = result[1];
					
					//check toggle status
					if(toggle_status.toLowerCase() == 'hide')
					{
						//gather content for this draggable element
						var content = $(block).getElementsByClassName(content_selector);
						
						//gather toggler for this element
						var toggle = $(block).getElementsByClassName(toggle_selector);
						
						//save first element in arrays
						content = content[0];
						toggle = toggle[0];
						
						//gather toggle image for this element
						var toggle_image = $(toggle.id);
						
						//save content status
						content.toggle = toggle_status;
						
						//check emelent
						//if(!Object.isUndefined($(content.id)))
						if((trim_whitespace(content.innerHTML) != '<p>&nbsp;</p>' && trim_whitespace(content.innerHTML) != '' && trim_whitespace(content.innerHTML).length > 0) || (content.innerHTML != '<p>&nbsp;</p>' && content.innerHTML != '' && content.length > 0))
						{
							//toggle element
							Effect.SlideUp(content, {duration: 0.0});
						}
						else
						{
							//detect browser type
							var browser = navigator.appName.toLowerCase();
							
							//check for IE
							if(browser.indexOf('explorer') > -1)
							{
								//hide content
								content.style.display = 'none';
							}
						}
						
						//switch toggle image
						toggle_image.src = '/images/blue_arrow_toggle_hide.gif';
						
						//increment total height
						total_height += 40;
					}
					else
					{
						//gather dimensions
						var dimensions = $(block).getDimensions();
						
						//increment total height
						total_height += dimensions.height;
					}
				}
				
				//append draggable element to droppable element
				$(container).appendChild($(block));
			});
			
			//append a reasonable amount of padding
			total_height += 0;
			
			//resize column
			$(container).setStyle({height: total_height + 'px'});
		}
		
		//create timer for droppable column height updates
		setInterval('update_droppables()', 500);
	}
};

//wrapper function for parsing arrays
function parse_array(old_array)
{
	//create a new array
	new_array = [];
	
	//loop through elements in array
	for(index = 0, count = old_array.length; index < count; index++)
	{
		//save droppable element
		new_array.push(old_array[index]);
	}
	
	//return array
	return new_array;
}

//wrapper function for removing whitespace from the start and end of a string
function trim_whitespace(string)
{
	//trim whitespace and return string
	return string.replace(/^\s*|\s*$/g, '');
}

//wrapper function for resizing the droppable content area after an item is added or removed from the column
function resize_droppable_area(element)
{
	//gather draggables for this column
	var draggables = $(element).getElementsByClassName('draggable_wrapper');
	
	//total height of draggables
	var total_height = 0;
	
	//loop through settings
	for(index = 0, count = draggables.length; index < count; index++)
	{
		//gather draggable element
		var draggable = $(draggables[index].id);
		
		//gather dimensions
		var dimensions = draggable.getDimensions();
		
		//increment total height
		total_height += dimensions.height;
	}
	
	//append a reasonable amount of padding
	total_height += 30;
	
	//resize column
	$(element).setStyle({height: total_height + 'px'});
}

//wrapper function for updating draggable column heights
function update_droppables()
{
	//loop through droppable columns
	for(var i = 1; i <= 4; i++)
	{
		//resize column
		resize_droppable_area($('droppable_wrapper_' + i));
	}
}
