/**
 * Tooltip made the plain old Javascript way without jQuery and similar overhead stuff.
 * Based on the 'jTip' script made by Cody Lindley (http://www.codylindley.com).
 *
 * @package Holotip
 * @author Misa Brezanac <brezanac@gmail.com>
 * @license GNU General Public License 
 * (In other words you can do whatever you like with this code, while holding up to the rules defined by the 
 * GNU General Public License, except drag me to the court cause it did something you did not expect it to do ;) )
*/

/**
 * IMPORTANT: The following variable must be set in order for the script to work properly. It points to the DOCROOT
 * location of the server on which the script is executed.
*/
var SITE_URL = 'http://www.virtus-international.com/';

/**
 * Text to show during the holotip AJAX loading phase
*/
var LOADING_TEXT = "LOADING...";

/**
 * Message to be displayed if browser has no AJAX capabilities
*/
var AJAX_FAILURE_MESSAGE = "It seems that your browser has no AJAX capabilities.\nPlease consider upgrading to at least 21st century browser!";

/**
 * Time interval to delay AJAX requests in milliseconds. Prevents server overload.
*/
var AJAX_DELAY_INTERVAL = 1000;

/**
 * A simple id selector fetcher.
 *
 * @param string id The name of the selector to be 'fetched'
 * @return object A reference to the requested object if it exists. Otherwise you get a nice 'null' object.
*/
function $get($id){
    return document.getElementById($id);
}

/**
 * Instantiates an AJAX functionality support object (cross browser compatible ofcourse...).
 * 
 * NOTICE: This script is part of W3Schools (www.w3schools.com) project material but it was so good 
 * that I had to put it in my dandy JS collection :)
 *
 * @return object xmlHttpObj Instance of an  AJAX xmlHttp object (ActiveX for IE, and pure xmlHttp for the rest).
*/
function createRequestObject() {
    try{
        // Firefox, Opera 8.0+ or Safari
        xmlHttpObj=new XMLHttpRequest();
    } catch (e){
        // Internet Explorer
        try{
            xmlHttpObj=new ActiveXObject("Msxml2.XMLHTTP");
        }       
        catch (e){
            try{
                xmlHttpObj=new ActiveXObject("Microsoft.XMLHTTP");
            }         
            catch (e){
                alert(AJAX_FAILURE_MESSAGE);
                return false;
            }         
        }
    }
    return xmlHttpObj;
}

/**
* Executes the actual AJAX request after which the required fields are populated with some nice data. 
* 
* The returning data is in XML format and although the response will always have exactly one element (one person) this
* function is capable of populating any number of div containers with 'content' intended for the container named 'title'.
* 
* @param string method Which method is to be used for the request (GET, POST).
* @param string url The URL which will be responsible for handling the AJAX request and sending back the XML data
*/
function makeAJAXRequest(method, url){
    var xmlHttp;
    
    if(xmlHttp = createRequestObject()){
        xmlHttp.onreadystatechange=function(){
            if(xmlHttp.readyState == 4){
                if(xmlHttp.status == 200){
                    var xmlDoc = xmlHttp.responseXML;
                    var pageElements = xmlDoc.getElementsByTagName("container"); 
                    /*
                     * For every element of the XML response we make the appropriate content assignment into DOM elements. 
                    */
                    for(var x=0; x < pageElements.length; x++){
                        var title = pageElements[x].childNodes[0].firstChild.nodeValue;
                        var content = pageElements[x].childNodes[1].firstChild.nodeValue; 
                        document.getElementById(title).innerHTML = content;
                    }
                }
            }    
        }
    
        /*
         * Making the actual request
        */
        xmlHttp.open(method,url,true);
        xmlHttp.send(null);  
    }
}

/**
 * Calculates the absolute left position of the sent object (in this case a link) by recursively reading the value
 * of all the parent elements to the object until the Document Element is reached. This is actually one of the rare
 * techniques that does not require Internet Explorer hacking.
 *
 * @param object linkId The object for which the absolute left position is to be calculated.
 * @return The requested absolute left position.
*/
function calculateAbsoluteLeft(linkId) {
    /*
     * Fetching the currently active link object
    */
    linkObject = $get(linkId);
    /*
     * Reading the left offset value of the current DOM element toward its parent node (object)
    */
    absoluteLeft = linkObject.offsetLeft;
    /*
     * Until the Document Element is reached during a recursive left offset addition of all 
     * the elements on the way up is performed.
    */
    while(linkObject.offsetParent != null) { //Is there a parent node to the current element in the DOM structure?
        /*
         * If there is we assign the parent object to a variable...
        */
        linkObjectParent = linkObject.offsetParent;
        /*
         * Adding the offset value od the current element towards its parent node...
        */
        absoluteLeft += linkObjectParent.offsetLeft;
        /*
         * Making the parent node current...
        */
        linkObject = linkObjectParent;
    }
    /*
     * Returning the sum of all leftOffsets which is actually the absolute position of the linkId...
    */
    return absoluteLeft;
}

