var LinkedList  = Class.create({
	initialize: function(navigation,content,current,mode) {
		
		this.navElements = $(navigation).childElements();		// the nav elements :)
		this.contentElements = $(content).childElements();		// and the content elements
		this.contentLength = this.contentElements.length;	// store the length for easyer acces
		this.currentElement = current || 0;						// the current element
		
		// throw an error if lengths are not identical (for debugging)
		if(this.navElements.length != this.contentElements.length){
			throw("mLinkedListTabs: items in navigation("+this.navElements.length+") must be identical to items in content("+this.contentElements.length+")");
		}
		if(this.currentElement == -1){
			this.currentElement = 0;
			this.navElements.invoke('removeClassName','current');
			this.contentElements.invoke('hide');
		}else{
			this.navElements[this.currentElement].addClassName('current'); // highlight the current tab
			this.navElements[this.currentElement].siblings().invoke('removeClassName','current'); // unhighlight others (cleanup, not realy needed)
		
			this.contentElements[this.currentElement].show(); // show tab content
			this.contentElements[this.currentElement].siblings().invoke('hide'); // hide other tabs
		}
		
		
		// Setup onclick functions
		var oThis = this;
		if(mode != 'hover'){
			this.navElements.each(function(e,index){
				e.onclick = function(){
					oThis.openNumber(index);
					return false;
				};
			});
		}else {
			this.navElements.each(function(e,index){
				e.onmouseover = function(){
					oThis.openNumber(index);
					return false;
				};
			});
			this.navElements.each(function(e,index){
				e.onmouseout = function(){
					oThis.hideCurrent();
					return false;
				};
			});
		}
		
		
	},
	open: function(arg){
		// switch function, depending on what argument is given the correct function is called
		switch(typeof arg){
			case 'object': this.openElememt(arg); break;
			case 'string': this.openElememt(arg); break;
			case 'number': this.openNumber(arg); break;
			default: this.openNumber(0); break;
		}
	},
	openElement: function(el){
		var el = $(el);
		if(el.tagName.toLowerCase() == 'li'){
			// given element is the li tag
			var elCount = el.previousSiblings().length;
		}else {
			// give element is an element inside the li
			var elCount = el.up('li').previousSiblings().length;
		}
		this.openNumber(elCount);
	},
	openNumber: function(nr){
		var nr = nr % this.contentLength; // catch errors with wrong numbers
		
		this.contentElements[this.currentElement].hide();
		this.contentElements[nr].show();
		
		this.navElements[this.currentElement].removeClassName('current');
		this.navElements[nr].addClassName('current');
		
		this.currentElement = nr;
		
	},
	hideCurrent: function(){
		this.contentElements[this.currentElement].hide();
	},
	next: function(){
		this.openNumber((this.currentElement+1)%this.contentLength);
	},
	previous: function(){
		this.openNumber((this.currentElement+this.contentLength-1)%this.contentLength);
	}
});
var LinkedListHome = Class.create({
	initialize: function(container,navigation,loopspeed) {
		this.loopSpeed = loopspeed || 0;
		this.container = $(container); // the container
		this.navElements = $(navigation).childElements();
		this.lockAnimation = false; // lock
		this.elements = $(container).childElements(); // list of all elements
		this.current = 0;	// define current slide
		this.timeout = null;
		
		this.inqueue = -1;
		
		// set height and width hardcoded on container
		this.container.setStyle({
			height: $(container).getDimensions().height + 'px',
			width: $(container).getDimensions().width + 'px'
		});
		
		// set slides as absolute
		this.elements.invoke('setStyle', {
			position: 'absolute', 
			left: '0px', 
			top: '0px',
			height: $(container).getDimensions().height + 'px',
			width: $(container).getDimensions().width + 'px'
		});
		
		this.elements[this.current].show(); // show tab content
		this.elements[this.current].siblings().invoke('hide'); // hide other tabs
		
		var oThis = this;
		this.navElements.each(function(e,index){
			e.onclick = function(){
				oThis.change(index);
				return false;
			};
			e.onmouseover = function(){
				oThis.hover(index);
				return false;
			};
		})
		
		if(this.loopSpeed > 0){
			this.startLoop();
		}
	},
	change: function(target) {
		var target = target % this.elements.length; // catch possible invalid nr
		if(!this.lockAnimation && target != this.current){
			this.inqueue = -1;
			// lock switch
			this.lockAnimation = true;
			
			var currentSlide = this.elements[this.current];
			var nextSlide = this.elements[target]
			// move current to back
			currentSlide.style.zIndex = 10;
			
			// set z-index (in front existing slide) & hide it
			nextSlide.style.opacity = 0;
			nextSlide.style.filter = 'alpha(opacity=0)';
			nextSlide.style.zIndex = 20;
			
			this.navElements[this.current%this.navElements.length].removeClassName('current');
			this.navElements[target%this.navElements.length].addClassName('current');
			
			
			this.current = target;
			var oThis = this;
			// animate
			nextSlide.appear({ 
				duration: 0.6, 
				from: 0, 
				to: 1, 
				afterFinish: function(){
					// unlock switch
					oThis.lockAnimation = false;
					currentSlide.hide();
					if(oThis.inqueue != -1 ){
						oThis.change(oThis.inqueue);
					}else{
						oThis.startLoop();
					}
					
				} 
			});
		}else {
			this.inqueue = target;
		}
	},
	hover: function(nr){
		this.inqueue = nr;
		var oThis = this;
		try{clearTimeout(this.timeout)}catch(e){};
		this.timeout = setTimeout(function(){oThis.change(nr);},300);
	},
	next: function(){
		this.change((this.current + 1)% this.elements.length);
	},
	previous: function(){
		this.change((this.current+this.elements.length - 1)% this.elements.length);
	},
	startLoop: function(){
		var oThis = this;
		try{clearTimeout(this.timeout)}catch(e){};
		this.timeout = setTimeout(function(){oThis.next();},oThis.loopSpeed);
	}
});

