/* icmsmenu.js                                                                                           */
/* purpose:         DHTML menu that works in DOM-browsers and with frames                                */
/* author:          Ueli Leutwyler                                                                       */
/* copyright:       insign gmbh                                                                          */
/* history:
//                          21.10.2004  mh  Fixed some trailing "px" missing.
//					v1.3		09.10.03		bugfix if frameless (scrolling) (ul)            																				     */
//					v1.2		29.09.03		menu checks if document is completely loaded and stops if not (bug fix for ie)                                                                                 
//					v1.1		03.09.03		menu checks if it has permission to write into traget file and stops if not (IE only :-( )
//					v1.0		01.09.03		menu adjusts to visible screenwidth, can open targets in new window
//                  V0.9b       25.08.03        beta-version

// internal global variables
menuid        = 1;

/************************************************************************************/
/* icmsmenu        - class that holds all needed functionality                                                                */
/************************************************************************************/

// -------------- constructor -------------------------
// parameter:
//         targetframe                Name or object of targetframe. If empty, the frame where the script is loaded will be taken.
function icmsmenu(name,targetframe)
{
        //properties
        this.name                = name;
        if(!targetframe)
        {
                this.target = parent;
        }
        else if (typeof(targetframe)=="string")
                this.target = parent.frames[targetframe];
        else
                this.tatget = targetframe;

        this.firstnode        	= new icmsmenunode("masternode","noname","","standard");
        this.firstnode.menu 	= this;
        this.parent             = this;
        this.nodes              = new Array();
        this.links              = new Array();
        this.menu               = this;
        this.master				= true;
        this.nodes['masternode']= this.firstnode;

        this.id                 = menuid;
        menuid++;
        this.target.document.masterDocRef=document;
        this.target.document.masterRef = this;

        //methods
        this.addnode        	= icmsmenu_addnode;
        this.popup              = icmsmenu_popup;
        this.popdn              = icmsmenu_popdn;
        this.ms                 = icmsmenu_ms;                	//internal method to be called by td mouseover of menu
        this.moff               = icmsmenu_moff;        		//internal method to be called by td mousoout of menu
        this.click				= icmsmenu_click;				//internal method to handel clicks
        this.nodevisibility		= icmsmenu_nodevisibility;		//internal
        this.checkstatus		= icmsmenu_checkstatus			//check if menu is still valid and close if not
}

// -------------- addnode -----------------------------
// parameter:
// see constructor of class icmsmenunode
function icmsmenu_addnode(id,name,link,styleset,relpospic,left,top)
{
        return this.firstnode.addnode(id,name,link,styleset,relpospic,left,top);
}

