/******************************************************************************
*
*                   INDIGEN SOLUTIONS CODE PROPERTY
*       The present javascript code is property of Indigen Solutions. This
*     code can only be used inside Internet/Intranet web sites located on
*  *web servers*, as the outcome of a licensed Indigen Solutions application
*  only. Any unauthorized use, reverse-engineering, alteration, transmission,
* transformation, facsimile, or copying of any means (electronic or not) is
*     strictly prohibited and will be prosecuted. Removal of the present
*              copyright notice is strictly prohibited
*         Copyright (c) 2004 Indigen Solutions. All Rights Reserved.
*
* Author:                      mig
* RCS Id                       $Id: IMenuPopup12.js,v 1.1 2005/11/15 11:27:20 david Exp $
*
******************************************************************************/

/*

This code provides a library to handle popup panels and popup menus.
Usage:

	<script src='ipopup.js'></script>

	<whatever-html-tag id='mytagid'>

	<script>
		new iMenu( // or new iPopup
			'mytagid',
			{ option1: value1, option2: value2, ...});
			);
	</script>

iPopup options:
	elementCorner:		used to determine the popup position relative to the anchor element					
						value is one of:
							iPopup.TOPLEFT
							iPopup.TOPRIGHT
							iPopup.BOTTOMLEFT (default)
							iPopup.BOTTOMRIGHT
	popupCorner:		used to determine the popup position relative to the anchor element					
						value is one of:
							iPopup.TOPLEFT (default)
							iPopup.TOPRIGHT
							iPopup.BOTTOMLEFT
							iPopup.BOTTOMRIGHT
	offsetX:			shift popup horizontal position by this value in pixel (default 0)
	offsetY:			shift popup vertical position by this value in pixel (default 0)
	offsetKQx:			shift popup horizontal position by this value in pixel when browser 
						is Konqueror (default 10)
	offsetKQy:			shift popup vertical position by this value in pixel when browser 
						is Konqueror (default 10)
	offsetMEx:			shift popup horizontal position by this value in pixel when browser 
						is IE for Mac (default -1)
	offsetMEy:			shift popup vertical position by this value in pixel when browser 
						is IE for Mac (default -1)
	closeTimeout:		the timeout in milliseconds to close the popup when mouse is out (default 500)
	panelClass:			the html class for the popup panel (default 'iPopupPanel') 
	anchorId:			used if popup position is relative to an element that is not the element whose
						id is passed as first constructor argument
	width:				force panel width
	minLeftPos:			left edge of popup cannot be below this value (default 0)
	maxRightPos:		right edge of popup cannot be upper this value
	minTopPos:			top edge of popup cannot be below this value (default 0)
	maxBottomPos:		bottom edge of popup cannot be upper this value
	borderTopLeftId:	if set to an element id, the popup cannot be positionned above or at the left of 
						the element
	borderTopLeftCorner: if borderTopLeftId is set, this option indicates the element corner used as the
						reference against the top left corner of the popup (default iPopup.TOPLEFT)
	borderBottomRightId: 	if set to an element id, the popup cannot be positionned below or at the right of 
						the element
	borderBottomRightCorner: if borderBottomRightId is set, this option indicates the element corner used as the
						reference against the bottom right corner of the popup (default iPopup.BOTTOMRIGHT)

iMenu options:
	all iPopup options
	content:		an array of items representing the menu content. Each item is an object
					that may have the properties:
						label:	the text to be displayed for the item
						href:	the url where to go when item is clicked
					exemple:
						new iMenu('elem-id',{content:[
							{label:'Item 1',href:'http://...'},
							{label:'Item 2',href:'http://...'}]})
	orient:			orientation for the menu. Value is one of:
						iMenu.HORIZ
						iMenu.VERT (default)
	cellClass:		html class for unselected menu cells (default iMenuCell)
	cellHClass:		html class for highlighted menu cells (default iMenuCellH)
	labelInStatus:  indicates whether or not the cell label should be displayed
					in the status bar when the mouse is over the cell (default false)
	hrefInStatus:  	indicates whether or not the cell link should be displayed
					in the status bar when the mouse is over the cell (default true)
	haveInterCell:	indicates whether or not an empty cell is inserted between each 
					item cell (default false)
	interCellClass:	html class for the intercell (default iInterCell)
	tableClass:     html class to be used for the table that holds the menu cells
	pixelUrl:	the url pointing to a 1x1 transparent image. This is required for interCells. (default 1pixel.gif)
*/

