/**
 * (c) Copyright 2008 Bedican Solutions
 *
 * PanelList and Panel classes extend the Yahoo UI library.
 * The following js files should be included first.
 *
 * http://yui.yahooapis.com/2.7.0/build/yahoo/yahoo-min.js
 * http://yui.yahooapis.com/2.7.0/build/yahoo-dom-event/yahoo-dom-event.js
 * http://yui.yahooapis.com/2.7.0/build/animation/animation-min.js
 * http://yui.yahooapis.com/2.7.0/build/dragdrop/dragdrop-min.js
 * http://yui.yahooapis.com/2.7.0/build/cookie/cookie-min.js
 *
 */

var Dom = YAHOO.util.Dom;
var Event = YAHOO.util.Event;
var DDM = YAHOO.util.DragDropMgr;

PanelPage =
{
	setup: function(id)
	{
		if(Dom.get(id).className.toLowerCase() != "page") { return; }

		var panels = Dom.getElementsByClassName("panels", "ul", id);
		if(panels.length == 0) { return; }

		for(x in panels) {
			PanelList.setup(panels[x].id);
		}
	}
};

PanelList = 
{
	setup: function(id)
	{
		if(Dom.get(id).nodeName.toLowerCase() != "ul") { return; }

		new YAHOO.util.DDTarget(id);
		var children = Dom.getChildren(id);

		if(children.length > 1) {
			for(x in children) {
				if(children[x].nodeName.toLowerCase() == "li") {
					new Panel(children[x].id);
				}
			}
		}
	},
	saveOrder: function(id)
	{
		if(Dom.get(id).nodeName.toLowerCase() != "ul") { return; }

		var ul = Dom.get(id);
		var page = Dom.getAncestorByClassName(id, "page");

		var cookieName = ul.id.replace(/^panels_/, "panels_" + page.id + "_").toLowerCase();

		var ordering = new Array();
		var panels = Dom.getChildren(ul);

		for(li in panels) {
			if(panels[li].nodeName.toLowerCase() == "li") {
				ordering.push(panels[li].id.replace(/^panel_/, ""));
			}
		}

		var date = new Date();
		date.setTime(date.getTime() + (1000*60*60*24*365));

		YAHOO.util.Cookie.set(cookieName, ordering.join(), { expires: date });
	}
};

Panel = function(id, sGroup, config)
{
	Panel.superclass.constructor.call(this, id, sGroup, config);

	this.setHandleElId(id + "_handle");

	Dom.setStyle(this.getDragEl(), "opacity", 0.67);
	Dom.setStyle(id + "_handle", "cursor", "move");

	var region = Dom.getRegion(Dom.getAncestorByTagName(id, "ul"));
	var el = this.getEl();

	//var bottom = region.bottom - parseInt(Dom.getStyle(el, 'height'), 10) - Dom.getY(el);
	var bottom = region.bottom - Dom.getY(el);
	var top = Dom.getY(el) - region.top;

	this.setXConstraint(0, 0);
	this.setYConstraint(top, bottom);

	this.goingUp = false;
	this.lastY = 0;
};

YAHOO.lang.extend(Panel, YAHOO.util.DDProxy, 
{
	startDrag: function(x, y)
	{
		// make the proxy look like the source element
		var proxy = this.getDragEl();
		var srcEl = this.getEl();
		Dom.setStyle(srcEl, "visibility", "hidden");

		//proxy.innerHTML = srcEl.innerHTML;

		Dom.setStyle(proxy, "border", "1px solid #ff33cc");
		Dom.setStyle(proxy, "background-color", "#ffffff");
	},

	endDrag: function(e)
	{
		var proxy = this.getDragEl();
		var srcEl = this.getEl();

		// Show the proxy element and animate it to the src element's location
		Dom.setStyle(proxy, "visibility", "");

		var a = new YAHOO.util.Motion
		(
			proxy, {points: {to: Dom.getXY(srcEl)}}, 0.2, YAHOO.util.Easing.easeOut
		)

		var proxyid = proxy.id;
		var thisid = this.id;

		// Hide the proxy and show the source element when finished with the animation
		a.onComplete.subscribe
		(
			function()
			{
				Dom.setStyle(proxyid, "visibility", "hidden");
				Dom.setStyle(thisid, "visibility", "");
			}
		);

		a.animate();

		// Save the panel list order
		var parent = Dom.getAncestorByTagName(thisid, "ul");
		PanelList.saveOrder(parent.id);
	},

	onDragDrop: function(e, id)
	{
		// If there is one drop interaction, the li was dropped either on the list,
		// or it was dropped on the current location of the source element.

		if (DDM.interactionInfo.drop.length === 1)
		{
			// The position of the cursor at the time of the drop (YAHOO.util.Point)
			var pt = DDM.interactionInfo.point;

			// The region occupied by the source element at the time of the drop
			var region = DDM.interactionInfo.sourceRegion;

			// Check to see if we are over the source element's location.  We will
			// append to the bottom of the list once we are sure it was a drop in
			// the negative space (the area of the list without any list items)
			if(!region.intersect(pt))
			{
				var destEl = Dom.get(id);
				var destDD = DDM.getDDById(id);
				destEl.appendChild(this.getEl());
				destDD.isEmpty = false;
				DDM.refreshCache();
			}
		}
	},

	onDrag: function(e)
	{
		// Keep track of the direction of the drag for use during onDragOver
		var y = Event.getPageY(e);

		if (y < this.lastY) {
			this.goingUp = true;
		} else if (y > this.lastY) {
			this.goingUp = false;
		}

		this.lastY = y;
	},

	onDragOver: function(e, id)
	{
		var srcEl = this.getEl();
		var destEl = Dom.get(id);

		// We are only concerned with list items, we ignore the dragover
		// notifications for the list.

		if(destEl.nodeName.toLowerCase() == "li")
		{
			var orig_p = srcEl.parentNode;
			var p = destEl.parentNode;

			if(this.goingUp) {
				p.insertBefore(srcEl, destEl); // insert above
			} else {
				p.insertBefore(srcEl, destEl.nextSibling); // insert below
			}

			DDM.refreshCache();
		}
	}
});