﻿var dropdown = Class.create(
{
	button: null,
	source: null,
	target: null,
	hiddenfield: null, // the actual aspnet field posted back to server.. 
	enabled: true,
	
	hoveringli: null,
	dropvisible: false,
	timerhandle: null,
	delay: 500,
	
	contextHelp: null,
	contextHelpVisible: false,
	contextHelpLi: null,  // stores a handle to the associated li
	hoverClass: "hoveroption",
	indexCounter: 0, // used when registering options to assign a listindex
	ondrop: null, // used for registering an external evthandler
	enableContextHelp: true,
	iframe1: null,
	
	initialize: function(button, source, target, hiddenfield)
	{
		this.button = $(button);
		this.source = $(source);
		this.target = $(target);
		// target has one li item inserted to make validation happy
		this.target.innerHTML = "";
		this.hiddenfield = $(hiddenfield);
		this.hiddenfield.value = ""; // clearing it to prevent backbutton mess
		
		this.source.immediateDescendants().each(function(li) {this.registeroption(li);}.bind(this));
		button.observe("mousedown", this.button_mousedown.bindAsEventListener(this));
		Event.observe(document.body, "mousedown", this.outside_click.bindAsEventListener(this));
	},
	
	
	button_mousedown: function(e)
	{
		if (!this.enabled)
			return;
		if (!this.dropvisible)
		{
			this.showdroppart();
		}
		else 
		{
			this.hidedroppart();
		}
		e.stop();

	},
	
	setEnabled: function(b)
	{
		if (b)
		{
			this.button.style.backgroundColor = "";
			this.target.style.backgroundColor = "";
		}
		else
		{
			this.button.style.backgroundColor = "#D4D0C8";
			this.target.style.backgroundColor = "#D4D0C8";
			//moving back options
			var lis = this.target.getElementsByTagName("LI");
			for (var i = lis.length-1; i >= 0; i--)
			{
				this.li_dblclick(lis[i]);
			}
			
			
		}
		this.enabled = b;
	},
	
	
	outside_click: function(e)
	{
		if (this.dropvisible && Event.element(e) != this.source)
			this.hidedroppart();
	},
	
	registeroption: function(li)
	{
		li.observe("mouseover", this.li_mouseover.bind(this, li));
		li.observe("mouseout",  this.li_mouseout.bind(this, li));
		li.observe("mousedown", this.li_click.bind(this, li));
		li.observe("dblclick", this.li_dblclick.bind(this, li));
		li.observe("mousemove", this.li_mousemove.bindAsEventListener(this, li));
		li.index = this.indexCounter++;
	},
	
	
	li_mouseover: function(li)
	{
		if (this.isInSource(li))
		{
			this.stopTimer();
			li.addClassName(this.hoverClass);
			if (this.hoveringli != null && this.hoveringli != li)
			{
				this.hoveringli.removeClassName(this.hoverClass);
			}
			this.hoveringli = li;
		}
	},
	
	li_mouseout: function(li)
	{
		if (this.contextHelpVisible)
			this.hideContextHelp();		
		
		li.removeClassName(this.hoverClass);
		this.hoveringli = null;
//		this.startTimer();
	},
	
	li_click: function(li)
	{
		if (this.isInSource(li))
		{
			this.target.appendChild(li);
			this.hideContextHelp();
		}
		this.hidedroppart();
		
		window.setTimeout(this.updateHiddenField.bind(this), 100);
	},
	
	
	li_dblclick: function(li)
	{
		// if li is in targetlist, put it back into source at appropriate index
		if (!this.isInTarget(li))
			return;
		
		var sourceChildren = this.source.immediateDescendants();
		
		var inserted = false;
		for (var i = 0; i < sourceChildren.length; i++)
		{
			if (sourceChildren[i].index > li.index)
			{
				this.source.insertBefore(li, sourceChildren[i]);
				inserted = true;
				break;
			}
		}
		if (!inserted)
		{
			this.source.appendChild(li);
		}
		this.hideContextHelp();
		window.setTimeout(this.updateHiddenField.bind(this), 100);
	},


	li_mousemove: function(e, li) 
	{
		if (!this.enableContextHelp)
			return;
			
		if (this.contextHelp == null)
			this.constructContextHelp();	// construct it

		
		if (this.contextHelpLi != li)
		{
			// set contxt up with info for this option .. 
			
			var hiddenspan = li.getElementsByTagName("SPAN");
			if (hiddenspan.length == 0)
			{
				this.hideContextHelp();		
				return; // no info stored in this li.. returning..
			}
			
			if (hiddenspan[0].innerHTML.replace(" ", "") == "")
			{
				this.hideContextHelp();
				return;
			}
			
			this.contextHelp.innerHTML = hiddenspan[0].innerHTML;
			this.contextHelpLi = li;
		}

		// update position
		var mx = Event.pointerX(e);
		var my = Event.pointerY(e);

		this.contextHelp.style.left = (mx + 20) + "px";
		this.contextHelp.style.top = my + "px";
		
		if (this.iframe1 != null)
		{
			var dim = this.contextHelp.getDimensions();

			this.iframe1.style.left = (mx + 20) + "px";
			this.iframe1.style.top =  my + "px";

			this.iframe1.style.width = dim.width + "px";
			this.iframe1.style.height = dim.height + "px";
		}

		if (!this.contextHelpVisible)
		{
			this.contextHelp.style.display = "block";
			this.contextHelpVisible = true;
			if (this.iframe1 != null)
				this.iframe1.style.display = "block";
		}
	},
	
	constructContextHelp: function()
	{
		this.contextHelp = $(document.createElement("div"));
		this.contextHelp.addClassName("contextHelp");
		this.contextHelp.style.display = "none";
		document.body.appendChild(this.contextHelp);
		
		var ievers = this.getInternetExplorerVersion();
		if (ievers > -1  && ievers <= 6)
		{
			var iframe1 = $(document.createElement("IFRAME"));
			iframe1.src = "javascript:false;";
			iframe1.frameBorder = 0;
			iframe1.scrolling = "no";
			iframe1.style.position = "absolute";
			iframe1.style.left = "0px";
//			iframe1.style.width = "500px";
//			iframe1.style.height = "300px";
			iframe1.style.top = "0px";
			iframe1.style.zIndex = "4";
			iframe1.style.filter = 'progid:DXImageTransform.Microsoft.Alpha(style=0,opacity=0)';
			document.body.appendChild(iframe1);
			this.iframe1 = iframe1;
		}

	},
	
	hideContextHelp: function()
	{
		if (this.contextHelp != null)
		{
			this.contextHelp.style.display = "none";
			this.contextHelpVisible = false;
			if (this.iframe1 != null)
				this.iframe1.style.display = "none";
		}
	},
	
	
	isInSource: function(elem)
	{
		return this.isIn(elem, this.source);
	},
	
	
	isInTarget: function(elem)
	{
		return this.isIn(elem, this.target);
	},
	
	
	isIn: function(elem, container)
	{
		var node = elem.parentNode;
		while (node != null && node != container)
		{
			node = node.parentNode;
		}

		return node == container;
	},
	
	
	startTimer: function()
	{
		this.timerhandle = window.setTimeout(this.onTimeout.bind(this), this.delay);
	},
	
	stopTimer: function()
	{
		if (this.timerhandle != null)
			window.clearTimeout(this.timerhandle);	
	},

	onTimeout: function()
	{
		this.hidedroppart();
		
	},
	
	showdroppart: function()
	{
		this.source.style.display = "";
		this.dropvisible = true;
		if (this.ondrop != null)
			this.ondrop();
	},
	
	hidedroppart: function()
	{
		this.source.style.display = "none";
		this.dropvisible = false;
		this.stopTimer();
	},
	
	updateHiddenField: function() 
	{
		var pipedlist = "";
		
		this.target.immediateDescendants().each(function(li) {
			var hidden = li.getElementsByTagName("INPUT");
			if (hidden.length == 1)
			{
				pipedlist += hidden[0].value + "|";
			}
		});
		
		this.hiddenfield.value = pipedlist;
	},

	// Returns the version of Internet Explorer or a -1
	// (indicating the use of another browser).
	getInternetExplorerVersion: function()
	{
		var rv = -1; // Return value assumes failure.
		if (navigator.appName == 'Microsoft Internet Explorer')
		{
			var ua = navigator.userAgent;
			var re  = new RegExp("MSIE ([0-9]{1,}[\.0-9]{0,})");
			if (re.exec(ua) != null)
				rv = parseFloat( RegExp.$1 );
		}
		return rv;
	}

}
);