function iPopup(id,options) {
	if(id==null)
		return; // id is null when instantied as class prototype
	this.element=document.getElementById(id);
	if(this.element==null) {
		alert("Not found element id "+id);
		return;
	}
	var i;
	for(i=0;iPopup.popups["ipopup"+i]!=null;i++);
	iPopup.popups["ipopup"+i]=this;
	this.id="ipopup"+i;
	this.oldOnmouseover=this.element.onmouseover;
	this.oldOnmouseout=this.element.onmouseout;
	this.element.onmouseover=new Function("iPopup.popups['"+this.id+"'].onmouseover()");
	this.element.onmouseout=new Function("iPopup.popups['"+this.id+"'].onmouseout()");
	
	if(options==null)
		options={};
	
	this.options=options;
	
	if(options.anchorId==null)
		this.anchor=this.element;
		else {
			this.anchor=document.getElementById(options.anchorId);
			if(this.anchor==null) {
				alert("Not found element id "+options.anchorId);
				this.anchor=this.element;
			}
		}	
		if(options.elementCorner==null)
			options.elementCorner=iPopup.BOTTOMLEFT;
		if(options.popupCorner==null)
			options.popupCorner=iPopup.TOPLEFT;
		if(options.offsetX==null)
			options.offsetX=0;
		if(options.offsetY==null)
			options.offsetY=0;
		if(options.offsetKQx==null)
			options.offsetKQx=10;
		if(options.offsetKQy==null)
			options.offsetKQy=10;
		if(options.offsetMEx==null)
			options.offsetMEx=-1;
		if(options.offsetMEy==null)
			options.offsetMEy=-1;
		if(options.closeTimeout==null)
			options.closeTimeout=500;
		if(options.closeHandler!=null)
		  this.closeHandler = options.closeHandler;
		if(options.panelClass==null)
			options.panelClass="iPopupPanel";
		if(options.minLeftPos==null)
			options.minLeftPos=0;
		if(options.minTopPos==null)
			options.minTopPos=0;		
		if(options.borderTopLeftId!=null)
			this.borderTopLeft=document.getElementById(options.borderTopLeftId);
		if(options.borderTopLeftCorner==null)
			options.borderTopLeftCorner=iPopup.TOPLEFT;
		if(options.borderBottomRightId!=null)
			this.borderBottomRight=document.getElementById(options.borderBottomRightId);
		if(options.borderBottomRightCorner==null)
			options.borderBottomRightCorner=iPopup.BOTTOMRIGHT;
		
		this.visible=false;
		this.panel=this.makePanel();
		
		
}

/**
* Retains created popups
*/
iPopup.popups={};