/**
 * Calculates the absolute top position of the sent object (in this case a link) by recursively reading the value
 * of all the parent elements to the object until the Document Element is reached. This is actually one of the rare
 * techniques that does not require Internet Explorer hacking.
 *
 * @param object linkId The object for which the absolute top position is to be calculated.
 * @return The requested absolute top position.
*/
function calculateAbsoluteTop(linkId) {
    /*
     * Fetching the currently active link object
    */
    linkObject = $get(linkId);
    /*
     * Reading the top offset value of the current DOM element toward its parent node (object)
    */
    absoluteTop = linkObject.offsetTop;
    /*
     * Until the Document Element is reached during a recursive top offset addition of all 
     * the elements on the way up is performed.
    */
    while(linkObject.offsetParent != null) { //Is there a parent node to the current element in the DOM structure?
        /*
         * If there is we assign the parent object to a variable...
        */
        linkObjectParent = linkObject.offsetParent;
        /*
         * Adding the offset value od the current element towards its parent node...
        */
        absoluteTop += linkObjectParent.offsetTop;
        /*
         * Making the parent node current...
        */
        linkObject = linkObjectParent;
    }
    /*
     * Returning the sum of all leftOffsets which is actually the absolute position of the linkId...
    */
    return absoluteTop;
}

/**
 * The following function handles the 'holotip' container behaviour.
 *
 * @param integer playerId The player id which will be used to make an AJAX request and which is by the way smuggled 
 * along with the 'rel' attribute.
 * @param string linkId Id selector of the currently active link
 * @param bool state "To show or to hide question is the now..."
*/
function showHoloTip(clientId, linkId, state){
	if(state == true){
		/*
         * First we need to calculate a couple of things before we actually show the container. 
        */
        var linkHeight = parseInt($get(linkId).offsetHeight); //height of the sent link object
        var linkWidth = parseInt($get(linkId).offsetWidth); //width of the sent link object
        var holoTipHeaderHeight = parseInt($get("holotipHeader").style.height); //holotip's header container height
        
        /*
         * in the following two lines the absolute positions of the holotip container are determined
        */
        $get("holotip").style.top =  (calculateAbsoluteTop(linkId) - Math.round((holoTipHeaderHeight - linkHeight) / 2)).toString() + "px"; 
        $get("holotip").style.left = (calculateAbsoluteLeft(linkId) + (linkWidth + 5)).toString() + "px";
        
        /*
		 * Time to show... We unhide the holotip right at the beginning to show the loading animation during the AJAX request.
		*/
        $get("holotip").style.display = "block";
		$get("holotipHeader").innerHTML = LOADING_TEXT; //How about an appropriate header title for the holotip?
		/*
         * This is where the actual animation is loaded and parsed into the document dynamically.
        */
        $get("holotipMainContent").innerHTML = '<div class="margo10"><img src="' + SITE_URL + 'images/loader.gif" alt="loader" width="62" height="13" /></div>';
        /*
         * NOTICE: To avoid problems with calling this function from various folder depths on a site 
         * the following URL MUST BE ABSOLUTE!!! Consult the SITE_URL variable at the beginning of this script.
         * Additionaly care has been taken to prevent possible server request overloads by simply hovering over
         * all of the links repeatedtlly.
        */
        /*
         * Since we are inside a function in order to read the value of the variable it needs to be declared as 
         * a property of the window object. Otherwise a 'Object undefined' would pay us a visit.
        */
        if(window.ajaxCallTimeout != null){
            /*
             * Declaring a variable as window object property since functions in Javascript are context sensitive.
            */
            window.clearTimeout(ajaxCallTimeout);
        }
        /*
         * Since we declared ajaxCallTimeout to be a first class citizen of the window object we now can access
         * it simply by addressing its name.  
        */
        ajaxCallTimeout = window.setTimeout('makeAJAXRequest("GET", ' + '"' + SITE_URL + 'fetchTip.php?id=' + clientId + '")', AJAX_DELAY_INTERVAL);
	} else {
		/*
		 * Time to hide... Just hiding the holotip container.
		*/
		$get("holotip").style.display = "none";
	}
}

/**
 * The following function will simply search the complete page for links and attach the two event handlers
 * to every link that is of class 'holotip'. That way only relevant links will receive additional behavioral
 * event handlers.
*/
function initHoloTip(){
	for(count = 0; count < document.links.length; count++){
		if(document.links[count].className == "HoloTip"){
			document.links[count].onmouseover = function(){showHoloTip(this.rel, this.id, true)};
			document.links[count].onmouseout = function(){showHoloTip(this.rel, this.id, false)};
		}
	}
}

/**
 * Used to ensure that everything in this script happens after the complete page is loaded.
*/
window.onload = initHoloTip;     
