/* foldermenu.js                                                                                     	*/
/* purpose:         DHTML menu that works like a openable folder structure								*/
/* need resources:	DOM-browsers and with or without frames				                                */
/* author:          Ueli Leutwyler                                                                      */
/* copyright:       insign gmbh                                                                         */
/* history:																								*/
//					v1.0	17.05.2004	implementation in intranet.spitalbern.ch						*/
//                  V0.0	13.05.2004	start of project


// global vars


/********************************************************************************************************/
// class foldermenu
// Diese Klasse stellt den Container für das Menu dar. Es enthält alle wichtigen Informationen für das 
// Funktionieren des Menus
/********************************************************************************************************/

// constructor
// parameter:
// ----------
// name			Name of instantiated object. Same as varname (eg. myMenu = new foldermenu("myMenu",...)
function foldermenu(name,defaultMenuStyleArray)
{
	// properties
	this.name					= name;
	this.defaultMenyStyleArray 	= defaultMenuStyleArray;
	this.idByIdentifier			= new Array
	this.objectById				= new Array
	this.initialized			= false;
	
	this.root					= new folderItem(name+"_root");		// create root-item to hold all others
	this.root.menu 				= this;								// reference to menuobject
	this.root.isRoot 			= true;
	// methods
	this.addItem	 			= foldermenu_addItem;
	this.open 					= foldermenu_open					// opens all items down to given level
	this.openItemByIdent		= foldermenu_openItemByIdent;		// opens and marks item with given identifier
	this.openItemById			= foldermenu_openItemById;			// opens and marks item with given id
	this.toggle					= foldermenu_toggle					// open or close given object
	this.init					= foldermenu_init
}

function foldermenu_init(levels)
{
	if(this.initialized) return true;
	
	this.root.setLook(true);
	
	this.open(levels);
	
	this.initialized = true;
		
}

function foldermenu_toggle(id)
{
	obj=this.objectById[id];
	if(obj)
	{
		if(obj.subItems.length>0)
		{
			if(obj.opened)
			{
				obj.close();
			}
			else
			{
				obj.open();
			}
		}
		

		
	}
}


function foldermenu_addItem(id, class_array,indentifier,pic_closed,pic_opened,pic_nochildren)
{
	return this.root.addItem(id,class_array,indentifier,pic_closed,pic_opened,pic_nochildren);
}

// levels			if 0, only this item will be opened
//					if -1 all children and subchildren will be opened
//					if x, x levels will be opened (e.g 2. opens the item and all children and grandchildren of it)
function foldermenu_open(levels)
{
	if(!levels) levels = 0;
	this.root.open(levels);
}

function foldermenu_openItemByIdent(identifier)
{
	this.openItemById(this.idByIdentifier["ident_"+identifier]);
}

function foldermenu_openItemById(id)
{
	var obj=this.objectById[id];
	if(obj)
	{
		obj.open(0,true);				// no sublevels but all parents
		obj.mark(true);					// recusrive up
		obj.setLook(false,true);		// not recursive down but recursive up
	}
	
}




/********************************************************************************************************/
// class folderItem
// Diese Klasse stellt die eigentlichen Menupunkte dar. Sie sind immer Kinder eines oberen folderItems.
// Das oberste Objekt vom Typ folderItem wird automatisch von der Klasse foldermenu generiert
/********************************************************************************************************/

// constructor
// parameter:
// ----------
// id											unique id of html-element that this item is represented by

// class_array									an array with information about used styles
// 		the format of this array is as follows
// 		myArray = new Array();
// 		myArray["closed_nolink_notmarked"] = "myClassName";
//		see list below for allowd types. If a type is not defined, default will be used;
//		list of allowed associations:
//			default								default style that is used if no specific className is defined
// 			closed_nolink_notmarked				css-class-name that is used if the item is closed, if there is no link given and if the object is not marked
// 			closed_nolink_makred
//			closed_link_notmarked
// 			closed_link_marked
// 			opened_nolink_notmarked				css-class-name that is used if the item is closed, if there is no link given and if the object is not marked
// 			opened_nolink_marked
// 			opened_link_notmarked
// 			opened_link_marked



function folderItem(id,	class_array,identifier,pic_closed,pic_opened,pic_nochildren)
{
	// properties

	this.id			 = id;
	this.class_array = class_array;
	this.identifier	 = identifier?identifier:null
	this.isRoot		 = false;
	this.opened		 = false;
	this.marked		 = false;
	this.pic_closed	 = pic_closed;
	this.pic_opened	 = pic_opened;
	this.pic_nochildren= pic_nochildren;
	this.hasLink	 = identifier>0?true:false;
	

	this.subItems	 = new Array;
	this.menu		 = null;					// reference to menu-object
	this.parent		 = null;					// refrence to parent-objects
	

	// methods
	this.addItem	= folderItem_addItem;
	this.open		= folderItem_open;
	this.close		= folderItem_close;
	this.getElement	= folderItem_getElement;
	this.openParent	= folderItem_openParent;
	this.show		= folderItem_show;
	this.hide		= folderItem_hide;
	this.setLook	= folderItem_setLook;
	this.setStyle	= folderItem_setStyle;
	this.setPic		= folderItem_setPic;
	this.mark		= folderItem_mark;

}

