// Dashboard Class

// Global Variable
var DashboardCount = 0;
var DashboardInstance = new Array;

function DashboardEventDelegate(instanceindex, type, id)
{
	var instance = DashboardInstance[instanceindex];
}

function Dashboard(width, height)
{	
	// Constant
	this.NULLINDEX = -1;
	this.TOPPART = 1;
	this.BOTTOMPART = 2;

	// Private Member
	DashboardCount++;
	DashboardInstance[DashboardCount] = this;
	this.id = DashboardCount; 
	this.name = "Dashboard" + DashboardCount;
	this.container = new Array;
	this.containertag = new Array;
	this.panel = new Array;
	this.paneltag = new Array;
	this.width = width;
	this.height = height;
	this.containerIndex = this.NULLINDEX;
	this.selectedIndex = this.NULLINDEX;
	this.selectedPart = this.TOPPART;
	this.dragObject = null;
	this.focusObject = null;
	this.mouseOffset = null;
	this.originalX = null;
	this.originalY = null;
	this.originalWidth = null;
	this.originalZIndex = 0;
	
	// Private Method
	this.GetObject = Dashboard_GetObject;
	this.InsertAfter = Dashboard_InsertAfter;
	this.MouseCoords = Dashboard_MouseCoords;
	this.FindPos = Dashboard_FindPos;
	this.MakeDraggable = Dashboard_MakeDraggable;
	this.Initialise = Dashboard_Initialise;
	this.StartDrag = Dashboard_StartDrag;
	this.EndDrag = Dashboard_EndDrag;
	this.OnMove = Dashboard_OnMove;
	
	this.AddMouseMoveEvent = Dashboard_AddMouseMoveEvent;
	this.AddMouseUpEvent = Dashboard_AddMouseUpEvent;
	this.AddExpandEvent = Dashboard_AddExpandEvent;
	this.AddCloseEvent = Dashboard_AddCloseEvent;
	this.AddRefreshEvent = Dashboard_AddRefreshEvent;
	this.AddSettingEvent = Dashboard_AddSettingEvent;

	// Public Method
	this.AddContainer = Dashboard_AddContainer;
	this.AddPanel = Dashboard_AddPanel;
	this.GetContainers = Dashboard_GetContainers;
	this.GetContainerTags = Dashboard_GetContainerTags;
	this.GetItems = Dashboard_GetItems;
	this.GetItemTag = Dashboard_GetItemTag;

	// Event
	this.OnClose = null;
	this.OnRefresh = null;
	this.OnSetting = null;
	this.OnLayoutChange = null;

	// Startup Method
	this.Initialise();
}

function Dashboard_GetObject(id)
{
	return document.getElementById(id);
}

function Dashboard_InsertAfter(parent, node, referenceNode)
{
	parent.insertBefore(node, referenceNode.nextSibling);
}

function Dashboard_MouseCoords(ev)
{
	if(ev.pageX || ev.pageY)
	{
		return {x:ev.pageX, y:ev.pageY};
	}
	
	return {
		x:ev.clientX + document.body.scrollLeft - document.body.clientLeft,
		y:ev.clientY + document.body.scrollTop  - document.body.clientTop
	};
}

function Dashboard_FindPos(obj)
{
	var curleft = 0;
	var curtop = 0;
	if (obj.offsetParent)
	{
		do 
		{
			curleft += obj.offsetLeft;
			curtop += obj.offsetTop;
		}
		while (obj = obj.offsetParent);
	}

	return {
		x:curleft,
		y:curtop
	};
}

function Dashboard_MakeDraggable(obj, toolbar)
{
	if(!obj) return;
	obj.className = "DashboardMovableItem";
	var oThis = this;
	toolbar.onmousedown = function(ev)
	{
		var inDrag = false;
		for(var i = 1; i <= DashboardCount; i++)
		{
			if(DashboardInstance[i].dragObject != null)
			{
				inDrag = true;
				break;
			}
		}

		if(!inDrag)
		{
			ev = ev || window.event;
			oThis.mouseOffset = oThis.MouseCoords(ev);
			var overlappedToolbar = false;
			for(var i = 0; i < oThis.panel.length; i++)
			{
				var toolbar = oThis.GetObject(oThis.panel[i] + "Toolbar");
				if(toolbar != null)
				{
					var point = oThis.FindPos(toolbar);
					if((oThis.mouseOffset.x > point.x) && (oThis.mouseOffset.x <= (point.x + toolbar.offsetWidth)) && (oThis.mouseOffset.y > point.y) && (oThis.mouseOffset.y <= (point.y + toolbar.offsetHeight)))
					{
						overlappedToolbar = true;
						break;
					}
				}
			}

			if(!overlappedToolbar)
			{
				oThis.dragObject  = obj;
				oThis.focusObject = obj;
				oThis.originalX = parseInt(obj.offsetLeft);
				oThis.originalY = parseInt(obj.offsetTop);
				oThis.originalWidth = parseInt(obj.offsetWidth);
				oThis.originalZIndex = obj.style.zIndex;
				obj.style.zIndex = 1000;
				oThis.dragObject.style.position = "absolute";
				oThis.dragObject.style.left = oThis.originalX;
				oThis.dragObject.style.top = oThis.originalY;
				oThis.dragObject.style.width = oThis.originalWidth;
				oThis.StartDrag();
			}
		}

		return false;
	}
}