function icmsmenu_popup(id)
{
        // check if target-frame is readonly
        if(typeof(this.target.document)=="unknown") return;
		if(!this.target.document||!this.target.document.body) return;		// check if target-document is ready
		if(typeof(this.target.document.readyState)!="undefined" && this.target.document.readyState!="complete") return;
        if(this.target.document&&this.target.document.createElement)
        {
                // get nodeobject
                nodeobject = this.nodes[id];
				if(!nodeobject) return;
                // check if allready rendered
                nodeDiv=this.target.document.getElementById("icmsmenu_"+this.id+"_"+id);
                if (!nodeDiv)
                {
                        // render
                        newMenu = this.target.document.createElement("DIV");
                        newMenu.id = "icmsmenu_"+this.id+"_"+id;
                        newMenu.style.width = (0 + stylesets[nodeobject.styleset]['width']) + 'px';
                        newMenu.style.zIndex = '2000';
                        newMenu.style.display = "none";
                        // get html for menu
                        newMenu.innerHTML = nodeobject.draw();
                        this.target.document.body.appendChild(newMenu);
                        nodeDiv = newMenu;
                }

                // set position
                nodeDiv.style.position = "absolute";
                corr=true;
                // relative positioning to picture
                if(nodeobject.relpospic!=""&&nodeobject.relpospic)
                {        // found picture
                        nodeobject.curr_left= getImageXfromLeft(nodeobject.relpospic);
                        nodeobject.curr_top = getImageYfromTop(nodeobject.relpospic);

                        // add offset
                        nodeobject.curr_left += nodeobject.left;
                        nodeobject.curr_top  += nodeobject.top;

                        // check if menu leaps over visible window
                        maxVisibleLeft = this.target.document.body.clientWidth;
                        maxMenuLeft = nodeobject.curr_left+stylesets[nodeobject.styleset]['width'];
                        if(maxVisibleLeft<maxMenuLeft)
                        {
                        	// move menu to the left, so it fits to the screen
                        	nodeobject.curr_left-=maxMenuLeft-maxVisibleLeft;
                        }
                        

                }
                else if(nodeobject.left>0||nodeobject.top>0)
                {
                 // absolute positioning
                 nodeobject.curr_left = nodeobject.left;
                 nodeobject.curr_top  = nodeobject.top;
                }
                else
                {
					// relaitve positioning to previous node
					nodeobject.curr_left = getImageXfromLeft("subpos_"+this.id+"_"+nodeobject.id,this.target.document) + stylesets[nodeobject.styleset]['horiz'];
					nodeobject.curr_top = getImageYfromTop("subpos_"+this.id+"_"+nodeobject.id,this.target.document) + stylesets[nodeobject.styleset]['vert'];
					corr=false;
					// check if submenu leaps over the visible area on the right
					maxVisibleLeft = this.target.document.body.clientWidth;
					maxMenuLeft = nodeobject.curr_left+stylesets[nodeobject.styleset]['width'];
                 	if(maxVisibleLeft<maxMenuLeft)
                 	{
						// open menu on the left side of parent
						nodeobject.curr_left -=stylesets[nodeobject.styleset]['width']+stylesets[nodeobject.parent.styleset]['width']-stylesets[nodeobject.styleset]['horiz'];
                 	}
                 	
                }

                // do correction because of scrollbars in target-frame
				if(this.target!=window)
				{
	                if(!stylesets[nodeobject.styleset]['absolute']&&corr)
	                {
	                                nodeobject.curr_left += this.target.document.body.scrollLeft;
	                                nodeobject.curr_top  += this.target.document.body.scrollTop ;
	                }
	            }
               nodeDiv.style.left = (0 + nodeobject.curr_left) + 'px';
               nodeDiv.style.top  = (0 + nodeobject.curr_top) + 'px';

                this.target.document.masterDocRef=document;        		// make sure target has got reference to nav-functionality
                this.target.document.masterRef = this;

				for(i=0;i<nodeobject.parent.subnodes.length;i++)		// hide opened siblings
				{
					if(nodeobject.parent.subnodes[i].open)
					{
						nodeobject.parent.subnodes[i].hide();
					}
										
				}
                nodeobject.parent.open=true;

				// unmark previously marked nodes
				if(this.markednode)
				{
					this.markednode.mark(false);
				}
				
				// mark node and its parents that have been selected (by url)
				node = this.links[this.target.document.location.href];
				if(node)
				{
					// found matching node
					this.markednode = node;
					node.mark(true);
				}
                nodeobject.show();									// make it visible    
                nodeobject.show();		
                nodeobject.show();		// für IE auf Mac die Schwarte!!!							// make it visible
                

        }


}
function icmsmenu_popdn(id)
{
        if(typeof(this.target.document)=="unknown") return;
		if(!this.target.document||!this.target.document.body) return;		// check if target-document is ready
        if(this.target.document&&this.target.document.createElement)
        {
                // get nodeobject
                nodeobject = this.nodes[id];
				if(!nodeobject) return;
				nodeobject.renewHideTimeout();
		}	
}
// handle mouseover of open node
function icmsmenu_ms(id)
{
        nodeObject = this.nodes[id];										// get nodeObject
        if(nodeObject.waiter) window.clearTimeout(nodeObject.waiter);	
        window.clearTimeout(nodeObject.parent.hidetimeout);
        
        if(nodeObject.ms) return;											// only do if not already done

		if(nodeObject.parent.openchild)      								// close previously opened child
		{
			nodeObject.parent.openchild.hide();
		}

		if(nodeObject.parent.lastMS)										// set style of previuosly focused item
		{
			nodeObject.parent.lastMS.setstyle(false);
		}
		nodeObject.parent.lastMS = nodeObject;
		

		nodeObject.ms = true;												// mark this item
		nodeObject.lockParents();											// tell parents that this item has mousefocus

		nodeObject.setstyle(true);											// set style of object
		
        // open child if there are any
        if(nodeObject.subnodes.length>0)
        {
			nodeObject.parent.openchild = nodeObject;						// tell parent which child is open
			this.popup(nodeObject.id);										// plot child-menu
        }
        
}


