Array.prototype.arremove = function(from, to) {
  var rest = this.slice((to || from) + 1 || this.length);
  this.length = from < 0 ? this.length + from : from;
  return this.push.apply(this, rest);
}

//Dit script word aangeroepen in script.js
var NavigatorCollection = Class.create(
{
	initialize: function()
	{
		this.navigators = new Array();
	},
	getNavigator:	function(options)
	{
		//in de var default_arg staan de default waarde van een menu.
		var default_args = {
		'id'				:	"",
		'submenu'			:	"left",
		'activatesubmenu'	:	"hover",
		'activeclass'		:	"active",
		'activeopen'		:	true,
		'effect'			:	"none",
		'effectopenspeed'	:	300,
		'effectclosespeed'	:	100,
		'mouseoutspeed'		:	300,
		'activeitem'		:	""
		}
		//hier worden de menu waarde uitgelezen. Als deze undefined is word de default_arg over genomen.
		for(var index in default_args) {
			if(typeof options[index] == "undefined") options[index] = default_args[index];
		}
		var id;
		var submenu;
		var effect;
		var activeclass;
		var activeitem;
		var activeopen;
		var activatesubmenu;
		var mousoutspeed;
		var effectopenspeed;
		var effectclosespeed;
		
		for(var i in options) 
		{
			switch(i)
			{
				case 'id':
					id = (options[i]);
					break;
				case 'submenu':
					submenu = options[i];
					break;
				case 'effect':
					effect = options[i];
					break;
				case 'activeclass':
					activeclass = options[i];
					break;
				case 'activeopen':
					activeclass = options[i];
					break;
				case 'activeitem':
					activeitem = options[i];
					break;
				case 'activatesubmenu':
					activatesubmenu = options[i];
					break;
				case 'mouseoutspeed':
					mousoutspeed = options[i];
					break;
				case 'effectopenspeed':
					effectopenspeed = options[i];
					break;
				case 'effectclosespeed':
					effectclosespeed = options[i]
					break;
			}
			
		}
		var newNavigator = new Navigator(id,submenu,effect,activeclass,activeitem,activatesubmenu,effectopenspeed,effectclosespeed,mousoutspeed,activeopen);
		this.navigators.push(newNavigator);
	}
});

