function isIE() {
	var browser= navigator.appName
	if (browser == "Microsoft Internet Explorer") {
		return true;
	} else {
		return false;
	}
}

function PopupClass() {  

	// Initilization function; Needs to be called by the HTML page
	this.init = function() { 
		this.draggingEnabled = true;
		this.ajaxReq = null;
		this.boxObj = null; 
		this.contentObj = null;
		this.hideDelay = 3000;
		this.showDelay = 0;
		this.showPopupTimer = null;
		this.hidePopupTimer = null;
		this.offX = 16;
		this.offY = 8;
		this.isIE = isIE();
		this.rootDirectory = "popupimages";
		this.errorMsg = "There was a problem retrieving data from the Url specified";
		this.mouseCoord = null;
		this.bgImg = "NW";
		this.indentClass = "leftmargin"
		this.xPos = "0";
		this.yPos = "0";
	}
 
	this.run = function() {
		if (this.draggingEnabled)
			this.addInitDragListener(document, "mousemove");
	}
 
	// This is the main function which is called from HTML page which displays Popup
 	this.showPopup = function(pObj, pEvent, pIsDIV, pDIVorURL, pFormatFunc, pTitle, pErrorMsg) {
	    var oSelf = this;    
    	this.mouseCoord = this.getMouseCoordinates(pEvent);
    	this.showPopupTimer = setTimeout( function() { oSelf.showPopupCallback(pObj, pIsDIV, pDIVorURL, pFormatFunc, pTitle, pErrorMsg) }, this.showDelay);
	}
 
	this.showPopupCallback = function(pObj, pIsDIV, pDIVorURL, pFormatFunc, pTitle, pErrorMsg) {
	    this.showPopupTimer = null; // cancel the timer
    
    	if(pErrorMsg)
        	this.errorMsg = pErrorMsg; 

	    if (! this.contentObj) {
	        this.createPopup(pTitle);
        } else {
	        this.hidePopupImmediately();	
	        this.createPopup(pTitle);
	    }
    
		if (! pIsDIV) {
			this.getAjaxResult(pDIVorURL, pFormatFunc);    
		} else {
			this.getDivResult(pDIVorURL);
		}
	}
 

/*================== Functions related to DRAG AND MOVE ======================*/
 
	this.drag = function() {
		if (! this.boxObj)
			return;
	  
		var eventObj = (window.event) ? window.event : e; //what?
    
		if (this.boxObj.dragging)
			this.move(eventObj.screenX - this.boxObj.dragX, eventObj.screenY - this.boxObj.dragY);
	}

	this.beginDrag = function() {  
		var eventObj = (window.event) ? window.event : e; //what?
		
		this.boxObj.dragX = eventObj.screenX - this.boxObj.offsetLeft;
		this.boxObj.dragY = eventObj.screenY - this.boxObj.offsetTop;
		this.boxObj.dragging = true;
	}

	this.endDrag = function() {
		this.boxObj.dragging = false;
	}
 
	this.move = function(pLeft, pTop) {
		this.clearTimer();
		this.boxObj.style.left = pLeft + "px";
		this.boxObj.style.top = pTop + "px";
	}

/*--- End of DRAG AND MOVE functions --*/

/*================ ADDLISTENER functions ================*/

	this.addInitDragListener = function(pObj, pEventType) {
		var oSelf = this;
		if (window.addEventListener) {
		    pObj.addEventListener(
		    	pEventType,
		    	fooMove = function (e) {
		        	window.event = e;
		            return oSelf.drag();
				},
				false);
		} else {
			pObj.attachEvent(
				"on" + pEventType, 
				fooMove = function(e) {
					oSelf.drag();
				});
		}
	}
 
	this.addBeginEndDragListenters = function(pObj) {
		var oSelf = this;
		if (window.addEventListener) {
		    pObj.addEventListener(
		    	"mousedown", 
		    	fooBeginDrag =  function (e) { window.event = e; return oSelf.beginDrag(); }, 
		    	false);
		    pObj.addEventListener(
		    	"mouseup", 
		    	fooEndDrag = function(e) { oSelf.endDrag() }, 
		    	false);
		} else {
		    pObj.attachEvent(
		    	"onmousedown", 
		    	fooBeginDrag = function(e) { oSelf.beginDrag(); });
		    pObj.attachEvent(
		    	"onmouseup", 
		    	fooEndDrag = function(e) { oSelf.endDrag() });	
		}
	}
	
/* -- End of ADDLISTENER functions -- */
 
/*================ Popup CREATE AND HIDE functions ================*/

	this.createPopup = function(pTitle) {
		var oSelf = this;
		
		if (this.hidePopupTimer) { 
			clearTimeout(this.hidePopupTimer);	
			this.hidePopupTimer = 0; 
		}
		
		this.boxObj = document.createElement("div");
		this.boxObj.srcBox = this;
		this.boxObj.className = "popupbox";
		this.boxObj.style.background = "url(" + this.rootDirectory + "/bgNW.gif)";
		this.boxObj.innerHTML = "<div class='popupcontent'><img class='close' src='" + this.rootDirectory + "/close.gif' alt='Close' />" + pTitle + "</div>"; 
		
		this.boxObj.childNodes[0].childNodes[0].onclick = function(e) { oSelf.killPopup(e); }  // This will need to be changed if the box's element structure is changed.
		this.boxObj.onselectstart = new Function("return false");
		
		this.addBeginEndDragListenters(oSelf.boxObj.childNodes[0]);
		this.boxObj.move = this.move;
		this.boxObj.dragX = 0;
		this.boxObj.dragY = 0;
		this.boxObj.dragging = false;
		
		// create results container
		var resultsObj = document.createElement("div");
		resultsObj.className = "popupcontentouter";
		
		// Create a permanent link to the content Object so results can be directly added
		this.contentObj = document.createElement("div");
		this.contentObj.className = "popupcontentinner";
		this.contentObj.srcObj = this;
		
		// fuse contents to the results Object
		resultsObj.appendChild(this.contentObj);
		
		// fuse resultsObj with containing object
		this.boxObj.appendChild(resultsObj);
		
		// Add created object to the page
		document.body.appendChild(this.boxObj);
	}
 
	this.killPopup = function(e) {
		var obj = (this.isIE) ? window.event.srcElement : window.event.target;  
		 
		while (obj && obj.className != "popupbox") {
			obj = obj.parentNode;
		}
		if (obj) {
		    obj.srcBox.hidePopupImmediately(); 
	    }
	}

	this.hidePopupImmediately = function() {
		try {
			document.body.removeChild (this.boxObj); 
		} catch(err) {}
		
		this.boxObj = null;
		this.contentObj = null;  
	}

	this.hidePopup = function() {    
	    if(this.showPopupTimer) {
	        clearTimeout(this.showPopupTimer);
	        this.showPopupTimer = null;
	    } else {
/*
	        var oSelf = this;       
	        this.hidePopupTimer = setTimeout( 
	        	function () { oSelf.hidePopupImmediately() }, 
	        	this.hideDelay);     
*/
	    }
	}

	this.clearTimer = function() {
    	if (this.hidePopupTimer) {
	    	clearTimeout(this.hidePopupTimer);
	    	this.hidePopupTimer = 0; 
	    }
	}
 
/* -- End of Popup CREATE AND DESTROY functions -- */


/*======= Find and Adjust Popup postion according to mouse position and screen size functions ========*/

	this.adjustPopupPosition = function() {    
		this.findPopupPosition();
		this.boxObj.style.left = this.xPos + "px";
		this.boxObj.style.top = this.yPos + "px";     
		this.boxObj.style.backgroundImage = "url(" + this.rootDirectory + "/bg" + this.bgImg + ".gif)";
		this.boxObj.childNodes[0].className = "popuptitlebar popuptitle" + this.indentClass;
		this.boxObj.childNodes[1].childNodes[0].className = "popupcontentinner popupcontent" + this.indentClass;
	}
 
	
	this.findPopupPosition = function() {
		var offX, OffY;
		
		offX = this.mouseCoord.x;
		offY = this.mouseCoord.y;
		
		var newBg = "NW"; 	 
		
		if (offX + this.boxObj.offsetWidth + this.offX > Position.viewportW() + Position.scrollLeft()) {
		    offX = offX - this.boxObj.offsetWidth - this.offX;
		    newBg="NE";
		    indent="rightmargin";
		
		    if (offX < 0)
		        offX = 0;
		} else {
		    offX = offX + this.offX;
		    newBg="NW";
		    indent="leftmargin";
		}
		
		if (offY + this.boxObj.offsetHeight + this.offY > Position.viewportH() + Position.scrollTop()) {
		    offY = offY - this.boxObj.offsetHeight - this.offY + 5;
		    newBg=newBg.replace("N","S");
		
		    if (offY < Position.scrollTop())
		        offY = Position.viewportH() + Position.scrollTop() - this.boxObj.offsetHeight + 20;
		} else {
			offY = offY + this.offY - 2;
		}
		
		this.bgImg = newBg;
		this.indentClass = indent;
		this.xPos = offX;
		this.yPos = offY;
	}

/* -- End of Adjust Popup position function -- */
 
/*======= Get data from the DIV tag ==========*/
	this.getDivResult = function(pDivId) {
		if(! this.isIE)
			this.adjustPopupPosition();
		else
			this.findPopupPosition();	
	
		var divContent = getObject(pDivId).innerHTML;
		var oSelf = this;
		this.contentObj.innerHTML = '<div style="padding:5px 8px">' + divContent + '</div>';

		if (! this.boxObj)
			return; 

		this.adjustPopupPosition();
	}

 /*================ Ajax related functions to get and display data ================*/
 
	this.getAjaxResult = function(pURL, pFormatFunc) {
		// branch for native XMLHttp AjaxRequest object
		var oSelf = this;
		this.contentObj.innerHTML = '<div style="padding:5px 8px" align="center"><img src="' + this.rootDirectory + '/ajax-loader.gif" vspace="20" alt="Loading..." style="border:none !important;" /></div>';
	
		if(! this.isIE)
			this.adjustPopupPosition();
		else
			this.findPopupPosition();  

		if(pURL != null) {
			this.ajaxReq = GetXmlHttpObject(function() { oSelf.displayAjaxResult(oSelf.contentObj, pFormatFunc, oSelf); });
	     	this.ajaxReq.open("GET", pURL, true);
			this.ajaxReq.send(null);
		} else {
			oSelf.contentObj.innerHTML = 'No data returned';
		}

		if (! this.boxObj)
			return; 
		
		this.adjustPopupPosition();
	}


	this.displayAjaxResult = function(pObj, pFormatFunc, pScope) {
		var oSelf = pScope;
		if (pObj != null && (oSelf.ajaxReq.readyState == 4 || oSelf.ajaxReq.readState == "complete")) {
			// only if "OK"
			if (oSelf.ajaxReq.status == 200) {
				if(pFormatFunc != null)
					pObj.innerHTML = pFormatFunc(oSelf.ajaxReq.responseText);
				else
					pObj.innerHTML = oSelf.ajaxReq.responseText;
			} else {            
				pObj.innerHTML = '<img src="' + this.rootDirectory + '/alert.gif"  border="0" alt="" />' + oSelf.errorMsg;    
			}
		}
	}
 
/* -- End of Ajax related functions -- */
 
/*======== HELPER Functions ============*/
 
	// Returns an object with two properties .x and .y
	this.getMouseCoordinates = function(pEvent) {
	    return { x:Position.mouseX(pEvent), y:Position.mouseY(pEvent) };
	}

	var Position = 
		{
    		viewportW:function() {
	    		return this.getVPVal("clientWidth") || this.getVPVal("offsetWidth");
	    	},
    		viewportH:function() {
	    		return self.innerHeight || this.getVPVal("clientHeight") || this.getVPVal("offsetHeight"); 
	    	},
    		scrollLeft:function() {
	    		return self.pageXOffset || this.getVPVal("scrollLeft"); 
	    	},
    		scrollTop:function() {
	    		return self.pageYOffset || this.getVPVal("scrollTop"); 
	    	},
    		pageH:function() { 
	    		return document.body.scrollHeight; 
	    	},
    		pageW:function() {
	    		return document.body.scrollWidth; 
	    	},
    		mouseX:function(e) {
	    		e = e || window.event; 
	    		return e.pageX || e.clientX + Position.scrollLeft(); 
	    	},
			mouseY:function(e) { 
				e = e || window.event; 
				return e.pageY || e.clientY + Position.scrollTop(); 
			},
    		getVPVal:function(key) {
	    		var de = document.documentElement;
        		var db = document.body;
        		if(de && de[key])
            		return de[key];
        		else 
        		if(db && db[key])
            		return db[key];
        
            	return 0;
			}
		};
 
/* -- End of HELPER functions -- */
}
