var bilderJsExists;
var indexJsExists;
var NavLevelObjektJsExists;
var ImageLevelObjektJsExists;
var ComplexNavLevelObjektJsExists;

/////////sema
function Semaphore() {
	this.value			=1;
	this.condP			=SemaphoreCondP;
	this.V				=SemaphoreV;
	if(arguments.length==1) this.value=arguments[0];
}
function SemaphoreCondP() {
	if(!this.value) return 1;
	this.value--;
	return 0;
}
function SemaphoreV() {
	this.value++;
}
/////////Navi
function NaviObjekt(hallotop){
	if(NavLevelObjektJsExists==null && 	ComplexNavLevelObjektJsExists==null){
		alert("decinavi.js:Die Datei (Complex)NavlevelObjekt.js wurde nicht geladen");}

	this.statAusnahme=null;
	this.spaceGif           ="images_navigation/platzhalter.gif";
	this.delay              =1000;
	this.debug				="";
	this.status               ="";
//level
	this.maxLevel			=0;
	this.levels				=new Array();
	this.levelobjs			=new Array();

	this.menus                =new Array();
	this.timer                =0;

	this.mutex=new Semaphore();

	if(bilderJsExists)
		this.bild=new bilder();
	else 
		this.bild=null;

	if(indexJsExists)
		this.index=new index();
	else
		this.index=null;

//	this.TOP=hallotop;

//	this.path                 =this.TOP.document.URL;
	this.TOP=window;
	this.path                 =window.document.URL;
	if(-1<this.path.lastIndexOf("/")) 
		this.path=this.path.slice(0,this.path.lastIndexOf("/")+1);


	this.leastCreatedObject	  ="";
	this.std_target			  ="main";

	if(-1<this.path.lastIndexOf("/")) 
		this.path=this.path.slice(0,this.path.lastIndexOf("/")+1);

	// methods during init
	this.init				=dummy;

	// methods during runtime
	this.setStatus            =NavigationSetStatus;

	// internal methods
	this.getChildren          =NavigationGetChildren;
	this.getParent            =NavigationGetParent;
	this.parentIsHighlighted  =NavigationParentIsHighlighted;
	this.displayMenu          =NavigationDisplayMenu;
	this.displayData          =NavigationDisplayData;
	this.displayGif           =NavigationDisplayGif;
	this.clearTimer           =NavigationClearTimer;

	

////////////////////////////
	if(bilderJsExists){
		this.addBild=NaviAddBild;
		this.addBildParam=NaviAddBildParam;
		this.setBild=NaviSetBild;
		this.addBildReaktion=NavigationAddBildReaktion;
		this.bildReaktion=NavigationBildReaktion;
	}else{
		this.addBild=dummy;
		this.addBildParam=dummy;
		this.setBild=dummy;
		this.addBildReaktion=dummy;
		this.bildReaktion=dummy;
	}
	if(indexJsExists){
		this.addIndexKey=NaviAddIndexKey;
		this.addIndexTitle=NaviAddIndexTitle;
		this.printIndex=NaviPrintIndex;
	}else{
		this.addIndexKey=dummy;
		this.addIndexTitle=dummy;
		this.printIndex=dummy;
	}
	this.addLevel		=NaviAddLevel;
	this.addLevelParam	=NaviAddLevelParam;

	this.add			=NaviAdd;
	this.addParam		=NaviAddParam;

	
	this.start=NaviStart;
	// initial data (root menu element)
	this.add("","",0,"","","","","","","","");
}