var Navigator = Class.create(
{
	initialize: function(id,submenu,effect,activeclass,activeitem,activatesubmenu,effectopenspeed,effectclosespeed,mousoutspeed,activeopen)
	{
		this.id = id;
		this.ul;
		this.submenu = submenu;							//submenu geeft je aan welke kan het submenu moet verschijnen 
		this.mouseoutspeed = mousoutspeed;				//mouseoutspeed geeft aan hoe snel na een mousout het active menu verschijnt
		
		this.effect = effect;							//effect is het soort effect bijvoorbeeld none slide of fade
		this.effectopenspeed = effectopenspeed/1000;	//effectspeed geeft aan hoe snel het effect moet worden uitgevoerd
		this.effectclosespeed = effectclosespeed/1000;
		
		this.activatesubmenu = activatesubmenu;			//actucatesubmenu is geeft aan op welke manier het submenu moet worden laten zien dus door middel van een click of een hover
		this.activeclass = activeclass;					//activeclass is de class die wordt meegegeven aan het menu item dat actief is
		this.activeitem = activeitem;					//activeitem is de naam van het item(bijvoorbeeld een logo) dat actief wordt als je de muis er overheen haalt
		this.activateopen = activeopen;
		this.findroot();
		this.menu = this.researchStructure($(this.ul),0,this);
		this.SetMenuChecker();
	},
	findroot: function()
	{
		//findroot vind uit het ul element aan de hand van het id
		if($(this.id).tagName != "UL")
		{
			this.original = this.id;
			this.ul = $(this.id).down('ul').id;
		}
		else
		{
			this.id = this.ul;
		}
	},
	researchStructure: function(elm,level,navigatoritem,path,parent)
	{
		//researchStructure is een recursieve fuctie die zorgt dat de menu structuur wordt omgezet in javascript
		if(level == 0)
		{
			var path 			= new Array();
			var parent			= null;
			
			var navigatoritem 	= new NavigatorItem(this,$(this.ul),this.ul,true,path.clone(),parent);
		}
		elm.childElements().each(function(child)
		{
			if(child.nodeName.toUpperCase() == "LI")
			{
				
				path[level] = child.id;
				path.arremove(level+1,path.length-1);
				var self 		= this;
				var activated 	= (child.hasClassName(this.activeclass))? true : false;
				var ni			= navigatoritem;
				var childitem	= new NavigatorItem(self,child,child.id,activated,path.clone(),navigatoritem);
				this.addBehaviour(childitem);
				navigatoritem.addChild(childitem);
				if(childitem.hasChild())
				{
				    var childul =	$(childitem.id).down('ul');
					
					//functie opnieuw aanroepen zodra er een childelement is
					childitem = this.researchStructure(childul,level + 1,childitem,path);
				}
			}
		}.bind(this))
		return navigatoritem;
	},
	SetMenuChecker : function()
	{
		setInterval(this.MenuChecker.bind(this,undefined),200);
	},
	addBehaviour : function(childitem)
	{
		//De funtionaliteit is uit de observers gehaald.Ze setten alleen booleans
		if(this.activatesubmenu == 'hover')
		{
			Event.observe(childitem.id, 'mouseover', function(event)
			{
				
				childitem.mouseover = true;
				//$('debug').innerHTML = $('debug').innerHTML + childitem.id + childitem.mouseover + '<br/>';
				childitem.mouseout	= false;
				
			}.bind(this))
			Event.observe(childitem.id, 'mouseout', function(event)
			{
				
				childitem.mouseover 		= false;
				//$('debug').innerHTML = $('debug').innerHTML + childitem.id + childitem.mouseover +'<br/>';
				this.SetMouseout(childitem);
				if(childitem.parent != this.menu && this.menu.children.indexOf(childitem.parent) == -1 && childitem.mouseout == true && childitem.parent.mouseout == true)
				{
					Event.stop(event);
				}
			}.bind(this))
		}
		if(this.activatesubmenu == 'click')
		{
			Event.observe(childitem.id, 'click', function(event)
			{
				if(childitem.mouseover)
				{
					childitem.mouseover = false;
				}
				else
				{
					childitem.mouseover = true;
					this.SetMouseover(childitem,'undefined');
				}
				if(childitem.hasChild())
				{
					Event.stop(event);
				}
			}.bind(this))
		}
	},
	SetMouseover: function(childitem,id)
	{
		//Set mousover zorgt dat de booleans goed worden geset voor de click
		if(id == 'undefined')
		{
			var id = childitem.id;
			var childitem = childitem.parent;
		}
		childitem.children.each(function(child)
		{
			if(child.mouseover && child.id != id)
			{
				child.mouseover = false;
				if(child.hasChild() && child.children.pluck('mouseover').indexOf(true) >= 0)
				{
					this.SetMouseover(child,id);
				}
			}
		}.bind(this))
	},
	SetMouseout: function(child)
	{
		//Set mousover zorgt dat de booleans goed worden geset voor de mouseout
		child.mouseout = true;
		if(child.parent != null)
		{
			this.SetMouseout(child.parent);
		}
	},
	MenuChecker : function(navitem)
	{
		//In deze word checkt welke functie voor het menu moet worden aangeroepen
		if(navitem == undefined)
		{
			navitem = this.menu;
			this.menu.haschildren = true;
		}
		if(navitem == this.menu && navitem.children.pluck('mouseover').indexOf(true) == -1)
		{
			 this.OpenActive(undefined);
		}
		else
		{
			if(navitem.hasChild())
			{
				navitem.children.each(function(child)
				{
				 	if(child.mouseover)
				 	{
				 		this.MenuOpener(child);
				 		if(child.hasChild())
				 		{
				 			this.MenuChecker(child);
				 		}
				 	}
				 	else
				 	{
			 			if(navitem != this.menu && this.menu.children.indexOf(navitem) == -1 && child.mouseout == true && child.parent.mouseout == true)
			 			{
			 				this.smoothClose(child);
			 			}
		 				else
		 				{
					 		this.MenuCloser(child);
				 		}
				 	}
				 	if(child.opened && !child.mouseover)
				 	{
				 		this.MenuCloser(child);
				 	}
				}.bind(this))
			}
		}
	},
	smoothClose :function(child)
	{	
		//smoothClose zorgt voor wanneer een mousout gebeurt op een submenu niet alle submenus te gelijk sluiten maar op elkaar wachten
		child.mouseover 		= false;
		child.mouseout 			= false;
		if(child.parent != null)
		{
			if($(child.parent.id).down('ul').visible())
			{
				if(!child.parent.activated)
				{
					var ul = $(child.parent.id).down('ul');
					this.Closer(ul,child,true);
				}
				else
				{
					if(child.hasChild())
					{
						this.smoothClose(child.parent);
					}
				}
			}
		}
	},
	MenuCloser : function(child)
	{
		//MenuCloser zorgt voor het sluiten van een menu
		$(child.id).removeClassName(this.activeclass);
		if(this.activeitem != '' && $(child.id +'_'+ this.activeitem))
		{
			$(child.id +'_'+ this.activeitem).hide();
		}
		if(child.hasChild())
		{
			if($(child.id).down('ul').visible())
			{
				var ul = $(child.id).down('ul');
				this.Closer(ul,child,false);
			}
		}
	},
	Closer: function(ul,child,smooth)
	{
		//Closer is de daadwerkelijke sluit animatie met all checks die daar mee verband houden 
		switch(this.effect)
		{
			case 'fade':
				$(ul.id).fade({ 
					duration: this.effectclosespeed, 
					from: 1, to: 0,
					queue:  { position: 'end', scope: child.id, limit: 1},
					afterFinish: function()
					{
						$(ul.id).hide();
						if(smooth == true)
						{
							this.smoothClose(child.parent);
						}
					}.bind(this)
				})
				break;
			case 'none':
				$(ul.id).hide();
				break;
			case 'slide':
				var effect
				switch(this.submenu)
				{
				 	case 'left':
				 		effect = Effect.BlindLeft;
				 		break;
				 	case 'downblind':
				 		effect = Effect.BlindUp;
				 		break;
				 	case 'downslide':
				 		effect = Effect.SlideUp;
				 		break;
				}
				effect(ul.id,
				{
					duration: this.effectclosespeed,
					queue: { position: 'end', scope: child.id},
					afterFinish: function()
					{
						
						$(ul.id).hide();
						if(smooth == true)
						{
							this.smoothClose(child.parent);
						}
					}.bind(this)
				});
				break;
		}
	},
	MenuOpener : function(child)
	{
		//MenuOpener zorgt voor het openen van een menu
		$(child.id).addClassName(this.activeclass);
		if(this.activeitem != '' && $(child.id +'_'+ this.activeitem))
		{
			$(child.id +'_'+ this.activeitem).show();
		}
		if(child.hasChild())
		{
			if(!child.opened)
			{
				if(child.hasChild())
				{
					if(!$(child.id).down('ul').visible())
					{
						child.opened = true;
						var ul = $(child.id).down('ul');
						this.Opener(ul,child);
					}
				}
			}
		}		
	},
	Opener : function(ul,child)
	{
		//Opener is de daadwerkelijke open animatie met all checks die daar mee verband houden 
		switch(this.effect)
		{
			case 'fade':
				ul.appear(
				{
					duration: this.effectopenspeed,
					queue:{ position: 'end', scope: child.id},
					afterFinish: function()
					{
						child.opened 	= false;
						$(ul).show();
					}.bind(this)	
				});
				break;
			case 'none':
				ul.show();
				child.opened = false
				break;
			case 'slide':
				var effect
				switch(this.submenu)
				{
				 	case 'left':
				 		effect = Effect.BlindRight;
				 		break;
				 	case 'downblind':
				 		effect = Effect.BlindDown;
				 		break;
				 	case 'downslide':
				 		effect = Effect.SlideDown;
				 		break;
				}
				effect(ul,
				{
					duration: this.effectopenspeed,
					queue:{ position: 'front', scope: child.id},
					afterFinish: function()
					{
						//$('debug').innerHTML = $('debug').innerHTML +'Open <br/>';
						child.opened 	= false;
						$(ul).show();
					}.bind(this)	
				});
				break;
		}
	},
	OpenActive: function(navitem)
	{
		//OpenActive zorgt voor het openen van het actieve item als er een mouse out plaats vind
		if(navitem == undefined)
		{
			navitem = this.menu
			this.menu.haschildren = true;
		}
		if(navitem.hasChild())
		{
			navitem.children.each(function(child)
			{
				if(child.activated)
				{	
					if(this.activeopen)
					{
						if(child.hasChild())
						{
							this.MenuOpener(child);
							if(child.hasChild())
							{
								this.OpenActive(child);
							}
						}
					}
				}
				else
				{
					this.MenuCloser(child);
					if(child.hasChild())
					{	
						this.OpenActive(child);
					}
				}	
			}.bind(this))
		}
	}
});
var NavigatorItem = Class.create(
{
	initialize: function(nav,extended,elm,activated,path,parent)
	{
		this.nav			= nav; 			//nav is het de Navigator class waarpmder dit NavigatorItem valt
		this.id 			= elm;			//id van het Navigatie element
		this.extended 		= extended; 	//referntie naar het extended Navigatie element
		
		this.path			= path;			//path geeft aan wat de bovenligende NavigatorItems id zijn
		this.parent			= parent;		//parent is het parent van het Navigatie element 
		this.haschildren	= null;
		this.activated		= activated;	//activated geeft aan of het item vanuit PHP actief is gemaakt
		
		this.mouseover		= false;
		this.opened			= false;
		this.mouseout		= false;		
		
		this.children		= new Array;
	},
	addChild: function(child)
	{
		this.children.push(child);
	},
	hasChild: function()
	{
		//hasChild checkt of een NavigatorItem child elementen heeft
		if(this.haschildren == null)
		{
			this.haschildren = false;
			this.extended.childElements().each(function(childElement)
			{
				if(childElement.tagName == "UL")
				{
					this.haschildren = true;
				}
			}.bind(this))
			
		}
		return this.haschildren;
	}
})
