/*********************************************************************************
*   Description: Client side of libPinkArrow Library, loads messages using libAjax and display in arrows
*   Who/When: Khalid Amin, 23 June 2006
**********************************************************************************/
/*
*   Description: libPinkArrow Class. this is constructor function
*   Who/When:Khalid Amin, 23 June 2006
*/
var _d;

var Browser = {
  Version: function() {
    var version = 999; // we assume a sane browser
    if (navigator.appVersion.indexOf("MSIE") != -1)
      // bah, IE again, lets downgrade version number
      version = parseFloat(navigator.appVersion.split("MSIE")[1]);
    return version;
  }
}

function libPinkArrow(){
	this.arrMessages = new Array();									// create new array to hold messages
	this.Elements = new Array();
//	this.ids = new Array();
	this.count;
	this.multipleArrows = false;
	this.fade = false;
	this.timer = 0;
} // end of function

/*
*   Description: this function set property to use fader
*   Who/When:Khalid Amin, 23 June 2006
*/
libPinkArrow.prototype.useFader = function(flag){
	this.fade = flag;
}// end of function

/*
*   Description: this function set property to use multiple arrows
*   Who/When:Khalid Amin, 23 June 2006
*/
libPinkArrow.prototype.useMultipleArrows = function(flag){
	_d.body.libPinkArrowObject = this; //save this pinkArrow object reference
	this.removeArrow();
	this.multipleArrows = flag;
}// end of function


/*
*   Description: this function initialize ajax object and make an ajax call to load messages
*   Who/When:Khalid Amin, 23 June 2006
*/
libPinkArrow.prototype.init = function(pageName){
	this.count = 0;
	this.ajax = new AjaxEngine();									// create ajax engine
	this.ajax.addCode('page',pageName)								// add page parameter
	this.ajax.addCode('action','page_messages')						// add action parameter
	this.ajax.loadXML('/PublicLibrary/libPinkArrow/libPinkArrow.php',this.init_cb,this);				// make ajax call

}// end of function

/*
*   Description: this function is call back function of init ajax call
*   Who/When:Khalid Amin, 23 June 2006
*/
libPinkArrow.prototype.init_cb = function(data, myself){
	myself.makeArray(data); // make array out of XML document
}// end of function

/*
*   Description: this function calculate position for pinkArrowLeft and call showArrow function
*   Who/When:Khalid Amin, 23 June 2006
*/
libPinkArrow.prototype.showLeft = function(field,messageID){
	if (typeof field == 'string') field = document.getElementById(field); // if string id is passed get Object

	x = this.getX(field);			// get x coordinate
	y = this.getY(field);			// get y coordinate
	w = this.getW(field);			// get width
	h = this.getH(field);			// get height

	y = y - 70 + h / 2;				// adjust y
	x = x + w -5 					// adjust x

	// call showArrow function
	this.showArrow(messageID,'Left',x,y,292,140,64,37,210,65);
	this.focusField(field); // set focus to this field
}// end of function

/*
*   Description: this function calculate position for pinkRight and call showArrow function
*   Who/When:Khalid Amin, 23 June 2006
*/
libPinkArrow.prototype.showRight = function(field,messageID){
	if (typeof field == 'string') field = document.getElementById(field); // if string id is passed get Object

	x = this.getX(field);			// get x coordinate
	y = this.getY(field);			// get y coordinate
	w = this.getW(field);			// get width
	h = this.getH(field);			// get height

	y = y - 70 + h / 2;				// adjust y
	x = x - 287						// adjust x

	// call showArrow function
	this.showArrow(messageID,'Right',x,y,292,140,17,37,210,65);
	this.focusField(field); // set focus to this field
}// end of function

/*
*   Description: this function calculate position for pinkTopRight and call showArrow function
*   Who/When:Khalid Amin, 23 June 2006
*/
libPinkArrow.prototype.showTopRight = function(field,messageID){
	if (typeof field == 'string') field = document.getElementById(field); // if string id is passed get Object

	x = this.getX(field);			// get x coordinate
	y = this.getY(field);			// get y coordinate
	w = this.getW(field);			// get width
	h = this.getH(field);			// get height

	y = y - 116 + 5;				// adjust y
	x = x + w / 2 - 277 + 26;		// adjust x

	// call showArrow function
	this.showArrow(messageID,'TopRight',x,y,277,116,13,3,210,65);
	this.focusField(field); // set focus to this field
}// end of function