function NaviStart(status){
	if(this.status!="")
		this.setStatus(1,this.status);
	else
		this.setStatus(1,"a0");
	this.TOP.sema=1;
	if(status!=""){
		this.statAusnahme=1;
		stat(status);
		this.statAusnahme=null;
	}
}
function NaviAddLevel(){
	var wArray=new Array();
	var hArray=new Array();
	var tmp=new Array();
	for(var i=0; i<arguments.length; i+=2) {
		tmp[arguments[i]]=arguments[i+1];
	}
	this.maxLevel++;
	this.levels[this.maxLevel]=new Array();
	if(arguments.length==8){
		if(NavLevelObjektJsExists==null){alert("decinavi.js:Die Datei NavlevelObjekt.js wurde nicht geladen");}
		this.levelobjs[this.maxLevel]=new NavLevel(tmp["frame"],tmp["name"],tmp["wArray"],tmp["hArray"]);
	}else{
		if(ComplexNavLevelObjektJsExists==null){alert("decinavi.js:Die Datei ComplexNavlevelObjekt.js wurde nicht geladen");}
		this.levelobjs[this.maxLevel]=new ComplexNavLevel(
			"frame",			tmp["frame"],
			"name",				tmp["name"],
			"wArray",			tmp["wArray"],
			"hArray",			tmp["hArray"],
			"left",				tmp["left"],
			"top",				tmp["top"],
			"zwischenabstand",	tmp["zwischenabstand"],
			"sliderlayer",		tmp["sliderlayer"],
			"slideroffsetleft",	tmp["slideroffsetleft"],
			"slideroffsettop",	tmp["slideroffsettop"],
			"slideroffset",		tmp["slideroffset"]
		);
	}
}

function NaviAddLevelParam(){
	for(var i=0; i<arguments.length; i+=2) {
		this.levels[this.maxLevel][arguments[i]]=arguments[i+1];
	}
}
function NaviAdd(objectName,
                 parentName,
                 selected){
	var m                    =new Array();
	m['name']                =objectName;
	m['selected']                =selected;
	for(var p in this.menus) {
		if(p==parentName) {
			m['parentElement']=this.menus[p];
			break;
		}
	}
	m['level']               =(m.parentElement)?m.parentElement['level']+1:0;
	m['pos']                 =this.getChildren(m.parentElement).length;
	var level=m['level'];
	if(level>this.maxLevel) {
		this.levels[level]                 =new Array;
		this.levels[level]['selected']     =null;
		this.levels[level]['highlighted']  =null;
		this.maxLevel=level;
	}
	this.menus[objectName]   =m;
	this.leastCreatedObject=objectName;
}
function NaviAddParam(){
	var arg1;
	var arg2;
	for(var i=0; i<arguments.length; i+=2) {
		arg1=arguments[i];
		arg2=arguments[i+1];
		if(arg1=="key"){
			this.addIndexKey(this.leastCreatedObject,arg2);
			continue;
		}
		if(arg1=="title"){
			this.addIndexTitle(this.leastCreatedObject,arg2);
			continue;
		}
		this.menus[this.leastCreatedObject][arguments[i]]=arguments[i+1];
	}
}
//////////////////////////////////////////////////////////////////////////////
//
// Interne Hilfs-Funktionen
//
//////////////////////////////////////////////////////////////////////////////
function debug(t) { 
	if(navi.debug=="") return;

	if(!parent.frames[navi.debug]) {alert("no top initial"); return;}
	parent.frames[navi.debug].document.write(t+"<br>"); 
}
////////////////////////////////////////////////////////
//
// Navigation object
//
////////////////////////////////////////////////////////

