/**
 * AS4PortalPage
 * Controller object for a managed user-editable portal page
 */
 
AS4PortalPage = Class.create({
	
	/**
	 * @type {Array} List of containing div elements whose panels will be made sortable
	 */
	containers: $A(['primary_column', 'secondary_column', 'tertiary_column']),
	
	/**
	 * @type {Array} Array of panels loaded into this portal
	 */
	panels: null,
	
	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
	
	/**
	 * Constructor 
	 */
	initialize: function() {
		this.prepare();
	},
	
	/**
	 * Prepare the portal page elements
	 */
	prepare: function() 
	{
		// Initialise panels array
		this.panels = $A();
		
		// Prepare each containing div as a sortable element
		this.containers.each(function(element){
			Sortable.create(element, {
				tag: 'div',
				only: 'panel',
				handle: 'header',
				constraint: null,
				containment: $A(['primary_column', 'secondary_column', 'tertiary_column']),
				hoverclass: 'active_drop',
				dropOnEmpty: true,
				onUpdate: this.onPanelDropped
			})
		}.bind(this));
	},
	
	/**
	 * Appends the given panel element to the given column
	 * 
	 * @param {AS4PortalPanel} panel The panel element to appended
	 * @param {Element} column The column element into which element will be inserted
	 */
	appendPanel: function(panel, column)
	{
		$(column).appendChild($(panel.element));
		
		this.panels.push(panel);
		this.prepare();
	},
	
	/**
	 * Return a serialized representation of the portal page layout
	 * @return string
	 */
	serialize: function()
	{
		var columns = {
			primary_column: this._serializeSortable('primary_column'),
			secondary_column: this._serializeSortable('secondary_column'),
			tertiary_column: this._serializeSortable('tertiary_column')
		};
		return Object.toJSON(columns);
	},
	
	/**
	 * Callback occurs when a Sortable element is changed
	 * 
	 * @param {Element} container The sortable container
	 */
	onPanelDropped: function(container)
	{
		container = $(container);
		if (container.select('.panel').length == 0 && !container.hasClassName('blank_column')) 
			container.addClassName('blank_column');
		else 
			container.removeClassName('blank_column');
	},
	
	/**
	 * Private method to override the Sortable.sequence() method to return the actual elements
	 *
	 * @return {Array}
	 */
	_sequence: function(element)
	{
		element = $(element);
		return $(element).select('.panel');
	},
	
	/**
	 * Private method to serialize a single sortable column, complete with current display options
	 *
	 * @param {Element} element The Sortable element to serialize 
	 * @return string 
	 */
	_serializeSortable: function(element)
	{
		element = $(element);

		var options = Object.extend(Sortable.options(element), arguments[1] || { });

		// Name of the column being serialized
		var container = encodeURIComponent((arguments[1] && arguments[1].name) ? arguments[1].name : element.id);

		return this._sequence(container, arguments[1]).map(function(item) {
			return $(item).controller;
		});
	}
});