function icmsmenu_moff(id)
{
        nodeObject = this.nodes[id];
        if(nodeObject.ms==false) return;

        nodeObject.setstyle(false);										// set mouse-out-style
        nodeObject.ms = false;
        nodeObject.freeParents();										// tell parents that mouse is no longer over this item
        nodeObject.parent.renewHideTimeout();
}

function icmsmenu_click(id)
{
	
	// hide everything
	nodeobject=this.nodes[id];										
	while(nodeobject.parent)
	{
		if(nodeobject.parent.name=="noname") break;
		nodeobject=nodeobject.parent;
	}
	nodeobject.hide();
	
	nodeobject=this.nodes[id];										
	if(nodeobject.target)
	{
		// open in new frame width given parameter
		params = nodeobject.target.split(":");
		if(!params[1]) params[1]=stylesets[nodeobject.styleset]['windowparams'];
		window.open(nodeobject.link,params[0],params[1]);
		
	}
	else
	{
		this.target.location= nodeobject.link;
	}
	
}


function icmsmenu_nodevisibility(id,show)
{
	this.nodes[id].setVisibility(show);
}

function icmsmenu_checkstatus(id)
{
	nodeobject=this.nodes[id];											// close node if neither mouse is on or child has focus
	if(!nodeobject.open) return;
	if(!nodeobject.msnode&&!(nodeobject.openchild&&nodeobject.openchild.msnode))
	{
		nodeobject.hide(true);											// hode this menu including parent if nessessairy
	}
	
}


/************************************************************************************/
/* icmsmenunode        - class that holds information of single node                                                */
/************************************************************************************/

// -------------- constructor -------------------------
// parameter:
// id 						unique id that will be used to handle node later
// name                     shown name (can contain html-code)
// link                     link if clicked (can be left empty)
//							if link is an array, this array will be interpreted as follow:
//							0:	url
//							1:	target (empty if in same frame as calling script, _blank etc. if on other frame)
//								can have optional parameter
//								_blank:widht=150,height=200,status=yes etc.
//							2:	statusline
//							3:	title-tag
// styleset                 name of varibable that holds the definition (if left empty or null, styleset from parent will be taken)
// relpospic                name of picture that is taken as reference for position (optional)This picture must be embedded in file that calls function popup
// left,top                 shift to position of picture. If relpospic is empty, left and top are taken for absolute positioning
//                          	if left empty relative postitioning to parent object will be taken
function icmsmenunode(id,name,link,styleset,relpospic,left,top)
{
        // properties
        this.id             = id;
        this.name           = name.replace("'","\'");
        this.link           = link;
        this.styleset       = styleset;
        this.subnodes       = new Array();
        this.parent        	= null;
        this.menu           = null;
        this.relpospic      = relpospic;
        this.left           = left;
        this.top            = top;
        this.open           = false;
        this.locked         = false;
		this.ms				= false;
		this.msnode			= null;
		this.hidetimeout	= null;
		this.marked			= null;
		
        // initialisation
        if(typeof(this.link)=="object")
        {
			this.target		= this.link[1];
			this.statusline	= this.link[2].replace("'","\'");
			this.titletag	= this.link[3].replace("'","\'");
			this.link		= this.link[0];
			if(this.link.substr(0,1)=="%") this.link="";
        }
        else
        {
        	this.target		= "";
        	this.statusline	= "";
        	this.titletag	= "";
        }
        
        // methods
        this.addnode        = icmsmenunode_addnode;
        this.draw           = icmsmenunode_draw;
        this.setVisibility	= icmsmenunode_setVisibility;
        this.hide			= icmsmenunode_hide;
        this.show			= icmsmenunode_show;
        this.setstyle		= icmsmenunode_setstyle;
        this.renewHideTimeout = icmsmenunode_renewHideTimeout;
        this.lockParents	= icmsmenunode_lockparents;
        this.freeParents	= icmsmenunode_freeparents;
        this.mark			= icmsmenunode_mark;
}