function showHideByID(id,el){
	var content = $(id);
	var link = $(el);
	if(content.visible()){
		content.hide();
		link.removeClassName('open');
		link.removeClassName('moreLinkOpen');
		link.innerHTML = "More info";
	}else{
		content.show();
		link.addClassName('open');
		link.addClassName('moreLinkOpen');
		link.innerHTML = "Less info";
	}
}
function showHideContacts(id,el){
	var content = $(id);
	var link = $(el);
	if(content.visible()){
		content.hide();
		link.removeClassName('open');
	}else{
		content.show();
		link.addClassName('open');
	}
}

var LinkedListPack = Class.create({
	initialize: function(container,navigation,loopspeed) {
		this.loopSpeed = loopspeed || 0;
		this.container = $(container); // the container
		this.navElements = $(navigation).childElements();
		this.lockAnimation = false; // lock
		this.elements = $(container).childElements(); // list of all elements
		this.current = this.elements.length-1;	// define current slide
		this.timeout = null;
		
		this.inqueue = -1;
		
		// set height and width hardcoded on container
		this.container.setStyle({
			height: $(container).getDimensions().height + 'px',
			width: $(container).getDimensions().width + 'px'
		});
		
		// set slides as absolute
		this.elements.invoke('setStyle', {
			position: 'absolute', 
			left: '0px', 
			top: '0px',
			height: $(container).getDimensions().height + 'px',
			width: $(container).getDimensions().width + 'px'
		});
		
		var oThis = this;
		this.navElements.each(function(e,index){
			e.onclick = function(){
				oThis.change(index);
				return false;
			};
			e.onmouseover = function(){
				oThis.hover(index);
				return false;
			};
		})
		
		if(this.loopSpeed > 0){
			this.startLoop();
		}
	},
	change: function(target) {
		var target = target % this.elements.length; // catch possible invalid nr
		if(!this.lockAnimation && target != this.current){
			this.inqueue = -1;
			// lock switch
			this.lockAnimation = true;
			
			var currentSlide = this.elements[this.current];
			var nextSlide = this.elements[target]
			// move current to back
			currentSlide.style.zIndex = 10;
			
			// set z-index (in front existing slide) & hide it
			nextSlide.style.opacity = 0;
			nextSlide.style.filter = 'alpha(opacity=0)';
			nextSlide.style.zIndex = 20;
			
			this.navElements[this.current%this.navElements.length].removeClassName('active');
			this.navElements[target%this.navElements.length].addClassName('active');
			
			
			this.current = target;
			var oThis = this;
			// animate
			nextSlide.appear({ 
				duration: 0.6, 
				from: 0, 
				to: 1, 
				afterFinish: function(){
					// unlock switch
					oThis.lockAnimation = false;
					currentSlide.hide();
					if(oThis.inqueue != -1 ){
						oThis.change(oThis.inqueue);
					}else{
						oThis.startLoop();
					}
					
				} 
			});
		}else {
			this.inqueue = target;
		}
	},
	hover: function(nr){
		this.inqueue = nr;
		var oThis = this;
		try{clearTimeout(this.timeout)}catch(e){};
		this.timeout = setTimeout(function(){oThis.change(nr);},300);
	},
	next: function(){
		this.change((this.current + 1)% this.elements.length);
	},
	previous: function(){
		this.change((this.current+this.elements.length - 1)% this.elements.length);
	},
	startLoop: function(){
		var oThis = this;
		try{clearTimeout(this.timeout)}catch(e){};
		this.timeout = setTimeout(function(){oThis.next();},oThis.loopSpeed);
	}
});
