/**
	@fileOverview Contains the coweldco.homepage.dd namespace.
	@author Philip Siedow-Thompson
	@version $Id$
*/

var coweldco;
	coweldco = (coweldco) ? coweldco : {};
	coweldco.homepage = (coweldco.homepage) ? coweldco.homepage : {};

(function() {
	/**
		@namespace Contains the classes used to Represend DropDown Menus.
	*/
	coweldco.homepage.dd = (coweldco.homepage.dd) ? coweldco.homepage.dd : {};
	
	/**
		The DropDown Menus
		@private
	*/
	var menuItems = [];
	
	/**
		The duration of the menu Fade transition in seconds.
		@type Number
		@default 1
	*/
	coweldco.homepage.dd.MENU_TRANSITION_DURATION = 0.15;
	
	/**
		The interpolation function to use in the transition.
		@type Function
		@default coweldco.animate.linearInterpolation
	*/
	coweldco.homepage.dd.MENU_TRANSITION_INTERPOLATION 
		= (function() {return coweldco.animate.linearInterpolation;})(); //this is wrapped to help jsdoc-toolkit
	
	/**
		The framerate of the menu transition in frames/sec
		@type Number
		@value 30
	*/
	coweldco.homepage.dd.MENU_TRANSITION_FRAMERATE = 30;
	
	/**
		Boolean value indicating if the transition should be used.
		@type Boolean
		@value True
	*/
	coweldco.homepage.dd.MENU_TRANSITION = true;
	
	/**
		The amount of time in seconds the menu should delay opening.
		@type Number
		@value 0.25
	*/
	coweldco.homepage.dd.MENU_DELAY = 0.25;
	
	/**
		The amount of time in seconds the menu should stay open after rolloff
		@type Number
		@value 0.5
	*/
	coweldco.homepage.dd.MENU_PERSIST = 0.5
	
	/**
		Constructs a new DropDown Menu
		
		@class Represents a Menu in a DropDown. This handles all the user events, closes
		other menus when it opens and runs transition effects.
		@param {Node} triggerItemNode the node that acts as the trigger for the menu
		@param {Node} menuNode the node that acts as the container for the menu
		@param {Node} menuBody the node that acs as the body of the menuItems (this may
		be the same as menuNode)
	*/
	coweldco.homepage.dd.Menu = function(triggerItemNode, menuNode, menuBody) {
		this.triggerItemNode = $(triggerItemNode);
		this.menuNode = $(menuNode);
		this.menuBody = $(menuBody);
		this.transition = null;
		this.openTimer = null;
		this.closeTimer = null;
		
		this.triggerItemNode.observe("mouseover", this.open.bind(this));
		this.triggerItemNode.observe("mouseout", this.close.bind(this));
		
		this.menuBody.getElementsBySelector("a").each(function(node) {
			node.observe("click", this.closeNow.bind(this));
		},this);
	}
	
	/**
		Opens the menu (after the delay)
		@memberOf coweldco.homepage.dd.Menu.prototype
	*/
	coweldco.homepage.dd.Menu.prototype.open = function() {
		this.startOpenTimer();
	}
	
	/**
		Opens the menu imediately
		@memberOf coweldco.homepage.dd.Menu.prototype
	*/
	coweldco.homepage.dd.Menu.prototype.openNow = function() {
		this.clearTimers();
		
		if(this.menuNode.hasClassName("coweldco-homepage-dd-menu-hidden")) {
			this.closeAllButCurrent();
			
			this.menuNode.removeClassName("coweldco-homepage-dd-menu-hidden");
			
			this.doTransition();
		}
	}
	
	/**
		Stops the active transition
		@memberOf coweldco.homepage.dd.Menu.prototype
	*/
	coweldco.homepage.dd.Menu.prototype.stopTransition = function() {
		if(this.transition) {
			this.transition.stop();
			this.transition = null;
		}
	}
	
	/**
		Runs the transition
		@memberOf coweldco.homepage.dd.Menu.prototype
	*/
	coweldco.homepage.dd.Menu.prototype.doTransition = function() {
		this.stopTransition();
		
			if(coweldco.homepage.dd.MENU_TRANSITION) {
				this.transition = new coweldco.animate.Animator(this.menuNode, 
					coweldco.homepage.dd.MENU_TRANSITION_INTERPOLATION,
					coweldco.homepage.dd.MENU_TRANSITION_FRAMERATE);
			
				this.transition.animate({opacity:0}, 
					{opacity:1}, 
					coweldco.homepage.dd.MENU_TRANSITION_DURATION);
			}
	}
	
	/**
		Clears any active timers.
		@memberOf coweldco.homepage.dd.Menu.prototype
	*/
	coweldco.homepage.dd.Menu.prototype.clearTimers = function() {
		if(this.closeTimer) {
			this.closeTimer.stop();
			this.closeTimer = null;
		}
		
		if(this.openTimer) {
			this.openTimer.stop();
			this.openTimer = null;
		}
	}
	
	/**
		Starts the close timer.
		@memberOf coweldco.homepage.dd.Menu.prototype
	*/
	coweldco.homepage.dd.Menu.prototype.startCloseTimer = function() {
		this.clearTimers();
		this.closeTimer = new PeriodicalExecuter(this.closeNow.bind(this),0.5);
	}
	
	/**
		Starts the open timer.
		@memberOf coweldco.homepage.dd.Menu.prototype
	*/
	coweldco.homepage.dd.Menu.prototype.startOpenTimer = function() {
		this.clearTimers();
		this.openTimer = new PeriodicalExecuter(this.openNow.bind(this),0.25);
	}
	
	/**
		Closes all the menus but the current one.
		@memberOf coweldco.homepage.dd.Menu.prototype
	*/
	coweldco.homepage.dd.Menu.prototype.closeAllButCurrent = function() {
		for(var i=0; i < menuItems.length; i++) {
			if(menuItems[i] != this) {
				menuItems[i].closeNow();
			}
		}
	}
	
	/**
		Closes the menu after the persistance delay
		@memberOf coweldco.homepage.dd.Menu.prototype
	*/
	coweldco.homepage.dd.Menu.prototype.close = function() {
		this.startCloseTimer();
	}
	
	/**
		Closes the menu imediately.
		@memberOf coweldco.homepage.dd.Menu.prototype
	*/
	coweldco.homepage.dd.Menu.prototype.closeNow = function() {
		this.clearTimers();
		this.stopTransition();
		this.menuNode.addClassName("coweldco-homepage-dd-menu-hidden");
	}
	
	/**
		Creates the Menus on DOM load.
		@private
	*/
	document.observe("dom:loaded", function() {
		var triggerItems = $$(".coweldco-homepage-dd-trigger-item");
		
		triggerItems.each(function(triggerItem) {
			var menuNodes = triggerItem.getElementsBySelector(".coweldco-homepage-dd-menu");
			var menuBodyNodes = triggerItem.getElementsBySelector(".coweldco-homepage-dd-body");
			
			if(menuNodes.length>0 && menuBodyNodes.length>0) {
				menuItems.push(new coweldco.homepage.dd.Menu(triggerItem, 
					menuNodes[0], 
					menuBodyNodes[0]));
			}
		});
	});
})();