// -------------- addnode -------------------------
// parameter:
//         see constructor
function icmsmenunode_addnode(id,name,link,styleset,relpospic,left,top)
{
        newNode = new icmsmenunode(id,name,link,styleset,relpospic,left,top);
        if(newNode.styleset==""||!newNode.styleset) newNode.styleset = this.styleset;
        newNode.parent        = this;
        newNode.menu        = this.menu;
        this.menu.nodes[id] = newNode;
        if(newNode.link)
        {
			// calculate absolute url if relative
			if(newNode.link.substr(0,4)=="http"||newNode.link.substr(0,1)=="/")
			{
				this.menu.links[newNode.link] = newNode;	
			}
			else
			{
				current=this.menu.target.document.location.href;
				current=current.substr(0,current.lastIndexOf("/"));
				link = newNode.link;
				while(link.substr(0,3)=="../")
				{
					current=current.substr(0,current.lastIndexOf("/"));
					link = link.substr(3);
				}
				link = current+"/"+link;
		        this.menu.links[link] = newNode;
			}
			
        }
        
        this.subnodes[this.subnodes.length] = newNode;
        return newNode;
}

// --------------- draw ---------------------------
// parameter:
//         none
// Purpose: generates HTML-code all subnodes
function icmsmenunode_draw()
{
        style = stylesets[this.styleset];
        
        // table definition
        html  = "<table width=\""+style['width']+"\"";
        if(style['style_tb']!="") html +=" class=\""+style['border']+"\"";
        html += " cellpadding=\"0\" cellspacing=\"0\">";

        // to TRs
        for(i=0;i<this.subnodes.length;i++)
        {
                // prepare mouseover
                cursor = this.subnodes[i].link? "style=\"cursor:pointer;\"":"";
                ms = " onmouseover=\"document.masterRef.ms('"+this.subnodes[i].id+"');status='"+this.subnodes[i].statusline.replace("'","´")+"';return true\" onmouseout=\"document.masterRef.moff('"+this.subnodes[i].id+"');status='';\"";
				title = this.subnodes[i].titletag?" title=\""+this.subnodes[i].titletag.replace("'","´")+"\" ":"";
				link = "";
				if(this.subnodes[i].link)
					link = " onclick=\"document.masterRef.click('"+this.subnodes[i].id+"')\" ";
				
                // TR and outer TD definition
                html += "<tr "+ms+title+link+cursor+"><td class=\""+style['row_mouseoff']+"\" id=\"tr_"+this.menu.id+"_"+this.subnodes[i].id+"\">";
                
                tds=" class=\""+style['text_mouseoff']+"\"";
				text = this.subnodes[i].name;
                
                // inner table
                html += "<table width=\"100%\" cellpadding=\"0\" cellspacing=\"0\"><tr id=\"innertr_"+this.menu.id+"_"+this.subnodes[i].id+"\">";
                if(this.subnodes[i].subnodes.length)
                {        // with subnodes
                        html +="<td"+tds+">"+text+"</td>";
                        html +="<td align=\"right\""+tds+"><img id=\"subpos_"+this.menu.id+"_"+this.subnodes[i].id+"\"src=\""+style['subpic']+"\"></td>";
                }
                else
                {        // without subnodes
                        html +="<td colspan=\"2\""+tds+">"+text+"</td>";
                }
                html += "</tr></table></td></tr>";
        }

        html += "</table>";
        return html;
}

function icmsmenunode_setVisibility(show)
{
	nodeDiv=this.menu.target.document.getElementById("icmsmenu_"+this.menu.id+"_"+this.id);
	if (nodeDiv)
	{
		nodeDiv.style.display = show ? "" : "none";
	}
}
	
