/*******
** vp **	
*******/

var menuInitItemHeight = 6;
var menuItemHeight = 22;

//top.debug = window.open();function log(m){if(!top.debug)top.debug=window.open();top.debug.document.write(m+'<br />');}

Page = function() {
	//if (!this.hasSupport()) return;
	this.menu = new Navigation("innerMainNav");
}

Page.prototype.destroy = function() {
	//if(!this.hasSupport()) return;
	this.menu.destroy();
}

/*
Page.prototype.hasSupport = function() { // block MSIE5.0x/Win, MSIE5.x/Mac
	var ua = navigator.userAgent;
	if ((ua.indexOf("MSIE 5.0") != -1 && ua.indexOf("Windows") != -1) || (ua.indexOf("MSIE 5.2") != -1 && ua.indexOf("Mac") != -1) || !document.getElementsByTagName || !document.getElementById) { 
		return false; 
	} else { 
		return true; 
	}
}
*/

/* -----------------------------------------------------------------
// Page helpers/methods/properties/...
----------------------------------------------------------------- */

// Dynamic classname handling for objects
addClass = function(obj, cName) { 
	if (obj) {
		removeClass(obj,cName); 
		return obj.className += (obj.className.length > 0 ? " " : "") + cName; 
	}
}
removeClass = function(obj, cName) {
	if (obj) {
		return obj.className = obj.className.replace(new RegExp("^" + cName+"\\b\\s*|\\s*\\b" + cName+"\\b",'g'),''); 
	}
}

// Function to fetch objects by classname
getElementsByClassName = function(cName, baseElement) {
	var results = new Array;
	var objs = document.getElementsByTagName("*").length > 0 ? baseElement.getElementsByTagName("*") : baseElement.all;
	if (!objs) objs = baseElement.all;
	for (var i=0; i<objs.length; i++){
		if (objs[i].className.match(cName)) results[results.length] = objs[i]
	}
	return results;
}

Object.prototype.method = function(method) {
	var context = this;
	return function(){
		method.apply(context, arguments);
	}
}


// Functions to calculate the position of objects
calculateLeft = function(object) {
	if (object) return object.offsetLeft + calculateLeft(object.offsetParent); 
	else return 0;
}
calculateTop = function(object) {
	if (object) return object.offsetTop + calculateTop(object.offsetParent); 
	else return 0;
}

// Tickle the browser to display correctly
tickle = function(){
	addClass(document.getElementsByTagName("body")[0], "tickle");
}

// Function to add event listeners
addEvent = function(obj, evType, fn, ieonly) { 
	if (obj.addEventListener && !ieonly){ /* Mozilla & others */
		obj.addEventListener(evType, fn, false); 
		return true; 
	} else if (obj.attachEvent){ /* IE */
		var r = obj.attachEvent("on"+evType, fn); 
		return r; 
	} else { 
		return false; 
	} 
}