/*
*   Description: this function calculate position for pinkTopLeft and call showArrow function
*   Who/When:Khalid Amin, 23 June 2006
*/
libPinkArrow.prototype.showTopLeft = function(field,messageID){
	if (typeof field == 'string') field = document.getElementById(field); // if string id is passed get Object

	x = this.getX(field);			// get x coordinate
	y = this.getY(field);			// get y coordinate
	w = this.getW(field);			// get width
	h = this.getH(field);			// get height

	y = y - 116 + 5;				// adjust y
	x = x + w / 2 - 26;				// adjust x

	// call showArrow function
	this.showArrow(messageID,'TopLeft',x,y,277,116,48,3,210,65);
	this.focusField(field); // set focus to this field
}// end of function

/*
*   Description: this function calculate position for pinkBottomRight and call showArrow function
*   Who/When:Khalid Amin, 23 June 2006
*/
libPinkArrow.prototype.showBottomRight = function(field,messageID){
	if (typeof field == 'string') field = document.getElementById(field); // if string id is passed get Object

	x = this.getX(field);			// get x coordinate
	y = this.getY(field);			// get y coordinate
	w = this.getW(field);			// get width
	h = this.getH(field);			// get height

	y = y + h - 5;					// adjust y
	x = x + w / 2 - 277 + 26;		// adjust x

	// call showArrow function
	this.showArrow(messageID,'BottomRight',x,y,277,116,13,46,210,65);
	this.focusField(field); // set focus to this field
}// end of function

/*
*   Description: this function calculate position for pinkBottomLeft and call showArrow function
*   Who/When:Khalid Amin, 23 June 2006
*/
libPinkArrow.prototype.showBottomLeft = function(field,messageID){
	if (typeof field == 'string') field = document.getElementById(field); // if string id is passed get Object

	x = this.getX(field);			// get x coordinate
	y = this.getY(field);			// get y coordinate
	w = this.getW(field);			// get width
	h = this.getH(field);			// get height

	y = y + h - 5;					// adjust y
	x = x + w / 2 - 26;				// adjust x

	// call showArrow function
	this.showArrow(messageID,'BottomLeft',x,y,277,116,48,46,210,65);
		this.focusField(field); // set focus to this field
}// end of function

