﻿/*

	Lost Boys 2005.
	
	De inhoud van dit bestand is in opdracht vervaardigd en eigendom van onze opdrachtgever.
	Niet hergebruiken zonder toestemming.
	Neem voor vragen contact op met Lost Boys, www.lostboys.nl.

	The contents of this file have been produced for and are the property of our client.
	Do not reuse without permission.
	Any questions? Please contact Lost Boys, www.lostboys.nl.

*/
Navigation = function (nodeID) {
	var navigation = this;

	this.rootNode = document.getElementById(nodeID);
	this.state = this.CLOSED;

	// Add behavior
	this.rootNode.onmouseout = function (e) {
		var destination = (e) ? e.relatedTarget : window.event.toElement;
		navigation.changeState(navigation.LOSTMOUSE, destination, this.menuitem);
	}
	var menuopener = function (e) {
		var destination = (e) ? e.relatedTarget : window.event.toElement;
		navigation.changeState(navigation.GOTMOUSE, destination, this.menuitem);
	}
	var as = this.rootNode.getElementsByTagName("a");
	for (var i=0; i < as.length; i++) {// Only treat 1st level links that have submenu's
		if (as[i].parentNode.parentNode.parentNode == this.rootNode && as[i].parentNode.getElementsByTagName("a").length > 1) {
			as[i].onmouseover = menuopener;

			as[i].menuitem = new Object();
			as[i].menuitem.submenu = as[i].parentNode.getElementsByTagName("ul")[0];
			as[i].menuitem.height =  this.calculateMenuHeight(as[i].menuitem.submenu);
			this.hide(as[i].menuitem.submenu);
		}
	}
	this.animator = null;// Will contain dynamically created Animator objects
}

//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), 300);
					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.show(this.activeItem.submenu);
	this.animator = new Animator(this.rootNode.offsetHeight, 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 Animator(this.rootNode.offsetHeight, 24, this.method(this.setHeight), this.method(this.closed));
	this.animator.start();
}
Navigation.prototype.closed = function () {
	this.state = this.CLOSED;
	this.hide(this.activeItem.submenu);
	this.activeItem = null;
	this.animator = null;
}
Navigation.prototype.adjust = function (newItem) {
	this.state = this.ANIMATING;
	this.hide(this.activeItem.submenu);
	this.show(newItem.submenu);
	this.activeItem = newItem;
	this.animator = new Animator(this.rootNode.offsetHeight, this.activeItem.height, this.method(this.setHeight), this.method(this.opened));
	this.animator.start();
}

Navigation.prototype.setHeight = function (x) {
	this.rootNode.style.height = x+"px";
}
Navigation.prototype.hide = function (object) {
	if (document.all) {object.style.visibility = "hidden"} else {object.style.display = "none";}
}
Navigation.prototype.show = function (object) {
	if (document.all) {object.style.visibility = "visible"} else {object.style.display = "block";}
}
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.calculateMenuHeight = function (list) {
	var total = 0;

	if (list.getElementsByTagName("div").length > 0) {
		var cols = list.getElementsByTagName("div");
		for (var i=0; i < cols.length; i++) total = Math.max(cols[i].offsetHeight, total);
	} else {
		var items = list.getElementsByTagName("a");
		for (var i=0; i < items.length; i++) {
			if (items[i].parentNode.parentNode == list)
				total += 25;
			else
				total += 19;
		}
	}
	return total+30;
}
