﻿
if(typeof(PLOL) == "undefined") var PLOL = new Object();
if(typeof(PLOL.Utilities) == "undefined") PLOL.Utilities = new Object();
PLOL.Utilities.PopupManager = function(){
    return {
        Config:[],
        LaunchPopup:function(){
            newWin = window.open(this.href, this.target, this.settings);
            newWin.focus();
            return false;
        },
        Initialize:function(){
              if (!document.getElementsByTagName) return true;
              var pageLinks = document.getElementsByTagName("a");
            
              for (var i = 0; i < pageLinks.length; i++) 
              {
                if (((pageLinks[i].className != null) && 
	                 (pageLinks[i].className != "")) ||
	                ((pageLinks[i].parentNode.className != null) && 
	                 (pageLinks[i].parentNode.className != "")))
                {
                  var linkClass = " " + pageLinks[i].className + " ";
                  if ((linkClass == "  ") && (pageLinks[i].parentNode.className != ""))
                  {
	                linkClass = " " + pageLinks[i].parentNode.className + " ";
                  }
                  for (var theKey in PLOL.Utilities.PopupManager.Config) 
                  {
	                if (linkClass.indexOf(" " + theKey + " ") > -1)
	                {
	                  if ((pageLinks[i].target == "") || (pageLinks[i].target == null))
	                  {
		                pageLinks[i].target = (PLOL.Utilities.PopupManager.Config[theKey][0] != "") ? popupLinkConfig[theKey][0] : theKey;
	                  }
	                  pageLinks[i].settings = PLOL.Utilities.PopupManager.Config[theKey][1];
	                  pageLinks[i].onclick = PLOL.Utilities.PopupManager.LaunchPopup;
	                }
                  }
                }
              }
              return true;
        }
       
    }
}();

PLOL.Utilities.BalloonManager = function(){
    return {
        Config:{CssClass:null,BalloonElement:null},
        ClickHandler:function(e){
            var posx = 0;
	        var posy = 0;
	        if (!e) var e = window.event;
	        if (e.pageX || e.pageY) 	{
		        posx = e.pageX;
		        posy = e.pageY;
	        }
	        else if (e.clientX || e.clientY) 	{
		        posx = e.clientX + document.body.scrollLeft
			        + document.documentElement.scrollLeft;
		        posy = e.clientY + document.body.scrollTop
			        + document.documentElement.scrollTop;
	        }

	        PLOL.Utilities.BalloonManager.LaunchBalloon(posx,posy);
        },
        LaunchBalloon:function(x,y){
	        var balloonElement = document.getElementById(PLOL.Utilities.BalloonManager.Config.BalloonElement);
	        balloonElement.style.display = "block";
	        
	        
	        var rPosX  = x + balloonElement.parentNode.scrollLeft-(balloonElement.offsetWidth)+25;
	       
	        if((rPosX + balloonElement.offsetWidth)>(balloonElement.parentNode.offsetWidth-20)){
	            rPosX = balloonElement.parentNode.offsetWidth - balloonElement.offsetWidth - 20;
	        }
	        if(rPosX < 0){
	            rPosX = 2;
	        }
	        var rPosY = y + balloonElement.parentNode.scrollTop-(balloonElement.offsetHeight*1.5)-60;
	        balloonElement.style.left = rPosX+"px";
	        balloonElement.style.top = rPosY+"px";
	       
	        // posx and posy contain the mouse position relative to the document
	        // Do something with this information
            return false;
        },
        Initialize:function(){
              if (!document.getElementsByTagName) return true;
              var pageLinks = document.getElementsByTagName("a");
              for (var i = 0; i < pageLinks.length; i++) 
              {
                if (((pageLinks[i].className != null) && 
	                 (pageLinks[i].className != "")) ||
	                ((pageLinks[i].parentNode.className != null) && 
	                 (pageLinks[i].parentNode.className != "")))
                {
                  var linkClass = " " + pageLinks[i].className + " ";
                  if ((linkClass == "  ") && (pageLinks[i].parentNode.className != ""))
                  {
	                linkClass = " " + pageLinks[i].parentNode.className + " ";
                  }
                  
                    var theKey = PLOL.Utilities.BalloonManager.Config.CssClass;
	                if (linkClass.indexOf(" " + theKey + " ") > -1)
	                {
	                    PLOL.Utilities.Events.addEvent(pageLinks[i],'click',PLOL.Utilities.BalloonManager.ClickHandler);
	                }
                  
                }
              }
              return true;
        }
       
    }
}();

