/**
 * Info box related variables
 */
var infoBoxDelay = 1000;

// the padding between the information icon and the boundary of the info box
// that pops up
var infoboxPaddingY = 15;

var ib_url;
var ib_id;
var ib_recipient = null;
// the infobox that is currently visible to the user
var ib_recent = null;

/**
 * skips the call to showInfoBoxDelayed() in the showInfoBox() function; this
 * is used during info box preloading to allow for showInfoBox() to be called
 * for only setting the global variables and not showing the info boxes.
 */
var skipTimeout = false;

/**
 * Called with the body onload handler, this function preloads the infoboxes
 * that have a class of 'preloaded-info-box' (the ones containing product information).
 */
function preloadInfoBoxes()
{
  skipTimeout = true;
  /**
   * Returns an array of all the anchor elements (<a>) elements in the document with
   * the given class.
   * 
   * @param cname The classname that the returned anchors should have.
   */
  function getAnchorsByClass(cname) {
  	var res = new Array();
  	var allLinks = document.getElementsByTagName("a");
  	for(var i = 0; i < allLinks.length; ++i) {
  		// if the this anchor is an infobox link, then load that infobox
  		var link = allLinks[i];
  		if(link.className && (link.className.indexOf(cname) != -1)) {
  			res.push(link);
  		}
  	}
  	
  	return res;
  }
  
  /**
   * Returns true if the array "arr" contains the value "val".
   */
  function arrayContains(arr, val) {
  	for(var i = 0; i < val.length; ++i) {
  		if(val == arr[i])
  			return true;
  	}
  	
  	return false;
  }
  
  var allInfoBoxes = getAnchorsByClass("preloaded-info-box");
  var loadedInfoBoxes = new Array();
  for(var i = 0; i < allInfoBoxes.length; ++i) {
  	// initialize ib_* variables required for infobox creation
  	allInfoBoxes[i].onmouseover();
  	var boxID = allInfoBoxes[i].getAttribute("id");
  	if(!arrayContains(loadedInfoBoxes, boxID)) {
  		createInfoBox(ib_recipient);
  		loadedInfoBoxes.push(boxID);
  	}
  }

  // allow future calls to showInfoBoxDelayed() to show the infobox
  skipTimeout = false;
}

/**
 * Shows the Info Box with the given id (with a delay).
 * 
 * @param startUrl   The start of the url to call to retrieve the info box data.
 * @param id         The id of the info box to show.
 * @param recipient  The id of the div where the info box should be inserted.
 * @param parameters Additional parameters for the Infobox (optional)
 */
function showInfoBox(startUrl, id, recipient, parameters) {
  ib_url = startUrl+'/fragment/infobox?id=' + id + '&recipient=' + recipient;
  if (parameters != null) {
  	for (pname in parameters) {
  		ib_url += "&"+pname+"="+parameters[pname];
  	}
  }
  ib_id = id;
  ib_recipient = 'infobox-' + recipient;
  if(!skipTimeout)
	  setTimeout('showInfoBoxDelayed("'+ib_recipient+'")', infoBoxDelay);
  	  
}

/**
 * Cancels the display of any Info Box
 */
function cancelShowInfoBox() {
  ib_recipient = null;
}

/**
 * Creates the info box div and calls the relevant methods for performing the
 * XMLHttpRequest() for the content.
 */
function createInfoBox(recipient) {
	var div = document.createElement("div");
  	div.setAttribute("id", recipient);
    document.getElementById("pbs-main").appendChild(div);
    retrieveInfoBoxAndHide(ib_url, recipient);
    div.style.position = "absolute";
    div.style.display = "none";
}

/**
 * Shows the Info Box after the delay
 */