function NavigationSetStatus(mode)                {
//       NavigationSetStatus(mode,stat)           
//       NavigationSetStatus(mode,level,position) 
//
//       parameter:
//         mode
//           0 ~ RESET            
//               Reset the state to current state stored in environment. 
//               Null out temporary state.
//               The parameters "stat", "level", and "position" are ignored.
//           1 ~ SET              
//               Set the state to state stored in environment or provided
//               by "stat" or "level,position". 
//               Null out temporary state.
//           2 ~ TMPSET 
//               Set the state to state stored in environment or provided
//               by "stat" or "level,position". 
//         
//         stat
//           Valid state name. Used to set state or temporary state.
//
//         level,position
//           Set state (or temporary state) to the value represented
//           by the button on menu level "level" at position "position"
//

	////////////////////////////////////////////////////////////////////
	//
	// set state or temporary according to level and position
	//
	if(arguments.length==3) {
		var level           =arguments[1];
		var position        =arguments[2];
		var parentElement   =this.getParent(level);
		if(!parentElement)  return; 

		var parentPosition  =parentElement.pos-1;
		var offset          =this.levels[level].offset;
		var realPosition    =position-(parentPosition*offset);

		var stat            =null;
		var siblings		=null;

		if(this.levels[level] && parentElement) {
			siblings=this.getChildren(parentElement);
			if(siblings[realPosition])
				stat=siblings[realPosition].name;
		}
		if(!stat) return;

		this.button=stat;
		this.setStatus(arguments[0],stat);
		return;
	}

	////////////////////////////////////////////////////////////////////
	//
	// set state or temporary state
	//
	if(arguments.length==2) {
		var stat=arguments[1];
		switch (mode) {
			case 0:
				// reset state, ie. we have to null out
				// the temporary state. Do NOT modify the
				// state variable itself, it still contains
				// the valid value.

				this.tmpstatus=null;
				break;
			case 1:
				// set state 
				this.status=stat;
				this.tmpstatus=null;
				break;
			case 2: 
				// set temporary state
				this.tmpstatus=stat; 
				break;
		}
		this.setStatus(mode);
		return;
	}

	////////////////////////////////////////////////////////////////////
	//
	// the real operation, (re)set state or set temporary state - refresh
	// the display
	//
	//
	// modes of operation:
	// mode==1 ~ SET       => set state
	//                        set data
	//                        clear tmp state
	// mode==0 ~ RESET     => set state
	//                        clear tmp state
	//
	// mode==2 ~ SETTMP    => set temporary state
	//
	// function:
	// - Find real (final) state
	// - Fix status information for all levels above
	// - Wipe out status for all levels below
	// - Display menus, gif and data fields
	//

	var stat;
	switch (mode) {
		case 0:
		case 1:
			if(!this.status || this.status=="") return;
			this.tmpstatus=null;
			stat=this.status;
			break;
		case 2: 
			if(!this.tmpstatus || this.tmpstatus=="") return;
			stat=this.tmpstatus;
			break;
	}
	////////
	// descend to find REAL (temporary) status
	//
	var current=this.menus[stat];
	var children;
	for(var i=0;i<1000;i++) {
		if(mode==2){
			if(this.levels[current.level].highlight==0)break;
		}

		children=this.getChildren(current);
		if(!children || children.length==0) break;
		var h=0;
		for(var c=1;c<children.length;c++) 
			if(children[c].selected>children[h].selected) h=c;
		current=children[h];
	}
	switch (mode) {
		case 0:
		case 1:
			this.status=current.name;    // real status
			break;
		case 2: 
			this.tmpstatus=current.name; // real temporary status
			break;
	}
	//////// 
	// null out unused levels
	//
	if(mode!=2){
	for(var i=this.maxLevel;i>current.level;i--) {
//		this.levels[i].selected=this.levels[i].highlighted=null;
		this.levels[i].selected=null;
		this.levels[i].highlighted=null;

		this.levels[i].update=2;
		this.levels[i].lastParentElement=null;
	}
}
	//////// 
	// find way to top level
	//
	for(var c=current;c && c.name!="";c=c.parentElement) {
		this.levels[c.level].update=1;
		if(!c.parentElement || 
		   !this.levels[c.level].lastParentElement || 
		   c.parentElement!=this.levels[c.level].lastParentElement) 
			this.levels[c.level].update=2;
		switch (mode) {
			case 0:
			case 1:
				this.levels[c.level].selected   =c;
				this.levels[c.level].highlighted=null;
				break;
			case 2:
				this.levels[c.level].highlighted=c;
				break;
		}

		this.levels[c.level].lastParentElement=c.parentElement;
	}


	////////
	// display levels (top down)
	//
	for(var i=1;i<=this.maxLevel;i++) this.displayMenu(i); 

	////////
	// display data
	//
	if(mode==1) this.displayData();

	////////
	// display gif
	//
	this.displayGif();
}

