/**
 * Display the selected info win overlay
 *
 * @param   string  id      The id of the info win to display
 * @param   integer xOffset The horizontal offset in pixels from the element's parent
 * @param   intefer yOffset The vertical offset in pixels from the element's parent
 * 
 * @return  nothing
 */

function show_info_win(id, xOffset, yOffset)
{
    // make sure params are the correct data types
    id      = String(id);
    xOffset = Number(xOffset);
    yOffset = Number(yOffset);
    
    //if ($(id).style.display != 'inline') {
        
        $(id).style.display = 'inline'; // info box needs to be displayed to make the calculations (change is quick enough to not notice)
        
        // get the window space dimensions
        var ww  = document.viewport.getWidth();
        var wh  = document.viewport.getHeight();
        
        // get/set the parent info box details
        var e_parent            = $(id).up();
        e_parent.style.zIndex   = 200000;
        var px                  = e_parent.viewportOffset().left;
        var py                  = e_parent.viewportOffset().top;
        
        // get the info box details
        var ew                  = $(id).getWidth();
        var eh                  = $(id).getHeight();
        var x_space             = ww - px;
        var y_space             = wh - py;
        
        var pointer_base        = id + '_pointer'; // for setting which pointer to display
        var pointer             = pointer_base;
        var show_pointer        = true;
        var safe_zone           = 20; // min clear space around box
        
        // set the top offset
        if (y_space > (eh + safe_zone + yOffset)) {     // if box fits in space below
            $(id).style.top     = yOffset + 'px';
            pointer            += '_t';
        } else if ((py + yOffset) > (eh + safe_zone)) { // if box fits in space above
            $(id).style.top     = (yOffset - eh) + 'px';
            pointer            += '_b';
        } else {
            show_pointer = false;
        }
        
        // set the left offset
        if (x_space > (ew + safe_zone + xOffset)) {     // if box fits in space to right
            $(id).style.left    = xOffset + 'px';
            pointer            += 'l';
        } else if ((px + xOffset) > (ew + safe_zone)) { // if box fits in space to left
            $(id).style.left    = (xOffset - ew) + 'px';
            pointer            += 'r';
        } else {
            show_pointer = false;
        }
        
        if (!show_pointer) { // if box doesn't fit in either space centre it in the window
            $(id).style.top     = (0 - ((py - Math.floor(wh / 2)) + Math.floor(eh / 2))) + 'px';
            $(id).style.left    = (0 - ((px - Math.floor(ww / 2)) + Math.floor(ew / 2))) + 'px';
        }
        
        // set up variables for testing for pointer arrows
        var pointers_exist  = false;
        var e_nodes         = $(id).childElements();
        
        for (var i = 0; i < e_nodes.length; i++) {
            if (e_nodes[i].id == id + '_pointer_tl') { // if at least one pointer exists
                pointers_exist = true;
            }
        }
        
        // add the pointer arrows if they don't already exist
        if (!pointers_exist) {
            var tl_img              = document.createElement('img');
            tl_img.src              = 'images/info-win/info_pointer_top_left.gif';
            tl_img.id               = id + '_pointer_tl';
            tl_img.style.position   = 'absolute';
            tl_img.style.top        = '-4px';
            tl_img.style.left       = '-4px';
            tl_img.style.display    = 'none';
            $(id).appendChild(tl_img);
            
            var tr_img              = document.createElement('img');
            tr_img.src              = 'images/info-win/info_pointer_top_right.gif';
            tr_img.id               = id + '_pointer_tr';
            tr_img.style.position   = 'absolute';
            tr_img.style.top        = '-4px';
            tr_img.style.right      = '3px';
            tr_img.style.cursor     = 'pointer';
            tr_img.style.display    = 'none';
            $(id).appendChild(tr_img);
            
            var bl_img              = document.createElement('img');
            bl_img.src              = 'images/info-win/info_pointer_bottom_left.gif';
            bl_img.id               = id + '_pointer_bl';
            bl_img.style.position   = 'absolute';
            bl_img.style.bottom     = '4px';
            bl_img.style.left       = '-4px';
            bl_img.style.display    = 'none';
            $(id).appendChild(bl_img);
            
            var br_img              = document.createElement('img');
            br_img.src              = 'images/info-win/info_pointer_bottom_right.gif';
            br_img.id               = id + '_pointer_br';
            br_img.style.position   = 'absolute';
            br_img.style.bottom     = '4px';
            br_img.style.right      = '3px';
            br_img.style.display    = 'none';
            $(id).appendChild(br_img);
        }
        
        $(pointer_base + '_tl').style.display   = 'none';
        $(pointer_base + '_tr').style.display   = 'none';
        $(pointer_base + '_bl').style.display   = 'none';
        $(pointer_base + '_br').style.display   = 'none';
        
        if (show_pointer) {
            $(pointer).style.display = 'inline'; // if the window is not centred then show the appropriate pointer arrow
        }    
    //}
}



/**
 * Hide the selected info win overlay
 *
 * @param   string  id      The id of the info win to hide
 * 
 * @return  nothing
 */

function hide_info_win(id)
{
    // if the selected info win is not hidden, reset its properties and hide it
    if ($(id).style.display != 'none') {
        $(id).style.left        = '0px';
        $(id).style.top         = '0px';
        $(id).up().style.zIndex = 0;
        $(id).style.display     = 'none';
    }
}



/**
 * Hide all info win overlays
 * 
 * @return  nothing
 */

function hide_all_info_wins()
{
    var info_wins = $$('div .info-box-block'); // get all the available info wins
    
    // cycle through the info wins, reset their properties and hide them
    for (var i = 0; i < info_wins.length; i++) {
        if (info_wins[i].style.display != 'none') {
            info_wins[i].style.top          = '0px';
            info_wins[i].style.left         = '0px';
            info_wins[i].up().style.zIndex  = 0;
            info_wins[i].style.display      = 'none';
        }
    }
}



/**
 * Hide all open info wins apart from the selected one
 *
 * @param   string  id      The id of the info win to hide
 * 
 * @return  nothing
 */

function hide_other_info_wins(id)
{
    var info_wins = $$('div .info-box-block'); // get all the available info wins
    
    // cycle through the info wins, reset their properties and hide them
    for (var i = 0; i < info_wins.length; i++) {
        if (info_wins[i].identify() != id && info_wins[i].style.display != 'none') {
            info_wins[i].style.top          = '0px';
            info_wins[i].style.left         = '0px';
            info_wins[i].up().style.zIndex  = 0;
            info_wins[i].style.display      = 'none';
        }
    }  
}



/**
 * Toggle display of selected info win overlay
 *
 * @param   string  id      The id of the info win to display
 * @param   integer xOffset The horizontal offset in pixels from the element's parent
 * @param   intefer yOffset The vertical offset in pixels from the element's parent
 * 
 * @return  nothing
 */

function toggle_info_win(id, xOffset, yOffset)
{
    // make sure params are the correct data types
    id      = String(id);
    xOffset = Number(xOffset);
    yOffset = Number(yOffset);
    
    hide_other_info_wins(id);
    
    // display the selected info win if it's not open, else hide it
    if ($(id).style.display != 'inline') {
        show_info_win(id, xOffset, yOffset);
    } else {
        hide_info_win(id);
    }
}