function showInfoBoxDelayed(recipient) {
  if (ib_recipient != recipient)
    return false;
  
  /* hide the infobox that was last displayed; only 1 should
   * be displayed at a time.
   */
  if(ib_recent != null) {
  	var lastDiv = document.getElementById(ib_recent);
  	if(lastDiv)
  		lastDiv.style.display = 'none';
  }
  ib_recent = recipient;
  
 // if this div was previously created and subsequently hidden, then don't create a new one
  var previousDiv = document.getElementById(recipient);
  var div;

  if (previousDiv != null) {
  	div = previousDiv;
  } 
  else {
  	div = document.createElement("div");
  	div.setAttribute("id", ib_recipient);
  	div.style.height = "auto";
  }

  if (div.innerHTML == '') {
    document.getElementById("pbs-main").appendChild(div);
    retrieveInfoBox(ib_url, ib_recipient);
    div.style.position = "absolute";
  }

  /**
   * Returns the recommended position along the X axis for the info
   * box to be placed so that the info box is always within the viewport.
   * 
   * The current page width is checked and if the infobox does not fit into
   * the page width left in the bottom right section of posX, then the box
   * is slided along to the left.
   */
  function getInfoBoxPosX(posX) {
  	// var windowWidth = document.body.clientWidth;
  	var windowWidth = getWindowWidth();
    var divWidth = 310; 
    
    if((windowWidth - posX) < (divWidth + 20))
//      added 20px as as security difference
//      return (windowWidth - divWidth);
      return (posX - divWidth);
    else
      return posX;
  }

  /**
   * Returns the recommended position along the Y axis for the info
   * box to be placed so that the info box is always within the viewport.
   * 
   * The current page height is checked and if the infobox does not fit into
   * the page height left underneath the point posY, then the box moved to
   * a location above posY.
   */
  function getInfoBoxPosY(posY) {
  	// get the current window dimensions
    // var windowHeight = document.body.clientHeight;

  	var windowHeight = getWindowHeight();

    //var divHeight = div.offsetHeight;
    var divHeight = 150;
   
    bottomOffset = (windowHeight - posY);
    requiredOffset = (divHeight + infoboxPaddingY);
  
    if( (windowHeight - posY) < (divHeight + infoboxPaddingY) )
      return (posY - divHeight - infoboxPaddingY);
    else
      return posY + infoboxPaddingY;
  }
  
  var recommendedX = getInfoBoxPosX(posX);
  var recommendedY = getInfoBoxPosY(posY);

  // div.offsetHeight always returns 0, so just use posY for now
  // var recommendedY = posY + infoboxPaddingY;


  var bottomOffset = (getWindowHeight() - posY);
  var requiredOffset = (150 + infoboxPaddingY);
  var expectedRec = (posY - 150 - infoboxPaddingY);


  // in case anything goes wrong with the recommendations for posX and posY,
  // just fall back to the original values.
  if(recommendedX === null || recommendedX === "" || !(recommendedX >= 0))
  	recommendedX = posX;
  if(recommendedY === null  || recommendedY === "" || !(recommendedY >= 0))
  	recommendedY = posY + infoboxPaddingY;
  
  // add px to specify the dimensions
  div.style.left = recommendedX + "px";
  div.style.top = recommendedY + "px";


  // set the style display to block AFTER it has been correctly positioned.
  div.style.display = "block";
  
  return false;
}

/**
 * Hides the Info Box with the given id
 * 
 * @param id the id of the info box to hide
 */
function hideInfoBox(id) {
  var div = document.getElementById('infobox-'+id);
  if (div)
    div.style.display = 'none';
    

  var trackDiv = document.getElementById('trackDiv');
  if (trackDiv)
    trackDiv.style.display = 'none';
    
  return false;
}

/**
 * Retrieve Mouse position
 */
 
var posX = 0;
var posY = 0;

 
var IE = document.all ? true : false;
if (!IE) document.captureEvents(Event.MOUSEMOVE);
document.onmousemove = getMouseXY2;



// Main function to retrieve mouse x-y pos.s
function getMouseXY(e) {
  if (IE) { // grab the x-y pos.s if browser is IE
    posX = event.clientX + document.body.scrollLeft + document.documentElement.scrollLeft;
    posY = event.clientY + document.body.scrollTop + document.documentElement.scrollTop;
  } else {  // grab the x-y pos.s if browser is NS
    posX = e.pageX;
    posY = e.pageY;
  }
  // catch possible negative values in NS4
  if (posX < 0) {posX = 0}
  if (posY < 0) {posY = 0}
  return true;
}