Navigation = function (nodeID) {

	var navigation = this;
	var selectedItem = null;
	
	this.rootNode = document.getElementById(nodeID);
	this.state = this.CLOSED;
	
	/*if(document.all){
		var iframeID = "primary-iframe";
		this.iframe = document.createElement("iframe");
		this.iframe.id=iframeID;
		this.iframe.frameBorder=0;
		this.rootNode.appendChild(this.iframe);	
	}*/
	
	// behavior
	var closeMenu = function (e) {
		if (e){
			e.stopPropagation();
		}
		else {
			window.event.cancelBubble = true;
		}
		var destination = (e) ? e.relatedTarget : window.event.toElement;
		if (!destination) return;
		if (destination.tagName != "INPUT") {
			// firefox bug ?
			navigation.changeState(navigation.LOSTMOUSE, destination, this.menuitem);
		}
		if (this.menuitem || !navigation.isChild(destination)) {
			navigation.selectedItem.getElementsByTagName('img')[0].src = navigation.selectedItem.getElementsByTagName('img')[0].src.replace('-o.', '-n.');
			removeClass(navigation.selectedItem, "selected");
		}
	}
	var openMenu = function (e) {
		if (e) {
			e.stopPropagation();
		}
		else {
			window.event.cancelBubble = true;
		}
		if (navigation.selectedItem) {
			removeClass(navigation.selectedItem, "selected");
			navigation.selectedItem.getElementsByTagName('img')[0].src = navigation.selectedItem.getElementsByTagName('img')[0].src.replace('-o.', '-n.');
		}
		navigation.selectedItem = this;
		navigation.selectedItem.getElementsByTagName('img')[0].src = navigation.selectedItem.getElementsByTagName('img')[0].src.replace('-n.', '-o.');
		if (navigation.selectedItem.menuitem.submenu) addClass(navigation.selectedItem, "selected");
		var destination = (e) ? e.relatedTarget : window.event.toElement;
		if(!destination) return;
		navigation.changeState(navigation.GOTMOUSE, destination, this.menuitem);
	}
	var openSubMenu = function (e) {
		addClass(this, "selected");
		if (e) e.stopPropagation(); else window.event.cancelBubble = true;
		//adjust manupanel
		var destination = (e) ? e.relatedTarget : window.event.toElement;
		if(!destination) return;
		navigation.changeState(navigation.GOTMOUSE, destination, this.menuitem);
	}
	var closeSubMenu = function (e) {
		removeClass(this, "selected");
		if (e) e.stopPropagation(); else window.event.cancelBubble = true;
		// check 4 lost events
		var destination = (e) ? e.relatedTarget : window.event.toElement;
		if(!destination) return;
		if (!navigation.isChild(destination)) navigation.changeState(navigation.LOSTMOUSE, destination, this.menuitem);
	}
	
	var root = this.rootNode.getElementsByTagName("ul")[0];
	root.onmouseout = closeMenu;
	var lis = root.getElementsByTagName("li");
	
	// shift main panel to the ul
	this.rootNode = root;
	
	for (var i=0; i < lis.length; i++) {
		if (lis[i].parentNode == root) {
			// level 0
			lis[i].onmouseover = openMenu;
			lis[i].menuitem = new Object();
			if (lis[i].getElementsByTagName("li").length > 0) {
				// has submenu
				lis[i].menuitem.submenu = lis[i].getElementsByTagName("ul")[0];
				lis[i].menuitem.height = this.calculateMenuHeight(lis[i].menuitem.submenu);
			}
			else {
				lis[i].menuitem.submenu = null;
				lis[i].menuitem.height = menuInitItemHeight;
			}
		}
		if (lis[i].parentNode.parentNode.parentNode == root) {
			// level 1
			lis[i].onmouseover = openSubMenu;
			lis[i].onmouseout = closeSubMenu;
			lis[i].menuitem = new Object();
			if (lis[i].getElementsByTagName("li").length > 0) {
				lis[i].menuitem.submenu = lis[i].getElementsByTagName("ul")[0];
				lis[i].menuitem.height =  this.calculateMenuHeight(lis[i].menuitem.submenu);
			}
			else {
				lis[i].menuitem.submenu = null;
				lis[i].menuitem.height = menuInitItemHeight;
			}
		}
	}
	// recalculate the height
	for (var i=0; i < lis.length; i++) {
		if (lis[i].parentNode == root && lis[i].getElementsByTagName("li").length > 0) {
			this.recalculateMenuHeight(lis[i].menuitem);
		}
	}
}
//Event types
Navigation.prototype.GOTMOUSE  = 0;
Navigation.prototype.LOSTMOUSE = 1;

//States
Navigation.prototype.OPEN      = 0;
Navigation.prototype.CLOSED    = 1;
Navigation.prototype.ANIMATING = 2;
Navigation.prototype.HOT       = 3;