/*
*   Description: this function create Divs and show Arrow messages in it
*   Who/When:Khalid Amin, 23 June 2006
*/
libPinkArrow.prototype.showArrow = function(messageID,type,x,y,w,h,l,t,msg_w,msg_h){

	if(!this.targetWin || this.targetWin == 'undefined') _d = document; //default shortcut to document
	else _d = this.targetWin.document; //shortcut if window specified
	// create arrow div
	ArrowDiv = _d.createElement('DIV');
	// Use Aplha transperency for png for IE 5.5
	ArrowDiv.style.position = 'absolute';				// set position
	ArrowDiv.style.left = x + 'px';						// set left
	ArrowDiv.style.top = y +'px';						// set top
	ArrowDiv.style.width = w + 'px';					// set width
	ArrowDiv.style.height = h + 'px';					// set height
	// set back ground url
	ArrowDiv.style.background = 'url("/PublicLibrary/libPinkArrow/images/PinkArrow'+type+'.gif") no-repeat';
	ArrowDiv.style.backGroundColor = 'transparent';		// set background color to transparent

	if (this.multipleArrows)
		ArrowDiv.id = "libPinkArrow"+this.count;						// set id
	else
		ArrowDiv.id = "libPinkArrow";									// set id

	ArrowDiv.style.zIndex= '100';



	ArrowMessageDiv = _d.createElement('DIV');	//create message div
	ArrowMessageDiv.style.position = 'absolute';		// set position
	ArrowMessageDiv.style.left = l + 'px';				// set left
	ArrowMessageDiv.style.top = t + 'px';				// set top
	ArrowMessageDiv.style.width = msg_w + 'px';			// set width
	ArrowMessageDiv.style.border = '0px red solid';			// set width
	ArrowMessageDiv.style.height = msg_h + 'px';		// set height

	ArrowMessageDiv.style.fontFamily = 'Arial';			// set font
	ArrowMessageDiv.style.fontSize = '11px';			// set font size
	ArrowMessageDiv.style.lineHeight = '110%';			// set line height
	ArrowMessageDiv.style.margin = '0px';				// set margin
	ArrowMessageDiv.style.padding = '0px';				// set padding
	ArrowMessageDiv.style.zIndex= '100';				// set padding

	if (!document.all) ArrowMessageDiv.style.display = 'table';				// set padding
	ArrowMessageDiv.style.verticalAlign = 'middle';				// set padding
	ArrowMessageDiv.innerHTML = '<div style="_position:absolute;display:table-cell;vertical-align:middle;border:0px blue solid;_top:50%">' // out div
									+'<div style="border:0px yellow solid;_position:relative;_top:-50%">' // inner div
										+this.arrMessages[messageID]+
									'</div>'+ // inner div
								'</div>'	// out div

	ArrowDiv.appendChild(ArrowMessageDiv);					// add to parent arrow div
	_d.body.libPinkArrowObject = this; //save this pinkArrow object reference

	if (this.multipleArrows)
		this.count=this.count+1;
	else
		this.removeArrow();

	// if there is a previous arrow
	//if (_d.getElementById("libPinkArrow") != null)
	//	_d.body.removeChild(_d.getElementById("libPinkArrow"));	// remove that arrow


	_d.body.appendChild(ArrowDiv)				    // add arrow div to document body

	var that = this;
	if (_d.all)
		_d.body.attachEvent("onclick", that.removeArrow,false); // add event
	else // else if FF
		_d.body.addEventListener("click", that.removeArrow,false); // add event
}// end of function

/*
*   Description: this function create associative array from XML document to make search easier
*   Who/When:Khalid Amin, 23 June 2006
*/
libPinkArrow.prototype.makeArray = function(data){
	var top_node = data.getXMLTopNode("data");			// get top node
	for (var i=0; i<top_node.childNodes.length; i++){        //for all childs
		if ((top_node.childNodes[i].nodeType==1)&&(top_node.childNodes[i].nodeName=="row")){        //check child type and name
			var row=top_node.childNodes[i];        //get row node
			this.arrMessages[row.childNodes[0].firstChild.data] = row.childNodes[1].firstChild.data // add to the messages div
		}	// if
	} // for
	if(!this.targetWin || this.targetWin == 'undefined') _d = document; //default shortcut to document
	else _d = this.targetWin.document; //shortcut if window specified
	// for all the controls where events should not propogate
	for (i=0;i<this.Elements.length;i++){
		// get object from id
		var obj = _d.getElementById(this.Elements[i]);
		if (obj == null) continue;
		// if IE
		if (document.all)
			obj.attachEvent("onclick", this.cancelBubble,false); // add event
		else // else if FF
			obj.addEventListener("click", this.cancelBubble,false); // add event
	} // for


}// end of function
/*
*   Description: this function cancel event bubbling
*   Who/When:Khalid Amin, 23 June 2006
*/
libPinkArrow.prototype.cancelBubble = function(e){
			if (!e) var e = window.event;					// to stop bubbling click event
			e.cancelBubble = true;							// for IE
			if (e.stopPropagation) e.stopPropagation();		// for FF
	}  // end of function

/*
*   Description: this function get Y position of the given Element
*   Who/When:Khalid Amin, 23 June 2006
*/
libPinkArrow.prototype.getY = function ( oElement ){
	var iReturnValue = 0;						// set initial value to 0
	while( oElement != null ) {					// while element is not null ( that we have not reached top most element )
		iReturnValue += oElement.offsetTop-oElement.scrollTop;		// get offset top
		oElement = oElement.offsetParent;		// move to parent object
	} // while
	if (document.all && Browser.Version() <= 8) iReturnValue = this.getPageYOffset() + iReturnValue;
	return iReturnValue;						// return the offsetTop
}// end of function