function getMouseXY2(e) {
  if( !e ) {
    if( window.event ) {
      //Internet Explorer
      e = window.event;
    } else {
      //total failure, we have no way of referencing the event
      return;
    }
  }
  if( typeof( e.pageX ) == 'number' ) {
    //most browsers
    posX = e.pageX;
    posY = e.pageY;
  } else if( typeof( e.clientX ) == 'number' ) {
    //Internet Explorer and older browsers
    //other browsers provide this, but follow the pageX/Y branch
    posX = e.clientX;
    posY = e.clientY;
    var badOldBrowser = ( window.navigator.userAgent.indexOf( 'Opera' ) + 1 ) ||
     ( window.ScriptEngine && ScriptEngine().indexOf( 'InScript' ) + 1 ) ||
     ( navigator.vendor == 'KDE' );
    if( !badOldBrowser ) {
      if( document.body && ( document.body.scrollLeft || document.body.scrollTop ) ) {
        //IE 4, 5 & 6 (in non-standards compliant mode)
        posX += document.body.scrollLeft;
        posY += document.body.scrollTop;
      } else if( document.documentElement && ( document.documentElement.scrollLeft || document.documentElement.scrollTop ) ) {
        //IE 6 (in standards compliant mode)
        posX += document.documentElement.scrollLeft;
        posY += document.documentElement.scrollTop;
      }
    }
  } else {
    //total failure, we have no way of obtaining the mouse coordinates
    return;
  }  
}

function getWindowWidth() {
  if( typeof( window.innerWidth ) == 'number' ) {
    //Non-IE
    return (window.innerWidth);
  } 
  else if( document.documentElement && ( document.documentElement.clientWidth || document.documentElement.clientHeight ) ) {
    //IE 6+ in 'standards compliant mode'
    return (document.documentElement.clientWidth);
  } 
  else if( document.body && ( document.body.clientWidth || document.body.clientHeight ) ) {
    //IE 4 compatible
    return (document.body.clientWidth);
  }
  return true;
}

function getWindowHeight() {
  if( typeof( window.innerWidth ) == 'number' ) {
    //Non-IE
    return (window.innerHeight);
  } 
  else if( document.documentElement && ( document.documentElement.clientWidth || document.documentElement.clientHeight ) ) {
    //IE 6+ in 'standards compliant mode'
    return (document.documentElement.clientHeight);
  } 
  else if( document.body && ( document.body.clientWidth || document.body.clientHeight ) ) {
    //IE 4 compatible
    return (document.body.clientHeight);
  }
  return true;
}

function trackDimensions (ib_recipient) {

  var trackDiv = document.createElement("div");
  trackDiv.setAttribute("id", "trackDiv");
  document.getElementById("pbs-main").appendChild(trackDiv);
  document.getElementById("trackDiv").innerHTML="<div>"
  + "<div>posX: " + posX + "</div>"
  + "<div>posY: " + posY + "</div>"
  + "<div>ib_recipient: " + ib_recipient + "</div>"

/*
  + "<div>recommendedX: " + recommendedX + "</div>"
  + "<div>recommendedY: " + recommendedY + "</div>"
  + "<div>document.body.clientWidth: " + document.body.clientWidth + "</div>"
  + "<div>document.documentElement.clientHeight: " + document.documentElement.clientHeight + "</div>"
  + "<div>getWindowHeight(): " + getWindowHeight() + "</div>"
  + "<div>getWindowWidth(): " + getWindowWidth() + "</div>"
  + "<div>bottomOffset: " + bottomOffset + "</div>"
  + "<div>requiredOffset: " + requiredOffset + "</div>"
  
 */ 
  + "<div>computed: " + document.getElementById(ib_recipient).offsetHeight + "</div>"
  + "</div>";

  trackDiv.style.left = "500px";
  trackDiv.style.top = "20px";
  trackDiv.style.display = "block";
  trackDiv.style.position = "absolute";

}

function adjustIBoxPos (ib_recipient) {
  var dimensionsDelay = 3000;
  setTimeout('trackDimensions("'+ib_recipient+'")', dimensionsDelay);
}