PLOL.Utilities.Events = function(){
		
		return{
			
			
			/**
			  * Crossbrowser event handling functions.
			  *
			  * A set of functions to easily attach and detach event handlers to HTML elements.
			  * These functions work around the shortcomings of the traditional method ( element.onevent = function; )
			  * where only 1 handler could be attached for a certain event on the object, and mimic the DOM level 2
			  * event methods addEventListener and removeEventListener for browsers that do not support these
			  * methods (e.g. Internet Explorer) without resorting to propriety methods such as attachEvent and detachEvent
			  * that have a whole set of their own shortcomings.
			  * Created as an entry for the 'contest' at quirksmode.org: http://www.quirksmode.org/blog/archives/2005/09/addevent_recodi.html
			  *
			  * @author Tino Zijdel ( crisp@xs4all.nl )
			  * @version 1.2
			  * @date 2005-10-21
			  */
			
			
			/**
			  * addEvent
			  *
			  * Generic function to attach event listeners to HTML elements.
			  * This function does NOT use attachEvent but creates an own stack of function references
			  * in the DOM space of the element. This prevents closures and therefor possible memory leaks.
			  * Also because of the way the function references are stored they will get executed in the
			  * same order as they where attached - matching the behavior of addEventListener.
			  *
			  * @param obj The object to which the event should be attached.
			  * @param evType The eventtype, eg. 'click', 'mousemove' etcetera.
			  * @param fn The function to be executed when the event fires.
			  * @param useCapture (optional) Whether to use event capturing, or event bubbling (default).
			  */
	  
			addEvent: function(obj, evType, fn, useCapture){  
				
				//-- Default to event bubbling
				if (!useCapture) useCapture = false;
			
				//-- DOM level 2 method
				if (obj.addEventListener)
				{   
					obj.addEventListener(evType, fn, useCapture);
				}
				else
				{
					//-- event capturing not supported
					if (useCapture)
					{
						//alert('This browser does not support event capturing!');
					}
					else
					{
						var evTypeRef = '__' + evType;
			
						//-- create function stack in the DOM space of the element; seperate stacks for each event type
						if (obj[evTypeRef])
						{
							//-- check if handler is not already attached, don't attach the same function twice to match behavior of addEventListener
							if (this.array_search(fn, obj[evTypeRef]) > -1) return;
						}
						else
						{
							//-- create the stack if it doesn't exist yet
							obj[evTypeRef] = [];
			
							//-- if there is an inline event defined store it in the stack
							if (obj['on'+evType]) obj[evTypeRef][0] = obj['on'+evType];
							//-- attach helper function using the DOM level 0 method
							obj['on'+evType] = this.IEEventHandler;
					
						}
			
						//-- add reference to the function to the stack
						obj[evTypeRef][obj[evTypeRef].length] = fn;
					}
				}
			},
			
			/**
			  * removeEvent
			  *
			  * Generic function to remove previously attached event listeners.
			  *
			  * @param obj The object to which the event listener was attached.
			  * @param evType The eventtype, eg. 'click', 'mousemove' etcetera.
			  * @param fn The listener function.
			  * @param useCapture (optional) Whether event capturing, or event bubbling (default) was used.
			  */
			removeEvent: function(obj, evType, fn, useCapture){
				//-- Default to event bubbling
				if (!useCapture) useCapture = false;
			
				//-- DOM level 2 method
				if (obj.removeEventListener)
				{
					obj.removeEventListener(evType, fn, useCapture);
				}
				else
				{
					var evTypeRef = '__' + evType;
			
					//-- Check if there is a stack of function references for this event type on the object
					if (obj[evTypeRef])
					{
						//-- check if function is present in the stack
						var i = this.array_search(fn, obj[evTypeRef]);
						if (i > -1)
						{
							try
							{
								delete obj[evTypeRef][i];
							}
							catch(e)
							{
								obj[evTypeRef][i] = null;
							}
						}
					}
				}
			},
			
			/**
			  * IEEventHandler
			  * 
			  * IE helper function to execute the attached handlers for events.
			  * Because of the way this helperfunction is attached to the object (using the DOM level 0 method)
			  * the 'this' keyword will correctely point to the element that the handler was defined on.
			  *
			  * @param e (optional) Event object, defaults to window.event object when not passed as argument (IE).
			  */
			IEEventHandler: function(e){
			
				e = e || window.event;
				var evTypeRef = '__' + e.type, retValue = true;
				
				//-- iterate through the stack and execute each function in the scope of the object by using function.call
				for (var i = 0, j = this[evTypeRef].length; i < j; i++)
				{
					if (this[evTypeRef][i])
					{
						if (Function.call)
						{
							retValue = this[evTypeRef][i].call(this, e) && retValue;
						}
						else
						{
							//-- IE 5.0 doesn't support call or apply, so use this
							this.__fn = this[evTypeRef][i];
							retValue = this.__fn(e) && retValue;
						}
					}
				}
			
				if (this.__fn) try { delete this.__fn; } catch(e) { this.__fn = null; }
			
				return retValue;
			},
			
			/**
			  * array_search
			  * 
			  * Searches the array for a given value and returns the (highest) corresponding key if successful, -1 if not found.
			  *
			  * @param val The value to search for.
			  * @param arr The array to search in.
			  */
			array_search: function(val, arr){
				var i = arr.length;
			
				while (i--)
					if (arr[i] && arr[i] === val) break;
			
				return i;
			}
	  }
}();

PLOL.Utilities.DOM = function(){
        return {
        getViewportHeight: function() {
            var height = self.innerHeight; // Safari, Opera
            var mode = document.compatMode;
        
            if ( (mode || PLOL.UserAgent.isIE) && !PLOL.UserAgent.isOpera ) { // IE, Gecko
                height = (mode == 'CSS1Compat') ?
                        document.documentElement.clientHeight : // Standards
                        document.body.clientHeight; // Quirks
            }
        
            return height;
        },
        
        /**
         * Returns the current width of the viewport.
         * @method getViewportWidth
         * @return {Int} The width of the viewable area of the page (excludes scrollbars).
         */
        
        getViewportWidth: function() {
            var width = self.innerWidth;  // Safari
            var mode = document.compatMode;
            
            if (mode || PLOL.UserAgent.isIE) { // IE, Gecko, Opera
                width = (mode == 'CSS1Compat') ?
                        document.documentElement.clientWidth : // Standards
                        document.body.clientWidth; // Quirks
            }
            return width;
        }
        }
}();

PLOL.Utilities.Events.addEvent(window,'load',PLOL.Utilities.PopupManager.Initialize);
PLOL.Utilities.Events.addEvent(window,'load',PLOL.Utilities.BalloonManager.Initialize);