// ===================================================================
// Author: Matt Kruse <matt@mattkruse.com>
// WWW: http://www.mattkruse.com/
//
// NOTICE: You may use this code for any purpose, commercial or
// private, without any further permission from the author. You may
// remove this notice from your final code if you wish, however it is
// appreciated by the author if at least my web site address is kept.
//
// You may *NOT* re-distribute this code in any way except through its
// use. That means, you can include it in your product, or your web
// site, or any other form where the code is actually being used. You
// may not put the plain javascript up on your site for download or
// include it in your javascript libraries for download. 
// If you wish to share this code with others, please just point them
// to the URL instead.
// Please DO NOT link directly to my .js files from your site. Copy
// the files to your server and use them there. Thank you.
// ===================================================================

/* SOURCE FILE: AnchorPosition.js */
function getAnchorPosition(anchorname){var useWindow=false;var coordinates=new Object();var x=0,y=0;var use_gebi=false, use_css=false, use_layers=false;if(document.getElementById){use_gebi=true;}else if(document.all){use_css=true;}else if(document.layers){use_layers=true;}if(use_gebi && document.all){x=AnchorPosition_getPageOffsetLeft(document.all[anchorname]);y=AnchorPosition_getPageOffsetTop(document.all[anchorname]);}else if(use_gebi){var o=document.getElementById(anchorname);x=AnchorPosition_getPageOffsetLeft(o);y=AnchorPosition_getPageOffsetTop(o);}else if(use_css){x=AnchorPosition_getPageOffsetLeft(document.all[anchorname]);y=AnchorPosition_getPageOffsetTop(document.all[anchorname]);}else if(use_layers){var found=0;for(var i=0;i<document.anchors.length;i++){if(document.anchors[i].name==anchorname){found=1;break;}}if(found==0){coordinates.x=0;coordinates.y=0;return coordinates;}x=document.anchors[i].x;y=document.anchors[i].y;}else{coordinates.x=0;coordinates.y=0;return coordinates;}coordinates.x=x;coordinates.y=y;return coordinates;}
function getAnchorWindowPosition(anchorname){var coordinates=getAnchorPosition(anchorname);var x=0;var y=0;if(document.getElementById){if(isNaN(window.screenX)){x=coordinates.x-document.body.scrollLeft+window.screenLeft;y=coordinates.y-document.body.scrollTop+window.screenTop;}else{x=coordinates.x+window.screenX+(window.outerWidth-window.innerWidth)-window.pageXOffset;y=coordinates.y+window.screenY+(window.outerHeight-24-window.innerHeight)-window.pageYOffset;}}else if(document.all){x=coordinates.x-document.body.scrollLeft+window.screenLeft;y=coordinates.y-document.body.scrollTop+window.screenTop;}else if(document.layers){x=coordinates.x+window.screenX+(window.outerWidth-window.innerWidth)-window.pageXOffset;y=coordinates.y+window.screenY+(window.outerHeight-24-window.innerHeight)-window.pageYOffset;}coordinates.x=x;coordinates.y=y;return coordinates;}
function AnchorPosition_getPageOffsetLeft(el){var ol=el.offsetLeft;while((el=el.offsetParent) != null){ol += el.offsetLeft;}return ol;}
function AnchorPosition_getWindowOffsetLeft(el){return AnchorPosition_getPageOffsetLeft(el)-document.body.scrollLeft;}
function AnchorPosition_getPageOffsetTop(el){var ot=el.offsetTop;while((el=el.offsetParent) != null){ot += el.offsetTop;}return ot;}
function AnchorPosition_getWindowOffsetTop(el){return AnchorPosition_getPageOffsetTop(el)-document.body.scrollTop;}