iPopup.prototype={
	/**
	* Mouse is over the base element
	*/
	onmouseover: function(arg) {
		if(this.oldOnmouseover!=null) {
			this.element._fnt=this.oldOnmouseover;
			try {
				// on konqueror this may generate exception
				this.element._fnt(arg);
			} catch(e) {
			}
		}
		this.showPanel();
	},
	
	/**
	* Mouse exits base element
	*/
	onmouseout: function(arg) {
		this.startHidingPanel();
		if(this.oldOnmouseout!=null) {
			this.element._fnt=this.oldOnmouseout;
			try {
				// on konqueror this may generate exception
				this.element._fnt(arg);
			} catch(e) {
			}
		}
	},
	
	/**
	* Constructs popup panel
	*/
	makePanel: function() {
		var panel=document.createElement("div");
		panel.className=this.panelClass;
		panel.style.position="absolute";
		panel.style.visibility="hidden";
		panel.style.zIndex="10";
		if(this.options.width!=null)
			panel.style.width=this.options.width+"px";
		// insert new div at the begining, appendChild fails on IE if file
		// is not finished parsing
		document.body.insertBefore(panel,document.body.firstChild);
		panel.onmouseover=new Function("iPopup.popups['"+this.id+"'].onmouseover()");
		panel.onmouseout=new Function("iPopup.popups['"+this.id+"'].onmouseout()");
		return panel;
	},
	
	/**
	* Makes the panel not visible
	*/
	hidePanel: function() {
		this.panel.style.visibility="hidden";
		var oldVisible = this.visible;
		this.visible=false;
		if(this.closeTimeout!=null) {		  
		  if ( (oldVisible == true) && this.closeHandler)
		    this.closeHandler(this);
		  clearTimeout(this.closeTimeout);
		  this.closeTimeout=null;
		}
	},
	
	/**
	* Prepares popup panel to become invisible
	*/
	startHidingPanel: function() {
		if(this.closeTimeout!=null) {
			clearTimeout(this.closeTimeout);
			this.closeTimeout=null;
		}
		this.closeTimeout=window.setInterval("iPopup.popups['"+this.id+"'].hidePanel()",
		parseInt(this.options.closeTimeout));
	},
	
	/**
	* Makes the panel visible
	*/
	showPanel: function() {

		if(this.visible) {
			if(this.closeTimeout!=null) {
				clearTimeout(this.closeTimeout);
				this.closeTimeout=null;
			}
			return;
		}
		
		for(var i in iPopup.popups) {
		  var popup=iPopup.popups[i];
		  if(popup.shouldCloseOnOpening) {
		    popup.hidePanel();
		  }
		}
		
		if(this.panel.firstChild==null) {
			this.panel.style.width="100px";
			this.panel.style.height="200px";
			this.panel.style.backgroundColor="#E0E0E0";
			this.panel.innerHTML="Popup\n";
		}

		this.panel.style.visibility="visible";
		this.visible=true;
		
		var x=0;
		var y=0;
		if(this.options.elementCorner==iPopup.TOPLEFT) {
			x=0;
			y=0;
		} else if(this.options.elementCorner==iPopup.TOPRIGHT) {
			x=this.anchor.offsetWidth;
			y=0;
		} else if(this.options.elementCorner==iPopup.BOTTOMLEFT) {
			x=0;
			y=this.anchor.offsetHeight;
		} else if(this.options.elementCorner==iPopup.BOTTOMRIGHT) {
			x=this.anchor.offsetWidth;
			y=this.anchor.offsetHeight;
		}
		if(this.options.popupCorner==iPopup.TOPLEFT) {
			x+=0;
			y+=0;
		} else if(this.options.popupCorner==iPopup.TOPRIGHT) {
			x-=this.panel.offsetWidth;
			y+=0;
		} else if(this.options.popupCorner==iPopup.BOTTOMLEFT) {
			x+=0;
			y-=this.panel.offsetHeight;
		} else if(this.options.popupCorner==iPopup.BOTTOMRIGHT) {
			x-=this.panel.offsetWidth;
			y-=this.panel.offsetHeight;
		}

		var x0=this.getElementPosition(null).x+this.options.offsetX+x;

		if(this.borderTopLeft!=null) {
			var x1=this.getElementPosition(this.borderTopLeft).x;
			if(this.options.borderTopLeftCorner==iPopup.TOPRIGHT ||
				this.options.borderTopLeftCorner==iPopup.BOTTOMRIGHT)
				x1 += this.borderTopLeft.offsetWidth;
			if(x0<x1)
				x0=x1;
		}
		if(this.borderBottomRight!=null) {
			var x1=this.getElementPosition(this.borderBottomRight).x;
			if(this.options.borderBottomRightCorner==iPopup.TOPRIGHT ||
				this.options.borderBottomRightCorner==iPopup.BOTTOMRIGHT)
				x1 += this.borderBottomRight.offsetWidth;
			if(x0+this.panel.offsetWidth>x1)
				x0=x1-this.panel.offsetWidth;
		}
		if(x0<parseInt(this.options.minLeftPos))
			x0=this.options.minLeftPos;
		if(this.options.maxRightPos!=null &&
			(x0+this.panel.offsetWidth)>parseInt(this.options.maxRightPos))
		x0=this.options.maxRightPos-this.panel.offsetWidth;
		
		var y0=this.getElementPosition(null).y+this.options.offsetY+y;
		if(this.borderTopLeft!=null) {
			var y1=this.getElementPosition(this.borderTopLeft).y;
			if(this.options.borderTopLeftCorner==iPopup.BOTTOMLEFT ||
				this.options.borderTopLeftCorner==iPopup.BOTTOMRIGHT)
				y1 += this.borderTopLeft.offsetHeight;
			if(y0<y1)
				y0=y1;
		}
		if(this.borderBottomRight!=null) {
			var y1=this.getElementPosition(this.borderBottomRight).y;
			if(this.options.borderBottomRightCorner==iPopup.BOTTOMLEFT ||
				this.options.borderBottomRightCorner==iPopup.BOTTOMRIGHT)
				y1 += this.borderBottomRight.offsetHeight;
			if(y0+this.panel.offsetHeight>y1)
				y0=y1-this.panel.offsetHeight;
		}
		if(y0<parseInt(this.options.minTopPos))
			y0=this.options.minTopPos;
		if(this.options.maxBottomPos!=null &&
			(y0+this.panel.offsetHeight)>parseInt(this.options.maxBottomPos))
		y0=this.options.maxBottomPos-this.panel.offsetHeight;

        if(iPopup.appName=="ME") {
          this.panel.style.height="100px";
          this.panel.style.width="100px";
        }

		this.panel.style.left=x0+"px";
		this.panel.style.top=y0+"px";

	},
	
	/**
	* Returns the position of the anchor element.
	*/
	getElementPosition: function(anchor) {
		if(anchor==null)
			anchor=this.anchor;
		var pos={x:0, y:0};
		var node=anchor;
		for (; node; node = node.offsetParent) {
			if(iPopup.appName=="ME") {
			  if(node.clientLeft!=null)
				pos.x += parseInt(node.clientLeft);
			  else
				pos.x += parseInt(node.offsetLeft);
			  if(node.clientTop!=null)
				pos.y += parseInt(node.clientTop);
			  else
				pos.y += parseInt(node.offsetTop);
			} else {
				pos.x += parseInt(node.offsetLeft);
				pos.y += parseInt(node.offsetTop);
			}
		}
		if(iPopup.appName=="KQ") {
			pos.x+=parseInt(this.options.offsetKQx);
			pos.y+=parseInt(this.options.offsetKQy);
		}		
		if(iPopup.appName=="ME") {
			pos.x+=parseInt(this.options.offsetMEx);
			pos.y+=parseInt(this.options.offsetMEy);
		}
		return pos;
	}
	
}