function icmsmenunode_hide(includeparents)
{	
	this.open = false;
	clearTimeout(this.hidetimeout);

	this.setVisibility(false);
	this.ms= false;

	// close children if any are opened
	if(this.openchild)
	{
		this.openchild.hide(true);
	}

	if(this.parent&&includeparents)								
	{
		this.parent.openchild = null;				// tell parent that child has been closed
		setTimeout(this.menu.name+".checkstatus(\""+this.parent.id+"\")",100);		// close parent if no mouse came over it
	}
	this.locked=false;
	
	
	for(i=0;i<this.subnodes.length;i++)
	{
		this.subnodes[i].setstyle(false);
		this.subnodes[i].ms=false;
	}
	
}
function icmsmenunode_show()
{
	if(this.parent.open)
	{

		this.open = true;
		this.setVisibility(true);
	}

}

function icmsmenunode_renewHideTimeout()
{
	clearTimeout(this.hidetimeout);
	this.hidetimeout=setTimeout(this.menu.name+".checkstatus(\""+this.id+"\")",stylesets[this.styleset]['hidedelay']);
}

function icmsmenunode_setstyle(mouse)
{
	add = this.marked?"sel_":"mouse";
	add = mouse?add+"on":add+"off";	
    styleset = stylesets[this.styleset];
    // change style of td around inner table (= every row)
    mytd=this.menu.target.document.getElementById("tr_"+this.menu.id+"_"+this.id);
	
    if(mytd)
    	mytd.className = styleset["row_"+add];
    
    // change styles of all tds in inner table
    myTr = this.menu.target.document.getElementById("innertr_"+this.menu.id+"_"+this.id);
    if(myTr)
    {
            myTd = myTr.firstChild;
            myTd.className=styleset["text_"+add];
            while(myTd=myTd.nextSibling)
                    myTd = myTd.className=styleset["text_"+add];
    }

}

function icmsmenunode_mark(markit)
{
	this.marked=markit;
	// set style
	this.setstyle();
	if(this.parent) this.parent.mark(markit);		
}


function icmsmenunode_lockparents()
{
	myparent = this.parent;
	while(myparent)
	{
		if(myparent.setstyle)
		{
			myparent.msnode=this;
			if(!this.parent.marked) myparent.setstyle(true);
			myparent=myparent.parent;
		}
		
	}
	
}

function icmsmenunode_freeparents()
{
	myparent = this.parent;
	while(myparent)
	{
		if(myparent.msnode==this) myparent.msnode=null;
		myparent.setstyle(false);
		myparent=myparent.parent;
	}
	
}


// additional functions
// funcitons to get position of a picture
function docjslib_getRealLeft(imgElem) {
        xPos = imgElem.offsetLeft; 		
        tempEl = imgElem.offsetParent;
          while (tempEl != null) {
                  xPos += tempEl.offsetLeft;
                  tempEl = tempEl.offsetParent;
          }
        return xPos;
}

function docjslib_getRealTop(imgElem) {
        yPos = imgElem.offsetTop;
		//alert(yPos);
        tempEl = imgElem.offsetParent;
        while (tempEl != null) {
                  yPos += tempEl.offsetTop;
                  tempEl = tempEl.offsetParent;
          }
        return yPos;
}

function getImageXfromLeft(imgID,mydoc) {
  if(!mydoc) mydoc = document;
  myImage = mydoc.getElementById(imgID);
  if(!myImage)
  {
//  	alert("Achtung!\nDas Bild "+imgID+", welches zur relativen Positionierung gebraucht wird, scheint nicht vorhanden zu sein.");
  	return false;
  }
return docjslib_getRealLeft(myImage);
}

function getImageYfromTop(imgID,mydoc) {
  if(!mydoc) mydoc = document;
  myImage = mydoc.getElementById(imgID);
  if(!myImage)
  {
//  	alert("Achtung!\nDas Bild "+imgID+", welches zur relativen Positionierung gebraucht wird, scheint nicht vorhanden zu sein.");
  	return false;
  }
	return docjslib_getRealTop(myImage);
}

