/**
 * @author Mark Cassar
 * @version 1.0.2
 * @lastmodified 05/04/07
 */
 

if (!com) var com = new Object();
if (!com.CS) com.CS = new Object();
if (!com.CS.General) com.CS.General = new Object();
if (!com.CS.General.Align) com.CS.General.Align = new Object();

//Requirements
if (!Class) throw new Error("com.CS.General.Align: Please include Class com.CS.defineClass")
if (!com.CS.General.Window) throw new Error("com.CS.General.Align: Please include Class com.CS.General.Window")
if (!com.CS.General.Mouse) throw new Error("com.CS.General.Align: Please include Class com.CS.General.Mouse")
if (!com.CS.General.Listener) throw new Error("com.CS.General.Align: Please include Class com.CS.General.Listener")
if (!com.CS.General.Item) throw new Error("com.CS.General.Align: Please include Class com.CS.General.Item")
//------------

com.CS.General.Align = Class({
	name: "Align",

	statics: {
	    
	    alignToCenterH : function(target, itemWidth, offset) {
	        if (target == undefined) {
	            alert("Error: com.CS.General.Align - target must be defined");
	        }
	        if (itemWidth == undefined) {
	            itemWidth = com.CS.General.Item.getOuterWidth(target);
	        }
	        var screenWidth = com.CS.General.Window.getWidth();
	        var xPos = (screenWidth - itemWidth) / 2;
	        xPos = Math.round(xPos);
	        if (offset != undefined) {
	            xPos += offset;
	        }

	        target.style.position = "absolute";
	        target.style.left = xPos + "px";
	    },
	    alignToBottom : function(target, offset, itemHeight) {
	        if (target == undefined) {
	            alert("Error: com.CS.General.Align - target must be defined");
	        }
	        if (itemHeight == undefined) {
	            itemHeight = com.CS.General.Item.getOuterHeight(target);
	        }
	        if (offset == undefined) {
	            offset = 0;
	        }
	        offset += itemHeight;
	        
	        var windowHeight = com.CS.General.Window.getHeight();
	        var scrollY = com.CS.General.Window.getScrollY();
	        var yPos = windowHeight + scrollY;
	        yPos -= offset;
	        target.style.position = "absolute";
	        target.style.top = yPos + "px";
	    },
		/**
		 * Align an object to the mouse.  Call 'detachAlignToMouse' to stop.
		 * @param {Object} target The target which to align to mouse
		 * @param {Integer} offsetX X offset
		 * @param {Integer} offsetY Y offset
		 * @param (String) showPos Position where to open the tooltip.  Can be either "TL" (top-left), "TR" (top-right), "BL" or "BR"
		 * @param {Object} scope Scope is the place where to trigger the mouse move event.  If left null, it defaults to document, which
		 * means everywhere in the browser. Leave null
		 */
		alignToMouse : function(target,offsetX,offsetY,showPos,scope) {
			if (!offsetX) offsetX = 0;
			if (!offsetY) offsetY = 0;
			scope = scope || document; //By default set it to document
			scope.com = com; //To pass the functions with the scope
			var align = function (event) {
				var com = this.com;
				var xPos = com.CS.General.Mouse.getX(event);
				var yPos = com.CS.General.Mouse.getY(event);
				var xOffsetMul, yOffsetMul;
			
				if (showPos == undefined) { //If no open position is defined, then open in best place
					
					var middleX = com.CS.General.Window.getWidth()/2;
					var middleY = com.CS.General.Window.getHeight()/2;
					var X = xPos - com.CS.General.Window.getScrollX();
					var Y = yPos - com.CS.General.Window.getScrollY();
					if (X >= middleX && Y < middleY) {
						openPos = "BL";
					}
					else if (X > middleX && Y >= middleY) {
						openPos = "TL";
					}
					else if (X <= middleX && Y > middleY) {
						openPos = "TR";
					}
					else {
						openPos = "BR";
					}
				}
				else
				{
					openPos = showPos;
				}
				
				var itemWidth = com.CS.General.Item.getOuterWidth(target);
				var itemHeight = com.CS.General.Item.getOuterHeight(target);
				switch (openPos) {
					case "TR" : xOffsetMul = 1;
							    yOffsetMul = -1;
								yPos -= itemHeight;
								break;
					case "TL" : xOffsetMul = -1;
							    yOffsetMul = -1;
								xPos -= itemWidth;
								yPos -= itemHeight;
								break;
					case "BR" : xOffsetMul = 1;
								yOffsetMul = 1;
								break;
					case "BL" : xOffsetMul = -1;
					  			yOffsetMul = 1;
								xPos -= itemWidth;
								break;
				}
				
				xPos += xOffsetMul*offsetX;
				yPos += yOffsetMul*offsetY;
				
				target.style.left = xPos + "px";
				target.style.top = yPos + "px";				
			}
			target.style.display = ""; // make visible
			var funcName = target.id + "_onAlignToMouseHandler"; //This is to attach the event handler with a unique name with the target itself for removal purpose
			var scopeName = target.id + "_alignToMouseScope"; //Same for scope
			target[funcName] = align;
			target[scopeName] = scope;
			var f = target[funcName];
			
			com.CS.General.Listener.addEventListener(scope,"onmousemove",f,false)
		},
		/**
		 * Detach an align to mouse event
		 * @param {Object} target Target which to remove
		 * @param {Object} hide Whether to hide it or not.  Defaults to true
		 */
		detachAlignToMouse : function(target,hide) {
			if (hide == undefined) {
				hide = true;
			}
			var funcName = target.id + "_onAlignToMouseHandler";
			var scopeName = target.id + "_alignToMouseScope";
			var f = target[funcName]; //Get handler to remove
			var scope = target[scopeName]; //Get scope of handler on target

			com.CS.General.Listener.removeEventListener(scope,"onmousemove",f,false);
			if (hide) {
				target.style.display = "none";
			}
		}
		
	}
});