Navigation.prototype.changeState = function (eventType, destination, newItem) {
	if (this.isChild(destination) && !newItem) {
		return;//Ignore event bubbling when open, top item events got newItems, so they fall through
	}
	switch (eventType) {
		case this.GOTMOUSE:
			switch (this.state) {
				case this.HOT:
					this.activeItem = newItem;
				break;
				case this.CLOSED:// Menu will open in half a second unless the fuse is put out
					this.fuse = setTimeout(this.method(this.open), 200);
					this.activeItem = newItem;
					this.state = this.HOT;
				break;
				case this.OPEN:// Switch between main categories
					if (newItem != this.activeItem) {
						this.adjust(newItem);
					}
				break;
				case this.ANIMATING:// Stop and animate to new target
					if (newItem != this.activeItem) {
						this.animator.stop();
						this.adjust(newItem);
					}
				break;
			}
		break;
		case this.LOSTMOUSE:
			switch (this.state) {
				case (this.HOT):// Lost the mouse, cancel menu opening
					clearTimeout(this.fuse);
					this.activeItem = null;
					this.state = this.CLOSED;
				break;
				case (this.OPEN):// Close it
					this.close();
				break;
				case this.ANIMATING:// Stop and animate to closed position
					this.animator.stop();
					this.close();
				break;
			}
		break;
	}
}
Navigation.prototype.open = function () {
	this.state = this.ANIMATING;
	this.animator = new ANNI(menuInitItemHeight, this.activeItem.height, this.method(this.setHeight), this.method(this.opened));
	this.animator.start();
}
Navigation.prototype.opened = function () {
	this.state = this.OPEN;
	this.animator = null;
}

Navigation.prototype.close = function () {
	this.state = this.ANIMATING;
	this.animator = new ANNI(this.currentHeight, menuInitItemHeight, this.method(this.setHeight), this.method(this.closed));
	this.animator.start();
}
Navigation.prototype.closed = function () {
	this.state = this.CLOSED;
	this.activeItem = null;
	this.animator = null;
}
Navigation.prototype.adjust = function (newItem) {
	this.state = this.ANIMATING;
	this.activeItem = newItem;
	this.animator = new ANNI(this.currentHeight, this.activeItem.height, this.method(this.setHeight), this.method(this.opened));
	this.animator.start();
}
Navigation.prototype.isChild = function (candidate) {
	while (candidate && candidate != this.rootNode.parentNode) {
		if (candidate == this.rootNode) return true;
		try {
			candidate = candidate.parentNode;
		} catch (c) {return false}
	}
	return false;
}
Navigation.prototype.setHeight = function (x) {
	this.currentHeight = x;
	var height=(x+16)/10;
	this.rootNode.style.height = height+"em";
	//if(document.all){
	//	this.iframe.style.height = height+"em";
	//	this.iframe.style.marginTop = -height+"em";
	//}
}
Navigation.prototype.calculateMenuHeight = function (list) {
	var total = 0;
	var items = list.getElementsByTagName("a");
	for (var i=0; i < items.length; i++) {
		if (items[i].parentNode.parentNode == list)
			total += menuItemHeight;
		else
			total += 0;
	}
	return total+menuItemHeight;
}
Navigation.prototype.recalculateMenuHeight = function (list) {
	var items = list.submenu.getElementsByTagName("li");
	var level1items = 0;
	for (var i=0; i < items.length; i++) {
		if (items[i].parentNode == list.submenu) {
			if ((level1items*menuItemHeight) + items[i].menuitem.height > list.height-menuItemHeight)
				items[i].menuitem.height = (level1items*menuItemHeight) + items[i].menuitem.height;
			else
				items[i].menuitem.height = list.height;
			level1items += 1;
		}
	}
}
Navigation.prototype.destroy = function() {
	this.rootNode.onmouseout=null;
	var lis = this.rootNode.getElementsByTagName("li");
	for (var i = 0; i < lis.length; i++) {
		lis[i].onmouseover = lis[i].onmouseout = null;
	}
}



NavigationELKickStart = function() {
	if (window.page) {
		window.navigationCL = new NavigationEL("innerMainNav");
	}
	else {
		// try again in x milliseconds
		setTimeout("NavigationELKickStart()", 100); 
	}
}
NavigationELKickStart(); 

// Set event listeners
addEvent(window, "unload", function(){
	if (window.navigationCL) { window.navigationCL.destroy(); }
});

NavigationEL = function(id){
	this.cl_items = new Array();
	this.load_from = 4;
	this.div = document.getElementById(id);
	this.load();
}