libPinkArrow.prototype.getPageYOffset = function(){
	var ns = (navigator.appName.indexOf("Netscape") != -1);
	if (ns)
	var pY = pageYOffset 
	else{
	if (document.documentElement && !document.documentElement.scrollTop)
		pY = 0;
	if (document.documentElement && document.documentElement.scrollTop)
		pY = document.documentElement.scrollTop;
	else if (document.body && document.body.scrollTop)
		pY = document.body.scrollTop;
	}
	return parseInt(pY);
}

/*
*   Description: this function get X position of the given Element
*   Who/When:Khalid Amin, 23 June 2006
*/
libPinkArrow.prototype.getX = function ( oElement ){
	var iReturnValue = 0;						// set initial value to 0
	while( oElement != null ) {					// while element is not null ( that we have not reached top most element )
		iReturnValue += oElement.offsetLeft;	// get offset left
		oElement = oElement.offsetParent;		// move to parent object
	} // while
	return iReturnValue;						// return the offsetTop
}// end of function

/*
*   Description: this function get width of the given Element
*   Who/When:Khalid Amin, 23 June 2006
*/
libPinkArrow.prototype.getW = function ( oElement ){
	return oElement.offsetWidth;	// return Width
}// end of function

/*
*   Description: this function get height of the given Element
*   Who/When:Khalid Amin, 23 June 2006
*/
libPinkArrow.prototype.getH = function ( oElement ){
	return oElement.offsetHeight;	// return height
}// end of function

/*
*   Description: this function is called recursively untill document body is loaded. once document body is loaded
*				 it calls pinkArrow init function
*   Who/When:Khalid Amin, 23 June 2006
*/
function pinkArrow_init(){
   // pinkArrow.init(pageName);   // initialize pink arrow
}// end of function


libPinkArrow.prototype.removeArrow = function (){
	removeFunction = (pinkArrow.fade) ? pinkArrow.fadeArrow : pinkArrow.removeArrows;
	if (!pinkArrow.multipleArrows)
		removeFunction("");
	else{
		for (i=0;i<pinkArrow.count;i++){
				removeFunction(i);
		}
		pinkArrow.count = 0;
	}
}// end of function


libPinkArrow.prototype.removeArrows = function (id){
	if(!document.all && _d.body.libPinkArrowObject != null && _d.body.libPinkArrowObject.targetWin) //if FF and has targetWin ->
		_d = _d.body.libPinkArrowObject.targetWin.document; //shortcut if window specified
	//for IE correct _d was saved in global when ShowArrow was called
	// if there is a previous arrow
	if (_d.getElementById("libPinkArrow"+id) != null){
		_d.body.removeChild(_d.getElementById("libPinkArrow"+id));	// remove that arrow*/
	}
}// end of function

libPinkArrow.prototype.fadeArrow = function (id){
	if(!document.all && _d.body.libPinkArrowObject.targetWin) //if FF and has targetWin ->
		_d = _d.body.libPinkArrowObject.targetWin.document; //shortcut if window specified
	//for IE correct _d was saved in global when ShowArrow was called
	// if there is a previous arrow
	if (_d.getElementById("libPinkArrow"+id) != null){
		new simpleFaderObject(_d.getElementById("libPinkArrow"+id),50,50,"1");
//		_d.body.removeChild(_d.getElementById("libPinkArrow"+id));	// remove that arrow*/
	}
}// end of function


/*
*   Description: This function is used to cancel event bubbling for controls,
*				  as we are hiding PinkArrow on body click, which we may not require for controls which show the arrow
*   Who/When:Khalid Amin, 29 June 2006
*/
libPinkArrow.prototype.CancelEventBubbling = function (Elements) { //v3.0
	this.Elements = Elements.split(",");
} // end of function

/*
*   Description: This funtion set focus to perticular field
*   Who/When:Khalid Amin, 29 June 2006
*/
libPinkArrow.prototype.focusField = function (field) { //v3.0

	try{
		field.focus();
	} catch(e){};
} // end of function