function Dashboard_AddMouseMoveEvent()
{
	var boardObj = this.GetObject(this.name);
	var oThis = this;
	var mouseMoveEvent = function(ev)
	{
		ev = ev || window.event;
		var mousePos = oThis.MouseCoords(ev);

		if(oThis.dragObject)
		{
			var newX = parseInt(oThis.originalX + (mousePos.x - oThis.mouseOffset.x));
			var newY = parseInt(oThis.originalY + (mousePos.y - oThis.mouseOffset.y));
			oThis.dragObject.style.left = newX;
			oThis.dragObject.style.top = newY;
			oThis.OnMove(mousePos.x, mousePos.y);
		}

		return false;
	};

	if(window.addEventListener)
	{
		boardObj.addEventListener("mousemove", mouseMoveEvent, false);
	}
	else
	{
		boardObj.attachEvent("onmousemove", mouseMoveEvent);
	}
}

function Dashboard_AddMouseUpEvent()
{
	var boardObj = this.GetObject(this.name);
	var oThis = this;
	var mouseUpEvent = function(ev)
	{
		if(oThis.focusObject != null)
		{
			oThis.focusObject.style.zIndex = oThis.originalZIndex;
		}

		if(oThis.dragObject != null)
		{
			oThis.dragObject.style.position = "relative";
			oThis.dragObject.style.left = 0;
			oThis.dragObject.style.top = 0;
			oThis.dragObject.style.width = "100%";
			oThis.EndDrag();
			oThis.dragObject = null;
			oThis.originalZIndex = 0;
		}

		return false;
	};

	if(window.addEventListener)
	{
		boardObj.addEventListener("mouseup", mouseUpEvent, false);
	}
	else
	{
		boardObj.attachEvent("onmouseup", mouseUpEvent);
	}
}

function Dashboard_AddExpandEvent(id)
{
	var btnObj = this.GetObject(id + "ExpandBtn");
	var oThis = this;
	var clickEvent = function()
	{
		var contentObj = oThis.GetObject(id);
		if(btnObj.className == "DashboardShowBtn")
		{
			contentObj.style.display = "none";
			btnObj.className = "DashboardHideBtn";
		}
		else
		{
			contentObj.style.display = "block";
			btnObj.className = "DashboardShowBtn";
		}
	};

	if(window.addEventListener)
	{
		btnObj.addEventListener("click", clickEvent, false);
	}
	else
	{
		btnObj.attachEvent("onclick", clickEvent);
	}
}

function Dashboard_AddRefreshEvent(id, tag)
{
	var btnObj = this.GetObject(id + "RefreshBtn");
	var oThis = this;
	var clickEvent = function()
	{
		if(oThis.OnRefresh != null)
		{
			oThis.OnRefresh(tag);
		}
	};

	if(window.addEventListener)
	{
		btnObj.addEventListener("click", clickEvent, false);
	}
	else
	{
		btnObj.attachEvent("onclick", clickEvent);
	}
}

function Dashboard_AddCloseEvent(id, tag)
{
	var btnObj = this.GetObject(id + "CloseBtn");
	var oThis = this;
	var clickEvent = function()
	{
		var panelObj = oThis.GetObject(id + "Panel");
		if (panelObj != null)
		{
			var index = -1;
			for(var i = 0; i < oThis.panel.length; i++)
			{
					if(oThis.panel[i] == id)
					{
						index = i;
						break;
					}
			}

			if(index != -1)
			{
				oThis.panel.splice(index, 1);
				oThis.paneltag.splice(index, 1);
			}

			var parentObj = panelObj.parentNode;
			parentObj.removeChild(panelObj);

			if(oThis.OnClose != null)
			{
				oThis.OnClose(tag);
			}
		}
	};

	if(window.addEventListener)
	{
		btnObj.addEventListener("click", clickEvent, false);
	}
	else
	{
		btnObj.attachEvent("onclick", clickEvent);
	}
}