/* SOURCE FILE: PopupWindow.js */
function PopupWindow_getXYPosition(anchorname){var coordinates;if(this.type == "WINDOW"){coordinates = getAnchorWindowPosition(anchorname);}else{coordinates = getAnchorPosition(anchorname);}this.x = coordinates.x;this.y = coordinates.y;}
function PopupWindow_setSize(width,height){this.width = width;this.height = height;}
function PopupWindow_populate(contents){this.contents = contents;this.populated = false;}
function PopupWindow_setUrl(url){this.url = url;}
function PopupWindow_setWindowProperties(props){this.windowProperties = props;}
function PopupWindow_refresh(){if(this.divName != null){if(this.use_gebi){document.getElementById(this.divName).innerHTML = this.contents;}else if(this.use_css){document.all[this.divName].innerHTML = this.contents;}else if(this.use_layers){var d = document.layers[this.divName];d.document.open();d.document.writeln(this.contents);d.document.close();}}else{if(this.popupWindow != null && !this.popupWindow.closed){if(this.url!=""){this.popupWindow.location.href=this.url;}else{this.popupWindow.document.open();this.popupWindow.document.writeln(this.contents);this.popupWindow.document.close();}this.popupWindow.focus();}}}
function PopupWindow_showPopup(anchorname){this.getXYPosition(anchorname);this.x += this.offsetX;this.y += this.offsetY;if(!this.populated &&(this.contents != "")){this.populated = true;this.refresh();}if(this.divName != null){if(this.use_gebi){document.getElementById(this.divName).style.left = this.x + "px";document.getElementById(this.divName).style.top = this.y + "px";document.getElementById(this.divName).style.visibility = "visible";}else if(this.use_css){document.all[this.divName].style.left = this.x;document.all[this.divName].style.top = this.y;document.all[this.divName].style.visibility = "visible";}else if(this.use_layers){document.layers[this.divName].left = this.x;document.layers[this.divName].top = this.y;document.layers[this.divName].visibility = "visible";}}else{if(this.popupWindow == null || this.popupWindow.closed){if(this.x<0){this.x=0;}if(this.y<0){this.y=0;}if(screen && screen.availHeight){if((this.y + this.height) > screen.availHeight){this.y = screen.availHeight - this.height;}}if(screen && screen.availWidth){if((this.x + this.width) > screen.availWidth){this.x = screen.availWidth - this.width;}}var avoidAboutBlank = window.opera ||( document.layers && !navigator.mimeTypes['*']) || navigator.vendor == 'KDE' ||( document.childNodes && !document.all && !navigator.taintEnabled);this.popupWindow = window.open(avoidAboutBlank?"":"about:blank","window_"+anchorname,this.windowProperties+",width="+this.width+",height="+this.height+",screenX="+this.x+",left="+this.x+",screenY="+this.y+",top="+this.y+"");}this.refresh();}}
function PopupWindow_hidePopup(){if(this.divName != null){if(this.use_gebi){document.getElementById(this.divName).style.visibility = "hidden";}else if(this.use_css){document.all[this.divName].style.visibility = "hidden";}else if(this.use_layers){document.layers[this.divName].visibility = "hidden";}}else{if(this.popupWindow && !this.popupWindow.closed){this.popupWindow.close();this.popupWindow = null;}}}
function PopupWindow_isClicked(e){if(this.divName != null){if(this.use_layers){var clickX = e.pageX;var clickY = e.pageY;var t = document.layers[this.divName];if((clickX > t.left) &&(clickX < t.left+t.clip.width) &&(clickY > t.top) &&(clickY < t.top+t.clip.height)){return true;}else{return false;}}else if(document.all){var t = window.event.srcElement;while(t.parentElement != null){if(t.id==this.divName){return true;}t = t.parentElement;}return false;}else if(this.use_gebi && e){var t = e.target;while(t.parentNode != null){if(t.id==this.divName){return true;}t = t.parentNode;}return false;}return false;}return false;}
function PopupWindow_hideIfNotClicked(e){if(this.autoHideEnabled && !this.isClicked(e)){this.hidePopup();}}
function PopupWindow_autoHide(){this.autoHideEnabled = true;}
function PopupWindow_hidePopupWindows(e){for(var i=0;i<popupWindowObjects.length;i++){if(popupWindowObjects[i] != null){var p = popupWindowObjects[i];p.hideIfNotClicked(e);}}}
function PopupWindow_attachListener(){if(document.layers){document.captureEvents(Event.MOUSEUP);}window.popupWindowOldEventListener = document.onmouseup;if(window.popupWindowOldEventListener != null){document.onmouseup = new Function("window.popupWindowOldEventListener();PopupWindow_hidePopupWindows();");}else{document.onmouseup = PopupWindow_hidePopupWindows;}}
function PopupWindow(){if(!window.popupWindowIndex){window.popupWindowIndex = 0;}if(!window.popupWindowObjects){window.popupWindowObjects = new Array();}if(!window.listenerAttached){window.listenerAttached = true;PopupWindow_attachListener();}this.index = popupWindowIndex++;popupWindowObjects[this.index] = this;this.divName = null;this.popupWindow = null;this.width=0;this.height=0;this.populated = false;this.visible = false;this.autoHideEnabled = false;this.contents = "";this.url="";this.windowProperties="toolbar=no,location=no,status=no,menubar=no,scrollbars=auto,resizable,alwaysRaised,dependent,titlebar=no";if(arguments.length>0){this.type="DIV";this.divName = arguments[0];}else{this.type="WINDOW";}this.use_gebi = false;this.use_css = false;this.use_layers = false;if(document.getElementById){this.use_gebi = true;}else if(document.all){this.use_css = true;}else if(document.layers){this.use_layers = true;}else{this.type = "WINDOW";}this.offsetX = 0;this.offsetY = 0;this.getXYPosition = PopupWindow_getXYPosition;this.populate = PopupWindow_populate;this.setUrl = PopupWindow_setUrl;this.setWindowProperties = PopupWindow_setWindowProperties;this.refresh = PopupWindow_refresh;this.showPopup = PopupWindow_showPopup;this.hidePopup = PopupWindow_hidePopup;this.setSize = PopupWindow_setSize;this.isClicked = PopupWindow_isClicked;this.autoHide = PopupWindow_autoHide;this.hideIfNotClicked = PopupWindow_hideIfNotClicked;}