NavigationEL.prototype.load = function(){
	var submenus = this.div.getElementsByTagName("ul");
	for(i = 0; i < submenus.length; i++){
		if(submenus[i].parentNode.parentNode.parentNode == this.div){
			this.cl_items.push(submenus[i]);
		}
	}
	for(i = this.load_from; i < this.cl_items.length; i++){
		this.cl_items[i].className = "expand-left";
	}
	tickle();
}

NavigationEL.prototype.destroy = function() {
	
	//if(!window.page.hasSupport()) return;
	
	// Kill objects to prevent memory leaks due to closures. - TODO!

}



/*******
** ANNI **	
*******/


ANNI = function (startValue, endValue, f, t, r) {
	this.step  = 20;
	this.rate  = 20;
	this.power = 2;
	this.type  = this.NONE;

	this.min = startValue;
	this.max = endValue;
	this.isReversing = false;
	this.animateFunction = f;
	this.terminateFunction = t;
	this.reversalFunction = r;

	this.precalc = new Array(100);
	for (var i=0; i <= 100; i++) {
		this.precalc[i] = this.calculate(i);
	}
}
ANNI.prototype.NONE      = 0;
ANNI.prototype.EASEIN    = 1;
ANNI.prototype.EASEOUT   = 2;
ANNI.prototype.EASEINOUT = 3;

ANNI.prototype.setStep = function (step) {
	this.step = step;
}
ANNI.prototype.setRate = function (rate) {
	this.rate = rate;
}
ANNI.prototype.setPower = function (power) {
	this.power = power;
	for (var i=0; i <= 100; i++){
		this.precalc[i] = this.calculate(i);
	}
}
ANNI.prototype.setType = function (type) {
	this.type = type;
	for (var i=0; i <= 100; i++){
		this.precalc[i] = this.calculate(i);
	}
}
ANNI.prototype.setAnimateFunction = function (f) {
	this.animateFunction = f;
}
ANNI.prototype.start = function () {
	if (this.interval) return;
	this.time = 0;
	this.isReversing = false;
	this.interval = setInterval(this.method(this.animate), this.rate);
}
ANNI.prototype.reverse = function () {
	this.isReversing = (this.isReversing) ? false : true;
}
ANNI.prototype.stop = function () {
	if (this.interval) clearInterval(this.interval);
	this.interval = null;
}
ANNI.prototype.pause = function () {
	//this.paused = true;
	if (this.interval) clearInterval(this.interval);
}
ANNI.prototype.resume = function () {
	//this.paused = false;
	this.interval = setInterval(this.method(this.animate), this.rate);
}
ANNI.prototype.isAnimating = function () {
	return Boolean(this.interval);
}
ANNI.prototype.animate = function () {
	if (this.time >= 0 && this.time <= 100) {
		this.animateFunction(this.precalc[this.time]);
		this.time = (this.isReversing) ? this.time - this.step : this.time + this.step;
	} else {
		clearInterval(this.interval);
		this.interval = null;
		if (!this.isReversing && this.terminateFunction) this.terminateFunction();
		if (this.isReversing && this.reversalFunction) this.reversalFunction();
	}
}
ANNI.prototype.calculate = function (t) {
	t = t/100;
	var factor;
	switch (this.type) {
		case this.NONE      : factor = this.easeNone(t);break;
		case this.EASEIN    : factor = this.easeIn(t);break;
		case this.EASEOUT   : factor = this.easeOut(t);break;
		case this.EASEINOUT : factor = this.easeInOut(t);break;
	}
	return parseInt(this.min + factor*(this.max-this.min));
}
ANNI.prototype.easeNone = function (t) {
	return t;
}
ANNI.prototype.easeIn = function (t) {
	return Math.pow(t,this.power);
}
ANNI.prototype.easeOut = function (t) {
	return 1-this.easeIn(1-t);
}
ANNI.prototype.easeInOut = function (t) {
	if (t < 0.5) return this.easeIn(t*2)/2;
	return 0.5+this.easeOut((t-0.5)*2)/2;
}