// this function repositions a menu to the speicified offset from center
function repositionMenu(menu, offset) { 
	// the new left position should be the center of the window + the offset
	var newLeft = getWindowWidth() / 2 + offset;
	// setting the left position in netscape is a little different than IE
	menu.container.style ? menu.container.style.left = newLeft + "px" : menu.container.left = newLeft;
} 
// this function calculates the window's width - different for IE and netscape
function getWindowWidth() {
	return window.innerWidth ? window.innerWidth : document.body.offsetWidth;
}


// constructor
var MainMenu = function(id, dir, width, height) {
	this.id  				 = id;
	this.dir 				 = dir;
	this.orientation = (dir == "left" || dir == "right") ? "h" : "v";
	this.dirType 		 = (dir == "right" || dir == "down") ? "-" : "+";
	this.dim 				 = (this.orientation == "h") ? width : height;
	this.hideTimer 	 = false;
	this.aniTimer    = false;
	this.open 			 = false;
	this.over 			 = false;
	this.startTime 	 = 0;
	this.gRef 			 = "MainMenu_" + id;
	eval(this.gRef + "=this");
	this.regNr			 = MainMenu.Registry.length;
	MainMenu.Registry[this.regNr] = this;
	
	this.load()
}

MainMenu.Registry 	= [];
MainMenu.aniLen 		= 250;
MainMenu.hideDelay 	= 1000;
MainMenu.steps 			= 10;

MainMenu.allHidden = function() {
	var reg = MainMenu.Registry;
	var hidden = true;
	for (var i = 0; i < reg.length; i++) {
		if (reg[i].open == true) {
			hidden = false;
			break;
		}
	}
	
	return hidden;
}

MainMenu.showMenu = function(regNr) {
	var reg = MainMenu.Registry;
	var currentMenu = MainMenu.Registry[regNr];
	
	if (currentMenu.container) {
		currentMenu.over = true;		
		
		for (var i = 0; i < reg.length; i++) {
			if (regNr != i) 
				MainMenu.hide(i);
		}
		
		if (currentMenu.hideTimer)
			reg[regNr].hideTimer = window.clearTimeout(reg[regNr].hideTimer);
			
		if (!currentMenu.open && !currentMenu.aniTimer) 
			reg[regNr].startSlide(true);
	}
}

MainMenu.hideMenu = function(regNr) {
	var currentMenu = MainMenu.Registry[regNr];
	
	if (!currentMenu.container)
		return;
		
	if (currentMenu.hideTimer) 
		window.clearTimeout(currentMenu.hideTimer);
		
	currentMenu.hideTimer = window.setTimeout("MainMenu.hide('" + regNr + "')", MainMenu.hideDelay);
}

MainMenu.hideAll = function() {
	var reg = MainMenu.Registry;
	
	for (menu in reg) {
		MainMenu.hide(menu);
		
		if (menu.hideTimer) 
			window.clearTimeout(menu.hideTimer);
	}
}

MainMenu.hide = function(regNr) {
	var currentMenu = MainMenu.Registry[regNr];
	
	currentMenu.over = false;
	
	if (currentMenu.hideTimer) 
		window.clearTimeout(currentMenu.hideTimer);
	
	currentMenu.hideTimer = 0;
	
	if (currentMenu.open && !currentMenu.aniTimer)
		currentMenu.startSlide(false);
}


