/* settings */
var MenuPrefix="menuLevel_"; /* prefix for each href collection */
var maxLevel=4; /* maximum deepness of menues */
var levelCountStart=0; /* base of counting */
var hrefContainerTag="span"; /* Container around a href */
var selectedClass="nav-aktiv";
var unSelectedClass="nav";
var wrapAround=true; /* scrolling changes to the first (last) Element when its beyond end (beginning) */

var wheelBrake=1; /* slows down the wheel */
var preloadImagesFlag=true; /* preload Images? */

var scrollSpeed=5; /* 0=flip 1 slowest 100=fastest */
var scrollWidth=910; /* scrollwidth in pixel */;

var changeTag="div"
var changeId="innerContent";

var debugMode=false /* normalerweise sollte hier false stehen nur wenn das Script nicht startet mal auf true setzen um eine entsprechende Alert Box angezigt zu bekommen */

		
/* globals */
var MenuItems=new Array();
var activeMenu=-1;
var wheelBrakeCounter=wheelBrake;


var Timers=new Array();

/* classes */


function timerFunction(slot) {
	Timers[slot].action();
}

function ScrollerManager(scrollerClass) {
	this.scrollerClass=scrollerClass;
	this.speed=0;
	this.width=0;
	this.running=false;
	this.timerID=false;
	this.timeSlot=false;
	this.currentPos=0;
}

ScrollerManager.prototype.stop=function() {
	window.clearTimeout(this.timerID);
	this.scrollerClass.completeScroll();
	this.timerID=false;
	this.currentPos=0;
	
}

ScrollerManager.prototype.start=function(speed,width) {
	if(this.running) this.stop();
	this.speed=speed;
	this.width=width;
	if(!this.timeSlot) {
		this.timeSlot=Timers.length;
		Timers[this.timeSlot]=this;
	}
	this.timerID=window.setTimeout("timerFunction("+this.timeSlot+")",10);
}

ScrollerManager.prototype.action=function() {
	this.currentPos+=(this.width*(this.speed/100));
// alert(this.currentPos +"/" + this.width);
	if(this.currentPos < this.width) {
		this.scrollerClass.element.scrollLeft=this.currentPos;
		this.timerID=window.setTimeout("timerFunction("+this.timeSlot+")",10);
	} else {
		this.stop();
	}
}

function Scroller(toScrollId) {
	this.scrollId=toScrollId;
	this.scrollCompleted=true;
	this.currentContent=false;
	this.element=document.getElementById(toScrollId);
	this.scrollManager=new ScrollerManager(this);
}

Scroller.prototype.scroll=function(newContent) {
	if(!this.scrollCompleted) {
		this.completeScroll();
	}
	this.currentContent=newContent;
	this.scrollCompleted=false;
	
	var oldContent=this.element.innerHTML;
	
	var scrollDiv=document.createElement("div");
	scrollDiv.className="contentScroller";
	scrollDiv.innerHTML=oldContent+newContent;
	this.element.innerHTML="";
	this.element.appendChild(scrollDiv);
	
	if(scrollSpeed > 0) {
		this.scrollManager.start(scrollSpeed,scrollWidth);
	} else {
		this.completeScroll();
	}
	
}


Scroller.prototype.completeScroll=function() {
	this.element.innerHTML=this.currentContent;
	this.element.scrollLeft=0;
	this.scrollCompleted=true;
}

function MenuRoller(prefix) {
	this.prefix=prefix;
	this.containsSelected=false;
	this.selectedItem=0;
	this.hrefs=new Array();
	this.cache=new Array()
	this.scroller=new Scroller(changeId);
	this.init();
}

MenuRoller.prototype.init=function() {
	var container=document.getElementById(this.prefix);
	
	if(container) {
		this.hrefs=container.getElementsByTagName(hrefContainerTag==""?'a':hrefContainerTag);
		for(var i=0;i< this.hrefs.length;i++) {
			var ref=this.getReferences(this.hrefs[i]);
			this.cache[i]=new innerCache(ref);
		}
		this.checkSelected();
	}
}

MenuRoller.prototype.getReferences=function(node) {
	
	var result=null;
	
	if(typeof(node) != 'object' ) {
		return(result);
	} 
	
	if(node.nodeName.toLowerCase()=="a") {
		result=node.getAttribute("href");
	} else {
		for (var i=0;i<node.childNodes.length;i++) {
  			var sibling=node.childNodes[i];
			result=this.getReferences(sibling);
			if(result) break;
		}
	}
	return(result);
}

MenuRoller.prototype.checkSelected=function(highlightIfEmpty) {
	var highlightIfEmpty=highlightIfEmpty==null?false:highlightIfEmpty;
	
	this.containsSelected=false;
	this.selectedItem=0;
	for(var i=0;i<this.elementCount();i++) {
		if(this.hrefs[i].className==unSelectedClass) {
			this.containsSelected=true;
			this.selectedItem=i;
			break;
		}
	}
	
	if(highlightIfEmpty && !this.containsSelected) {
		this.highlight(0);
	}
	
}