function Dashboard_AddSettingEvent(id, tag)
{
	var btnObj = this.GetObject(id + "SettingBtn");
	var oThis = this;
	var clickEvent = function()
	{
		if(oThis.OnSetting != null)
		{
			oThis.OnSetting(tag);
		}
	};

	if(window.addEventListener)
	{
		btnObj.addEventListener("click", clickEvent, false);
	}
	else
	{
		btnObj.attachEvent("onclick", clickEvent);
	}
}

function Dashboard_StartDrag()
{
	var pointerObj = this.GetObject(this.name + "Pointer");
	pointerObj.style.display = "block";
	pointerObj.style.height = this.dragObject.offsetHeight;

	var parentObj = this.dragObject.parentNode;	
	parentObj.insertBefore(pointerObj, this.dragObject);
}

function Dashboard_EndDrag()
{
	var pointerObj = this.GetObject(this.name + "Pointer");
	pointerObj.style.display = "none";

	if(this.containerIndex != this.NULLINDEX)
	{
		var containerObj = this.GetObject(this.container[this.containerIndex]);
		if(this.selectedIndex == this.NULLINDEX)
		{
			containerObj.appendChild(this.dragObject);
		}
		else
		{
			if(this.selectedPart == this.TOPPART)
			{
				containerObj.insertBefore(this.dragObject, containerObj.childNodes[this.selectedIndex]);
			}
			else
			{
				this.InsertAfter(containerObj, this.dragObject, containerObj.childNodes[this.selectedIndex]);
			}
		}

		if(this.OnLayoutChange != null)
		{
			var tag = 0;
			var index = -1;
			for(var i = 0; i < this.panel.length; i++)
			{
				if(this.dragObject.id == this.panel[i] + "Panel")
				{
					index = i;
					break;
				}
			}

			if(index > -1)
			{
				tag = this.paneltag[index];
			}
			this.OnLayoutChange(tag);
		}
	}
}

function Dashboard_OnMove(x, y)
{
	var pointerObj = this.GetObject(this.name + "Pointer");
	
	this.containerIndex = this.NULLINDEX;
	
	// Find container
	var boardObj = this.GetObject(this.name);
	for(var i = 0; i < this.container.length; i++)
	{
		var obj = this.GetObject(this.container[i]);
		var point = this.FindPos(obj);
		if((x >= point.x) && (x <= (point.x + obj.offsetWidth)) && (y >= point.y) && (y <= (point.y + obj.offsetHeight)))
		{
			this.containerIndex = i;
			break;
		}
	}

	// Find where to append
	if(this.containerIndex != this.NULLINDEX)
	{
		this.selectedIndex = this.NULLINDEX;
		var containerObj = this.GetObject(this.container[this.containerIndex]);
		this.selectedPart = this.TOPPART;

		for(var i = 0; i < containerObj.childNodes.length; i++)
		{
			var	obj = containerObj.childNodes[i];
			if(obj != this.dragObject)
			{
				if((x >= obj.offsetLeft) && (x <= (obj.offsetLeft + obj.offsetWidth)) && (y >= obj.offsetTop) && (y <= (obj.offsetTop + obj.offsetHeight)))
				{
					this.selectedIndex = i;
					if(y <= (obj.offsetTop + (obj.offsetHeight / 2)))
					{
						this.selectedPart = this.TOPPART;
					}
					else
					{
						this.selectedPart = this.BOTTOMPART;
					}
					break;
				}
			}
		}

		if(this.selectedIndex == this.NULLINDEX)
		{
			containerObj.appendChild(pointerObj);
		}
		else
		{
			if(this.selectedPart == this.TOPPART)
			{
				containerObj.insertBefore(pointerObj, containerObj.childNodes[this.selectedIndex]);
			}
			else
			{
				this.InsertAfter(containerObj, pointerObj, containerObj.childNodes[this.selectedIndex]);
			}
		}
	}
}

function Dashboard_Initialise()
{
	document.write("<div id='" + this.name + "' class='Dashboard' style='width: " + this.width + "; height: " + this.height + "'>");
	document.write("<div id='" + this.name + "Clear' style='clear: both'></div>");
	document.write("<div id='" + this.name + "Pointer' class='DashboardPointer'>");
	document.write("<div class='DashboardPointerContent'></div>");
	document.write("</div>");
	document.write("</div>");

	this.AddMouseMoveEvent();
	this.AddMouseUpEvent();
}