MainMenu.prototype = {
	
	load : function() {
		var containerDiv = document.getElementById(this.id + "Container");
		if (containerDiv) 
			var contentDiv = document.getElementById(this.id + "Content");
			
		var trigger = document.getElementById(this.id + "Trigger");
		
		this.container 	= containerDiv;
		this.menu 		 	= contentDiv;
		this.trigger    = trigger;
		this.style 			= this.menu.style;
		this.homePos 		= eval("0" + this.dirType + this.dim);
		this.outPos 		= 0;
		this.accelConst = (this.outPos - this.homePos) / MainMenu.aniLen / MainMenu.aniLen 

    // set event handlers.
		this.menu.onmouseover = new Function("MainMenu.showMenu('" + this.regNr + "')");
		this.menu.onmouseout 	= new Function("MainMenu.hideMenu('" + this.regNr + "')");
		// for trigger button
    this.trigger.onmouseover = new Function("MainMenu.showMenu('" + this.regNr + "')");
		this.trigger.onmouseout = new Function("MainMenu.hideMenu('" + this.regNr + "')");
		
		//set initial state
		this.endSlide();
	},
	
	position: function() {		
		var pos = Util.getPageXY(this.trigger);
		var topDistancer = 3;
		
		var brdW = parseInt(Util.getElementsComputedStyle(this.trigger, 'border-right-width'), 10) || 0;

		var newX = (browser == 'opera') ? pos.x : (pos.x - brdW);

		var arrow_style = (document.getElementById('menu-arrow')).style;
		arrow_style.visibility = 'visible';
		arrow_style.left = (newX) + 'px';
		arrow_style.top  = (pos.y + this.trigger.offsetHeight) + 'px';
		arrow_style.width = (this.trigger.offsetWidth + 1) + 'px';
				
		this.container.style.left = (newX - 1) + 'px';
		this.container.style.top = (pos.y + this.trigger.offsetHeight + topDistancer) + 'px';		
		
		//--	
		arrow_style = null;
		pos = null;
	},

	startSlide : function(open) {
		//alert('start');
		this[open ? "onactivate" : "ondeactivate"]();
		this.open = open;
		
		//position
		this.position();
		
		if (open) 
			this.setVisibility(true);
			
		this.startTime = (new Date()).getTime();
		//alert('MainMenu_services');
		this.aniTimer  = window.setInterval(this.gRef + ".slide()", MainMenu.steps);
	},

	slide : function() {		
		var elapsed = (new Date()).getTime() - this.startTime;
		
		if (elapsed > MainMenu.aniLen) {
			//alert('s');
			this.endSlide();
		}
		else {
			var d = Math.round( Math.pow( MainMenu.aniLen - elapsed, 2 ) * this.accelConst );
			
			if (this.open && this.dirType == "-") {
				d = -d;
			}
			else if (this.open && this.dirType == "+") {
				d = -d;
			}
			else if (!this.open && this.dirType == "-") {
				d = -this.dim + d;
			}
			else {
				d = this.dim + d;
			}
			
			this.moveTo(d)
		}
	},

	endSlide : function() {
		this.aniTimer = window.clearTimeout(this.aniTimer);	
		this.moveTo(this.open ? this.outPos : this.homePos);
		
		if (!this.open) 
			this.setVisibility(false)
			
		if ((this.open && !this.over) || (!this.open && this.over))
			this.startSlide(this.over);	
	},

	setVisibility : function(bShow) { 	 
		this.container.style.visibility = bShow ? "visible" : "hidden";
		this.container.style.display = bShow ? "block" : "none";
		
 	  var arrow = document.getElementById('menu-arrow');
		if (!MainMenu.allHidden()) {
			arrow.style.visibility = "visible";
			arrow.style.display = "block";
		}
		else {
			arrow.style.visibility = "hidden";
			arrow.style.display = "none";			
		}
		//--
		arrow = null;
	},

	moveTo : function(p) { 
		this.style[this.orientation == "h" ? "left" : "top"] = p + "px";
	},

	getPos : function(c) {
		return parseInt(this.style[c]);
	},

	onactivate : function() { },	
	ondeactivate : function() { }
};



var Submenu = function() {};
Submenu.duration = 200;
Submenu.steps = 10;

Submenu.prototype = {
	
	initialize : function(el, controller) {
		this.htmlElement = document.getElementById(el);
		this.controller	 = document.getElementById(controller);
		this.items = null;

		this.start    = 1;
		this.end      = this.htmlElement.offsetHeight;
		this.duration = 300;
		this.steps    = 10;
		this.timer    = null;
		this.isExpanding = null;
		
		this.initItems();
		
		this._mouseOver = this._mouseOverHandler.bindAsEventListener(this);
		this.controller.onmouseover = this._mouseOver;
		
		
		//--
		this.htmlElement.style.height = '1px';
		
	},
	
	_mouseOverHandler: function(e) {
		
		this.isExpanding = true;

		this.animate();
	},
	

	
	animate: function() {
	  var el = this.htmlElement;
	
		if (this.isFinished()) {
			// just in case there are round errors or such...
			this.htmlElement.style.height = this.end + "px";			
			
			return;
		}
	
		if (this.timer)
			 clearTimeout(this.timer);
	
		var stepDuration = Math.round(this.duration/this.steps) ;
	
		var diff = this.steps > 0 ? (parseInt(el.offsetHeight) - this.start)/this.steps : 0;
		this.resizeBy(diff, this.isExpanding);
	
		this.duration -= stepDuration;
		this.steps--;
	
		this.timer = setTimeout(this.animate.bind(this), stepDuration);
	},
	
	isFinished: function() {
		return this.steps <= 0;
	},
	
	resizeBy: function(diff, isExpanding) {
		var height = this.htmlElement.offsetHeight;
		var intDiff = parseInt(diff);
		var el = this.htmlElement;
		
		if ( diff == 0 )
			return;
		
		if (isExpanding) {
			 el.style.height = (height + intDiff) + "px";
		}
		else {
			 el.style.height = (height - intDiff) + "px";
		}
	}	
};