function NavigationDisplayMenu(level) {
	var parentElement   =this.getParent(level);
	var tmp      =this.parentIsHighlighted(level);
	var siblings =this.getChildren(parentElement);

	var offset   =0;
	var parentpos=0;
	if(parentElement) {
		parentpos=parentElement.pos-1;
		offset   =this.levels[level].offset*parentpos;
	}
	var bildaktiv;
	var spalte;
	var lev=this.levels[level];
	for(var i=1;i<=this.levelobjs[level].getAnz();i++){
		if(!parentElement || i<=offset || !siblings[(i-offset)]){
			this.levelobjs[level].set(i-1,0);
			continue;
		}else{
			this.levelobjs[level].set(i-1,1);
		}
		bildaktiv="bPassive";
		if(lev.selected==siblings[(i-offset)]){
			bildaktiv="bActive";
		}else if(lev.highlighted==siblings[(i-offset)]){
			if(tmp)
				bildaktiv="bTmphighlighted";
			else
				bildaktiv="bHighlighted";
		}else{
			if(tmp)
				bildaktiv="bTemporary";
			else
				bildaktiv="bPassive";
		}
		spalte=siblings[(i-offset)].sp;
		this.levelobjs[level].set(i-1,spalte-1,lev[bildaktiv]-1);
	}
}


function NavigationDisplayData() {
	var current=this.menus[this.status];
	while(!current.href) {
		current=current.parentElement;
		if(!current) return;
	}
	var h=current.href;	
	if(h.search("javascript:")!=-1){
		h=h.replace(/javascript\:/,"");
//		h=h.replace(/file:\/\//,"");
		eval(h);
		return;
	}
//	if(this.status == "a0")return;
	if(navigator.appVersion.search("MSIE 5.0")!= -1){h=h.replace(/file:\/\//,"");}
	if(document.all){
		if(current.target==null){
			this.TOP.frames[this.std_target].location.href=h;
		}else{
			this.TOP.frames[current.target].location.href=h;
		}
	}else{
		if(current.target==null){
//		alert(navi.std_target +"  "+ parent.frames[navi.std_target]);
			this.TOP.frames[this.std_target].document.location.href=h;
		}else{
			this.TOP.frames[current.target].document.location.href=h;
		}
	}
}
function NavigationDisplayGif() {
	// Run thru all levels and display the level specific
	// Gif(s). The levels are parsed top down, ie. a more
	// specific Gif (low level Gif) may overwrite a "general"
	// Gif (high level Gif), if both use the same target
	// (same image, same frame, same layer)

	if(!this.bild)return;
	var bildernamen=this.bild.getNames();
	if(bildernamen.length==0)return;

	var lev;
	for(var level=1;level<=this.maxLevel;level++) {
		lev=this.levels[level];
		if(!lev)continue;
		// If the level has a highlighted item, use
		// its GIf!! 
		// Second priority is the selected item.
		// Otherwise we will overwrite the image using a "spacegif".
		
		var current=null;
		if(lev.gifRefreshOnHighlight &&
		   lev.gifRefreshOnHighlight==1)
			current=lev.highlighted;
		if(!current) current=lev.selected;
		if(!current )continue;

		for(var i=0;i < bildernamen.length;i++){
			name=bildernamen[i];
			if(current[name]!=null){
				this.bild.an(name);
				this.bild.set(name,current[name]);
			}
		}

	}
}

function NavigationGetParent(level) {
	if(level>1 && 
	   this.levels[level-1].highlighted && 
	   this.levels[level-1].highlight) 
		return this.levels[level-1].highlighted;
	if(this.levels[level].selected) 
		return this.levels[level].selected.parentElement;
	return null;
} 

function NavigationParentIsHighlighted(level) {
	if(level>1 && 
	   this.levels[level-1].highlighted && 
	   this.levels[level-1].highlight)  
		return 1;
	return 0;
}

function NavigationGetChildren(parentElement) {
	var ret=new Array();
	var n  =0;
	if (!parentElement) return ret;
	for(var i in this.menus) {
		if(this.menus[i]['parentElement']==parentElement) {
			ret[n]=this.menus[i];
			n++;
		}
	}
	return ret;
}
function NavigationClearTimer(reset) {
	if(!this.timer) return;
	this.TOP.clearTimeout(this.timer);
	this.timer=null;
}
function dummy(){}