function Dashboard_AddContainer(id)
{
	if(Dashboard_AddContainer.arguments.length >= 2)
	{
		this.containertag[this.containertag.length] = Dashboard_AddContainer.arguments[1];
	}
	this.container[this.container.length] = id;
	var containerObj = this.GetObject(id);
	if(containerObj == null)
	{
		containerObj = document.createElement("div");
		containerObj.id = id;
	}
	containerObj.className = "DashboardContainer";

	var dashboardObj = this.GetObject(this.name);
	var clearObj = this.GetObject(this.name + "Clear");
	dashboardObj.insertBefore(containerObj, clearObj);
}

function Dashboard_AddPanel(id, containerid)
{
	var toolbar = false;
	var title = "";
	var tag = 0;
	if(Dashboard_AddPanel.arguments.length >= 3)
	{
		toolbar = Dashboard_AddPanel.arguments[2];
	}
	if(Dashboard_AddPanel.arguments.length >= 4)
	{
		title = Dashboard_AddPanel.arguments[3];
	}
	if(Dashboard_AddPanel.arguments.length >= 5)
	{
		tag = Dashboard_AddPanel.arguments[4]; 
		this.paneltag[this.paneltag.length] = Dashboard_AddPanel.arguments[4];
	}

	var containerObj = this.GetObject(containerid);
	var contentObj = this.GetObject(id);
	this.panel[this.panel.length] = id;
	
	if(containerObj != null && contentObj != null)
	{
		contentObj.className = "DashboardPanel";
		
		var panelObj = document.createElement("div");
		panelObj.id = id + "Panel";
		
		if(toolbar)
		{
			var toolbarObj = document.createElement("div");
			toolbarObj.className = "DashboardToolbar";
			
			var source = "<div id='" + id + "Toolbar' style='float: right'>";
			source += "<div style='float: left; padding: 1px'><input type='button' id='" + id + "SettingBtn' value='' class='DashboardSettingBtn'></div>";
			source += "<div style='float: left; padding: 1px'><input type='button' id='" + id + "RefreshBtn' value='' class='DashboardRefreshBtn'></div>";
			//source += "<div style='float: left; padding: 1px'><input type='button' id='" + id + "ExpandBtn' value='' class='DashboardShowBtn'></div>";
			source += "<div style='float: left; padding: 1px'><input type='button' id='" + id + "CloseBtn' value='' class='DashboardCloseBtn'></div>";
			source += "</div>";
			source += title;
			source += "<div style='clear: both'></div>";

			toolbarObj.innerHTML = source;

			panelObj.appendChild(toolbarObj);
		}
		else
		{
			panelObj.style.cursor = "move";
		}

		panelObj.appendChild(contentObj);
		
		containerObj.appendChild(panelObj);

		if(toolbar)
		{
			this.AddRefreshEvent(id, tag);
			//this.AddExpandEvent(id);
			this.AddCloseEvent(id, tag);
			this.AddSettingEvent(id, tag);
			this.MakeDraggable(panelObj, toolbarObj);
		}
		else
		{
			this.MakeDraggable(panelObj, panelObj);
		}
	}
}

function Dashboard_GetContainers()
{
	return this.container;
}

function Dashboard_GetContainerTags()
{
	return this.containertag;
}

function Dashboard_GetItems()
{
	return this.panel;
}

function Dashboard_GetItemTag(index)
{
	var p = null;
	var c = null;
	var o = 0;
	if(index >= 0 && index < this.paneltag.length)
	{
		p = this.paneltag[index];
	}

	var panelObj = this.GetObject(this.panel[index] + "Panel");
	if(panelObj != null)
	{
		// Found container
		var containerObj = panelObj.parentNode;
		var containerIndex = -1;
		for(var i = 0; i < this.container.length; i++)
		{
			if(this.container[i] == containerObj.id)
			{
				containerIndex = i;
				break;
			}
		}

		if(containerIndex >= 0 && containerIndex < this.containertag.length)
		{
			c = this.containertag[containerIndex];
		}

		// Found order
		for(var i = 0; i < containerObj.childNodes.length; i++)
		{
			var obj = containerObj.childNodes[i];
			if(obj != null)
			{
				if(obj.id == panelObj.id)
				{
					o = i;
					break;
				}
			}
		}
	}

	return {
		panel:p,
		container:c,
		order:o
	};
}