MenuRoller.prototype.cacheAll=function() {
	for(var i=0;i<this.elementCount();i++) {
		this.cache[i].cache();
	}
}

MenuRoller.prototype.elementCount=function() {
	return(this.hrefs.length);
}


MenuRoller.prototype.highlight=function(toHighlightItem) {
	if(this.containsSelected) {
		this.hrefs[this.selectedItem].className=unSelectedClass;
	}
	
	if(toHighlightItem < 0) {
		if(wrapAround) {
			toHighlightItem=this.elementCount()-1;
		} else {
			toHighlightItem=0
		}
	}
	
	if(toHighlightItem >= this.elementCount()) {
		if(wrapAround) {
			toHighlightItem=0
		} else {
			toHighlightItem=this.elementCount()-1;
		}
	}
	
	this.hrefs[toHighlightItem].className=selectedClass;
	this.containsSelected=true;
	if(this.selectedItem!=toHighlightItem) {
		this.selectedItem=toHighlightItem;
		this.changeView();
	}
}

MenuRoller.prototype.changeView=function() {
	var fragment=this.cache[this.selectedItem].getFragment();
	this.scroller.scroll(fragment);
}

MenuRoller.prototype.scrollSelected=function(delta) {
	var newPos=this.selectedItem+(delta > 0?-1:1);
	this.highlight(newPos);
}


function innerCache(url) {
	this.url=url;	

	this.request=false;
	this.fragment=false;
	this.images=Array();
}

innerCache.prototype.cache=function () {
	if(this.request) return;
	var req = false;
// branch for native XMLHttpRequest object
	if(window.XMLHttpRequest && !(window.ActiveXObject)) {
		try {
			req = new XMLHttpRequest();
		} catch(e) {
			req = false;
		}
// branch for IE/Windows ActiveX version
	} else if(window.ActiveXObject) {
		try {
			req = new ActiveXObject("Msxml2.XMLHTTP");
		} catch(e) {
			try {
				req = new ActiveXObject("Microsoft.XMLHTTP");
			} catch(e) {
				req = false;
			}
		}
	}
	if(req) {
		var cachedObject=this;
		req.onreadystatechange = function(evt) {
			if((req.readyState==4) && (req.status==200)) {
				cachedObject.getFragment();
			}
		}
		req.open("GET", this.url, true);
		req.send("");
	}
	
	this.request=req;

}

innerCache.prototype.getFragment=function () {
	if(!this.fragment) {
		
		var container = document.createElement("div");
		container.innerHTML = this.request.responseText;
		var candidates=container.getElementsByTagName(changeTag);
		var foundFlag=false;
		for(var i=0;i<candidates.length && !foundFlag ;i++) {
			for(var j=0;j<candidates[i].attributes.length && !foundFlag;j++) {
				if(
    					(candidates[i].attributes[j].nodeName.toLowerCase()=="id") && 
					(candidates[i].attributes[j].nodeValue==changeId)
				) {
					this.preloadImages(candidates[i]);
					this.fragment=candidates[i].innerHTML;
					 foundFlag=true;
				}
			}
		}
			
	}
	return(this.fragment);
}

innerCache.prototype.preloadImages=function (node) {
	if(preloadImagesFlag) {
		var imgArr=node.getElementsByTagName(changeTag);
		for(var i=0;i < imgArr.length;i++) {
			var src=imgArr[i].getAttribute("src");
			if(src) {
				this.images[i]=new Image(src);
			}
		}
	}
} 

/* Program */
function runScroller() {
	activeMenu=-1;

	for(var i=0;i<maxLevel;i++) {
		var idString=MenuPrefix+(i+levelCountStart);
		MenuItems[i]=new MenuRoller(idString);
		if(MenuItems[i].elementCount()>0) {
			activeMenu=i;
		}
	}
	if(activeMenu>=0) {
		MenuItems[activeMenu].cacheAll();
		MenuItems[activeMenu].checkSelected(true);
	} else {
		if(debugMode) {
			alert("Scroller did not start: No Elements with idString:"+idString);
		}
	}
}

function wheelEvent(event) {
	if(activeMenu >= 0) {
		var delta = 0;

		if(!event) {
			event=window.event;
		}
		if(event.wheelDelta) {
			delta=event.wheelDelta/120;
			delta*=window.opera?-1:1;
		} else {
			if(event.detail) {
				delta=-event.detail/3;
			}	
		}
		

		if(wheelBrakeCounter==0) {
			MenuItems[activeMenu].scrollSelected(delta);
			wheelBrakeCounter=wheelBrake;
		} else {
			wheelBrakeCounter--;
		}
	
		if(event.preventDefault) event.preventDefault();
	}
	event.returnValue=false;
}


if(window.addEventListener) {
	window.addEventListener("load", runScroller, false);
	window.addEventListener('DOMMouseScroll', wheelEvent, false);
} else {
	window.onload=document.onload=runScroller; /* Warning!! overwrites or is overwirtten by existing onload settings */
	window.onmouswheel=document.onmousewheel=wheelEvent;
}