/** 
The 'base' is the URL prefix added to context-relative paths like 
'/static/img/...' to make them externally accessible.  This is 
deployment-specific and set by 'setBase()' function below. 
*/
var base = null;

/** 
Generates a help button using javascript.  The 'id' parameter is used
as the DOM node id of the generated IMG tag which serves as the anchor for
the help popup window (MUST be unique within the page).  The "text" is the
help text to be displayed.  If "text" is undefined (e.g., when called without
it like "makeHelp(id)"), then the help text is taken from the global object
named "HELP" as the property for the "id"; e.g., "makeHelp('xxx')" will display
text defined as "HELP['xxx']".  Sets "onmouseover" to "onMouseOverHelp()",
"onmouseout" to "onMouseOutHelp()", and "onlick" to "showHelp()" below.
*/
function makeHelp(id, text) {
  var textPart = (text != undefined) ? text.replace(/'/g, "\\'") : '';
  document.write('<img id="' + id + '" class="icon" src="' + base + '/static/img/question_std.gif" onmouseover="this.src=' + "'" + base + "/static/img/question_over.gif'" + "; onMouseOverHelp(this, '" + textPart + "');" + '" onmouseout="onMouseOutHelp(); this.src=' + "'" + base +"/static/img/question_std.gif'" + '" onclick="showHelp()"/>');
}

/**
Similar to makeHelp(), this generates a help text anchor with "linkText"
value, instead of an image.
*/
function makeTextHelp(id, linkText, text) {
  var textPart = (text != undefined) ? text.replace(/'/g, "\\'") : '';
  document.write('<a href="#" id="' + id + '" class="helpLink" onmouseover="onMouseOverHelp(this,' + " '" + textPart + "');" + '" onmouseout="onMouseOutHelp()" onclick="showHelp()">' + linkText + '</a>');
}

/**
The 'helpNode' keeps the node to display help for.  To enable delayed popup, 
this is set to the node under mouse on mouseover event, and the help popup
is displayed after 1 second if the mouse doesn't leave the node. 
*/
var helpNode = null;

/**
Handles mouseover on help nodes.  If help popup is already displayed, 
then immediately shows help; otherwise keeps the node in 'helpNode' and
starts a 1 second "showHelp()" timer.  Receives the value of "text" given
to makeHelp() or makeTextHelp() which is kept as "helpText" property of the
node in "helpNode".
*/
function onMouseOverHelp(node, text) {
  var timeout = 1000;

  var popupVisible = document.getElementById(helpPopup.divName).style.visibility;
  if (popupVisible == 'visible') {
    timeout = 0;
  }

  if (helpNode == null) {
    helpNode = node;
    helpNode.helpText = text;
    helpNode.helpTimer = setTimeout(showHelp, timeout);
  }
}

/**
Handles mouseout on help nodes.  Clears the 1 second timer if the mouse
goes out of the 'helpNode'.
*/

function onMouseOutHelp() {
  if (helpNode != null) {
    clearTimeout(helpNode.helpTimer);
    helpNode.helpText = null;
    helpNode = null;
  }
}

/**
Shows help popup on 'helpNode' using divs named "helpBox" 
(whose innerHTML is set to the help text) and "helpIFrame" 
(used to make surethe help box appears above other page
components such as scroll bars).  The popup shape is adjusted to 
something close to square.
*/

function showHelp() {
  if (helpNode != null) {
    var helpBox = document.getElementById("helpBox");
    var helpIframe = document.getElementById("helpIframe");
    var text = helpNode.helpText;
    var node = helpNode;

    helpBox.style.width = '100px';
    helpBox.innerHTML = (text != '') ? text : HELP[node.id];
    helpPopup.offsetX = 12;
    helpPopup.offsetY = 12;

    var adjustedWidth = parseInt(Math.floor(Math.sqrt(helpBox.offsetWidth * helpBox.offsetHeight)));
    helpBox.style.width = adjustedWidth + 'px';

    helpIframe.style.width = (helpBox.offsetWidth + 22) + 'px';
    helpIframe.style.height = (helpBox.offsetHeight + 22) + 'px';
    helpPopup.showPopup(node.id);
  }
};

/**
Keeps an instance of help popup (PopupWindow).
*/
var helpPopup = null;

/**
Sets base and initializes helpPopup.
*/
function setBase(b) {
  base = b;
  helpPopup = new PopupWindow("helpFrame");
  helpPopup.autoHide();
}