function folderItem_mark(recursive)
{
	// set mark flag of given item and its parents if recusrive is true
	this.marked = true;
	if(recursive&&this.parent) this.parent.mark(true);
	
}


function folderItem_setLook(recursiveDown,recursiveUp)
{
	this.setPic();
	this.setStyle(this.marked);
	if(recursiveDown)
	{
		for(var i = 0 ;i<this.subItems.length;i++)
		{
			this.subItems[i].setLook(true);
		}
		
	}
	if(recursiveUp&&this.parent)
	{
		this.parent.setLook(false,true);
	}
	
	
}

function folderItem_setStyle(marked)
{
	var stylestring = ""
	
	if(this.opened) 
		stylestring = "opened_";
	else
		stylestring = "closed_";
		
	if(this.hasLink)
		stylestring +=  "link_";
	else
		stylestring +=  "nolink_";
	
	if(marked)
		stylestring +=  "marked";
	else
		stylestring +=  "notmarked";

	myObj = this.getElement('link');
	if(myObj)
	{
		if(this.class_array[stylestring])
		{
			myObj.className= this.class_array[stylestring];
		}
		else
		{
			myObj.className= this.class_array['default'];
		}
		
	}
	
	
}

function folderItem_setPic()
{
	if(this.subItems.length==0 && this.pic_nochildren)
	{
		myPic = this.getElement('pic');
		if(myPic)
		{
			myPic.src = this.pic_nochildren.src;
		}
		
	}
	
	
}



function folderItem_addItem(id, class_array,identifier,pic_closed,pic_opened,pic_nochildren)
{
	var subItem = new folderItem(id, class_array,identifier,pic_closed,pic_opened,pic_nochildren);

	subItem.menu = this.menu;
	subItem.parent = this;
	this.subItems[this.subItems.length] = subItem;

	// initial setting
	if(subItem.identifier)
	{
		var ident = "ident_"+subItem.identifier
		this.menu.idByIdentifier[ident] = subItem.id;
	}

	this.menu.objectById[subItem.id] = subItem;

	return subItem;
}

// levels			if 0, only this item will be opened
//					if -1 all children and subchildren will be opened
//					if x, x levels will be opened (e.g 2. opens the item and all children and grandchildren of it)

function folderItem_open(levels,openParents)
{
	this.show();
	var div = "";  // <- this line added 23.12.2004 by fs
    if (div = document.getElementById('extra_div_' + this.identifier)) {
        div.style.display = '';
    }

	if(this.subItems.length>0 && this.pic_opened)
	{
		if( (picEl=this.getElement('pic')) )
		{
			picEl.src = this.pic_opened.src;
		}
	}
	// open parents if needed
	this.opened = true;

	if(openParents)
	{
		this.openParent(true);	
	}
	
	for(var i=0;i<this.subItems.length;i++)
	{
		this.subItems[i].show();
		
		// open children if needed
		if(levels>0||levels<0)
		{
			this.subItems[i].open(levels-1);
		}
	}
}

function folderItem_close()
{
	this.opened = false;
	if(this.pic_closed)
	{
		if( this.subItems.length>0 && (picEl=this.getElement('pic')) )
		{
			picEl.src = this.pic_closed.src;
		}
	}
	
	for(var i=0;i<this.subItems.length;i++)
	{
		this.subItems[i].hide();
		this.subItems[i].close();
	}
	var div = "";  // <- this line added 23.12.2004 by fs

    if (div = document.getElementById('extra_div_' + this.identifier)) {
        div.style.display = 'none';
    }
}


function folderItem_show()
{
	if(this.isRoot) return;
	if( (myEl=this.getElement('div')) )
	{
		myEl.style.display="";	
	}
}

function folderItem_hide()
{
	if(this.isRoot) return;
	if( (myEl=this.getElement('div')) )
	{
		myEl.style.display="none";	
	}
}

function folderItem_openParent(recursive)
{
	if(this.parent && !this.parent.isRoot)
	{
		this.parent.open();
		if(recursive) this.parent.openParent(true);
	}
	
}



function folderItem_getElement(element)
{
	if(this.isRoot) return false;
	myEl = document.getElementById(element+"_"+this.id);
	if(!myEl)
	{
		alert("Es fehlt ein HTML-Element mit id '"+element+"_"+this.id+"'");
		return false;
	}
	else
	{
		return myEl;
	}
}