/**
* Corner constants
*/
iPopup.TOPLEFT=1;
iPopup.TOPRIGHT=2;
iPopup.BOTTOMLEFT=3;
iPopup.BOTTOMRIGHT=4;

/**
* Retain navigator information
*/
iPopup.appName=navigator.appName;

if(iPopup.appName=="Microsoft Internet Explorer")
	iPopup.appName="IE";
if(iPopup.appName=="Netscape")
	iPopup.appName="NS";
if(iPopup.appName=="Konqueror")
	iPopup.appName="KQ";
if(iPopup.appName=="Opera")
	iPopup.appName="OP";
	try {
		eval("iPopup.appVersion=/^.*?(\\d+\\.?\\d*).*?$/.exec(navigator.appVersion)[1];");
	} catch(e) {
		// mac ie does not support .*? !!!
		eval("iPopup.appVersion=/(\\d+\\.?\\d*).*$/.exec(navigator.appVersion)[1]");
		if(navigator.appVersion.indexOf("Macintosh")!=-1) {
			iPopup.appName="ME";
		}
	}
	
	
	/**
	* Debug utility
	*/
	/*
	iPopup.alertObj=function(obj,text) {
		
		if(text==null)
			text="";
		else
			text+=":\n";
		var column=0;
		var testFnt=function(obj) {
			var res;
			try {
				eval("res=(obj instanceof Function);");
			} catch(e) {
				// mac ie does not support instanceof !!
				eval("res=(''+obj).indexOf('function(')==0;");
			}
			return res;
		}
		for(var i in obj) {
			if(testFnt(obj[i])==false &&
			i!="innerHTML") {
				text+=i+": "+obj[i];
				column++;
				if(column==3) {
					column=0;
					text+="\n";
				} else {
					text+=" - ";
				}
			}
		}
		alert(text);
	}
	*/
	
	/**
	* iMenu implements a popup menu
	*/
	function iMenu(id,options) {
		if(options.orient==null)
			options.orient=iMenu.VERT;
		if(options.content==null)
			options.content=[];
		if(options.tableClass==null)
			options.tableClass="iTableClass";
		if(options.cellClass==null)
			options.cellClass="iMenuCell";
		if(options.cellHClass==null)
			options.cellHClass="iMenuCellH";
		if(options.labelInStatus==null)
			options.labelInStatus=false;
		if(options.hrefInStatus==null)
			options.hrefInStatus=true;
		if(options.haveInterCell==null)
			options.haveInterCell=false;
		if(options.interCellClass==null)
			options.interCellClass="iInterCell";
		if(options.pixelUrl==null)
			options.pixelUrl="1pixel.gif";
		
		this.base=iPopup;
		this.base(id,options);
		
		this.shouldCloseOnOpening=true;
	}
	iMenu.prototype=new iPopup(null,null);
	
	/**
	* iMenu Constants
	*/
	iMenu.HORIZ=1;
	iMenu.VERT=2;

	/**
	 * Creates a panel containing the menu
	 */
	iMenu.prototype.makePanel=function() {

		this._makePanel=iPopup.prototype.makePanel;
		var panel=this._makePanel();
		var html="<table class='"+this.options.tableClass+"' cellspacing='0' cellpadding='0'>";
		var isVert=this.options.orient==iMenu.VERT;
		var isHoriz=this.options.orient==iMenu.HORIZ;
		if(isHoriz) 
			html+="<tr>";
	    for(var i=0;i<this.options.content.length;i++) {
			if(isVert)
					html+="<tr>";
				var item=this.options.content[i];
				var label=item.label;
				if(label==null)
					label="";
				html+="<td class='"+this.options.cellClass+"'"+
					" onmouseover=\"iPopup.popups['"+this.id+"'].cellOver(this,"+i+")\""+
					" onmouseout=\"iPopup.popups['"+this.id+"'].cellOut(this,"+i+")\"";
				if(item.href!=null)
					html+=" onclick=\"iPopup.popups['"+this.id+"'].cellClick(this,"+i+")\"";

				html+=" nowrap>";
				html+=label;
				html+="</td>";
				if(isVert)
					html+="</tr>";
				if(this.options.haveInterCell==true && i<this.options.content.length-1) {
					if(isVert)
						html+="<tr>";

					html += "<td class='"+this.options.interCellClass+"'><img src='"+this.options.pixelUrl+"'/></td>";

					if(isVert)
						html+="</tr>";
				}
			}
			if(isHoriz)
				html+="</tr>";
			html+="</table>";
			panel.innerHTML=html+"\n";
			return panel;
	}
	
	/**
	* The mouse entered a cell
	*/
	iMenu.prototype.cellOver=function(cell,index) {
		cell.className=this.options.cellHClass;
		this.oldStatus=top.status;
		top.status="";
		if(this.options.labelInStatus==true && this.options.content[index].label!=null)
			top.status+=this.options.content[index].label+" ";
		if(this.options.hrefInStatus==true && this.options.content[index].href!=null)
			top.status+=this.options.content[index].href+" ";
	}
	
	
	/**
	* The mouse exited a cell
	*/
	iMenu.prototype.cellOut=function(cell,index) {
		cell.className=this.options.cellClass;
		top.status=this.oldStatus;
	}
	
	
	/**
	* A cell has been clicked
	*/
	iMenu.prototype.cellClick=function(cell,index) {
		this.hidePanel();
		window.location=this.options.content[index].href;
	}
	
	
	
	