/*
*   Description: this function is image preloader
*				 it calls pinkArrow init function
*   Who/When:Khalid Amin, 23 June 2006
*/
function MM_preloadImages() { //v3.0
  var d=document; if(d.images){ if(!d.MM_p) d.MM_p=new Array();		// if there is a document object
    var i,j=d.MM_p.length,a=MM_preloadImages.arguments; for(i=0; i<a.length; i++)	// for each parameter
    if (a[i].indexOf("#")!=0){ d.MM_p[j]=new Image; d.MM_p[j++].src=a[i];}}	// load image
} // end of function


// create pink arrow object
window.pinkArrow = new libPinkArrow();
// initialize the pinkArrow object

if (window.addEventListener)									//set onload event
    window.addEventListener('load',pinkArrow_init,false);	//set onload event
else if (window.attachEvent)									//set onload event
    window.attachEvent('onload',pinkArrow_init);			//set onload event

/*
*   Description: This function is used to cancel event bubbling for controls,
*				  as we are hiding PinkArrow on body click, which we may not require for controls which show the arrow
*   Who/When:Khalid Amin, 29 June 2006
*/
function CancelEventBubbling(Elements) { //v3.0
	Elements = Elements.split(",");

	// for all the controls where events should not propogate
	for (i=0;i<Elements.length;i++){
		// get object from id
		var obj = 	document.getElementById(Elements[i]);
		if (obj == null) continue;
		// if IE
		if (document.all)
			obj.attachEvent("onclick", cancelBubbleFunc,false); // add event
		else // else if FF
			obj.addEventListener("click", cancelBubbleFunc,false); // add event
	} // for
} // end of function

/*
*   Description: this function cancel event bubbling
*   Who/When:Khalid Amin, 23 June 2006
*/
function cancelBubbleFunc(e){
			if (!e) var e = window.event;					// to stop bubbling click event
			e.cancelBubble = true;							// for IE
			if (e.stopPropagation) e.stopPropagation();		// for FF
	}  // end of function



//=====================

//fader object
//create css classes for FF
if (!document.all){
        document.write("<STYLE>");
                for (var i=0; i<=100; i++){        //100 classes for each opacity level
                        document.write(".div_transparent_"+i+"{ -moz-opacity: "+(i/100)+"; }");
                }
        document.write("</STYLE>");
        }

function simpleFaderObject(cobject,timeout,stages,state){
            if (typeof(cobject)=="string")                 //if object parametr is a string
                this.cobject=document.getElementById(cobject); //work with it as with object id
        else
                this.cobject=cobject;        //save object
                this.astate=state;
        this.startTrans="100";                //save end color value
        this.timeout=timeout||50;        //save timeout
        this.stages=stages||50;        //save stages count
        this.counter=-1;                        //set initial counter value
        cobject.fading=this;                //save pointer on object

        this.init(); //init object
        this.tick(); //start fading process
        return null; //return null pointer
}
        simpleFaderObject.prototype.init=function(){
                this.cobject.style.position="absolute";                                //IE fix
                this.sA=this.startTrans/this.stages;                // get transformation speed
        }

                        //timer call wrapper
        simpleFaderObject.prototype._delCall=function(node){
                //wrapper routine
                this.temp=function(){
                        node.tick(); //made neccesary changes
                }
                return this.temp;
        }
        simpleFaderObject.prototype.tick=function(){
                                this.cobject.className="div_transparent_"+Math.round(this.startTrans);        //set necessary css - FF
                                this.cobject.style["filter"]="alpha(opacity: "+Math.round(this.startTrans)+")";        //set opacity level - IE
                                this.startTrans=this.startTrans-this.sA;                //correct progress state
                this.counter++;                //increment stage counter
                if (this.counter==this.stages)        //if last stage
                        {
                        this.cobject.fading=null;        //destroy object
                        this.cobject.style.display="none";
						if(this.cobject.parentNode)
							this.cobject.parentNode.removeChild(this.cobject);
//                        this.cobject=null;                         //destroy link to DOM node
//                        jump_state(this.astate);
                        }
                else
                this.timer=window.setTimeout(new this._delCall(this),this.timeout); //delayed call
        }

function dropFader(node){
    if ((node.fading)&&(node.fading.timer)) window.clearTimeout(node.fading.timer);
    node.className="";
    node.style["filter"]="alpha(opacity: 100)";        //set opacity level - IE
    node.style.display="";
}

function jump_state(){

}

