// Copyright (C) 2005-2008 Hagerty Insurance. All rights reserved.
//
// Library of functions for associating a popup control with another element
//
// To use you must have a parent control that the user clicks and a child div
// control that is displayed when it is clicked. The div must use the PopupControl
// css class and style="visibility: hidden".
//
// <span id="lnkRoleDefinitions" style="text-decoration: underline">
//   Click here.
// </span>
//
// <div id="pnlRoleDefinitions" class="PopupControl" style="visibility: hidden">
//   Some html
// </div>
//
// <!-- This must be done at the bottom of the page, after all controls have been created -->
// <script language="javascript" type="text/javascript">
//    attachPopup("lnkRoleDefinitions", "pnlRoleDefinitions", "click", "left", "above", "pointer", 333);
// </script>
//

// ***** Popup Control *********************************************************

// This is to keep track if a popup is currently being displayed
var popup_child;
var popup_iframe;
var child_delay;
//var o_hide_child;

var ie = document.all;
function iecompattest()
{
   return (document.compatMode && document.compatMode!="BackCompat")? document.documentElement : document.body;
}

function isFiringOnChild(element, child, e) {
    var oe = element;
    var retval=false;
    //ignore events from iframe... so return true 
    if (element == popup_iframe) {
        retval = true;
    }
    
    if (e.type == "mouseout") {
        while (element.parentNode !== document.body) {
            //alert("element.tagName="+element.tagName+", element.parentID="+element.parentNode.id+", child.id="+child.id);
            if ( element.parentNode == child) {
                retval = true;
                break;
            }
            element = element.parentNode;
        }
    } else if (e.type == "blur") {
        //alert("element.tagName="+element.tagName+", element.id="+element.id+", child.id="+child.id);
        if (element == child) {
            retval = true;
        }
    } else {
        retval = true;
    }
    
    //alert("retval="+retval+", element="+element.id+", "+element.tagName+", e.type="+e.type+", OrigElement="+oe.id);
    return retval;
}

// Makes sure the specified edge is inside the browser viewport
function clearbrowseredge(parent, child, whichedge)
{
   if (whichedge=="right")
   {
      var edgeoffsetx = 0;
      var rightedge = (ie && !window.opera) ? iecompattest().scrollLeft + iecompattest().clientWidth-15 : window.pageXOffset + window.innerWidth-15;
      if (rightedge - child.x < child.offsetWidth)
      {
         edgeoffsetx = child.offsetWidth - parent.offsetWidth;
      }
      return edgeoffsetx;
   }
   else if (whichedge=="left")
   {
      var edgeoffsetx = child.x;
      var leftedge = (ie && !window.opera ? iecompattest().scrollLeft : window.pageXOffset);
      if (leftedge > child.x)
      {
         edgeoffsety = leftedge;
      }
      return edgeoffsetx;
   }
   else if (whichedge=="top")
   {
      var edgeoffsety = child.y;
      var topedge = (ie && !window.opera ? iecompattest().scrollTop : window.pageYOffset);
      if (topedge > child.y)
      {
         edgeoffsety = topedge;
      }
      return edgeoffsety;
   }
   else if (whichedge=="bottom")
   {
      var edgeoffsety = 0;
      var topedge = (ie && !window.opera ? iecompattest().scrollTop : window.pageYOffset);
      var bottomedge = (ie && !window.opera ? iecompattest().scrollTop+iecompattest().clientHeight-15 : window.pageYOffset+window.innerHeight-18);
      if (bottomedge - child.y < child.offsetHeight) //move up?
      {
         edgeoffsety = child.offsetHeight + parent.offsetHeight;
      }
      return edgeoffsety;
   }
   
   return 0;
}

// ***** popupShowImpl *****

function popupShowImpl(parent, child)
{
  var p = document.getElementById(parent);
  var c = document.getElementById(child);

  // Only allow one popup at a time to display
  if (popup_child != undefined && popup_child != c)
  {
    popup_child.style.visibility = "hidden";
    clearTimeout(popup_child["at_timeout"]);
  }
  popup_child = c;
  
  var parentWidth = p.offsetWidth;
  var parentHeight = p.offsetHeight;
  
  var top  = (c["at_positionY"] == "below") ? p.offsetHeight + 2 : 0;
  var left = (c["at_positionX"] == "right") ? p.offsetWidth + 2 : 0;

  var pNode = p;
  while (pNode)
  {
    top  += pNode.offsetTop;
    left += pNode.offsetLeft;
    pNode = pNode.offsetParent;
  }

  c.style.position = "absolute";
  if (c["at_positionY"] == "above")
  {
    // Add height of parent so its positioined at the bottom
    // Subtract height of child so it displays above
    top = top + parentHeight - c.offsetHeight;
    c.y = top;
    top = clearbrowseredge(p, c, "top");
    c.style.top = top + "px";
  }
  else
  {
    c.style.top = top + "px";
  }
  
  if (c["at_positionX"] == "left")
  {
    left = left + parentWidth - c.offsetWidth;
    c.x = left;
    left = clearbrowseredge(p, c, "left");
    c.style.left = left + "px";
  }
  else
  {
    c.style.left = left + "px";
  }
  
  var isIE6 = false /*@cc_on || @_jscript_version < 5.7 @*/;
  
    // Put an iframe under the popup so dropdowns don't show thru in ie6
    if (popup_iframe == undefined)
    {
      popup_iframe = document.createElement('iFrame');
      popup_iframe.id = 'popupControliFrame';
      popup_iframe.style.filter = 'alpha(opacity=0)';
      popup_iframe.style.position = 'absolute';
      popup_iframe.style.border = '0px';
      //popup_iframe.style.backgroundColor = 'red';
      popup_iframe.style.zIndex = 999998; //iFrame will be just below the theDiv
      
      c.parentNode.appendChild(popup_iframe);
    }
      
    if (isIE6) {
      popup_iframe.style.display = 'block';    
    } else {
      popup_iframe.style.display = 'none';
    }
    
    //set the position of the iframe and display it
    popup_iframe.style.top = c.style.top; //(top - 0) + "px"; //one less than the value given for theDiv
    popup_iframe.style.left = c.style.left; //(left - 0) + "px"; //one less than the value given for theDiv
    popup_iframe.style.height = (c.offsetHeight + 0) + "px";
    popup_iframe.style.width = (c.offsetWidth + 0) + "px";

    popup_iframe.style.visibility = "visible";
 
  
  c.style.zIndex = 999999;
  c.style.visibility = "visible";
  c.focus();
  clearTimeout(c["at_timeout"]);
}

// ***** popupShow *****

function popupShow()
{
  var p = document.getElementById(this["at_parent"]);
  var c = document.getElementById(this["at_child" ]);

  popup_iframe.style.visibility = "visible";
  
  var isOnChild = isFiringOnChild(window.event.srcElement, c, window.event);
  
  if (c.style.visibility != "visible") popupShowImpl(p.id, c.id);
}

// ***** popupHide *****

function popupHide(parent, child)
{
  var p = document.getElementById(parent == null ? this["at_parent"] : parent);
  var c = document.getElementById(child == null ? this["at_child" ] : child);
  
  //o_hide_child = c;
  
  //var isOnChild = isFiringOnChild(window.event.srcElement, c, window.event);
  
  //alert("isOnChild="+isOnChild);

  //if ( !isOnChild ) {
    //alert("setting timeout -- " + window.event.type + ", " + window.event.srcElement.tagName + ", " + window.event.srcElement.id);
    c["at_timeout"] = setTimeout("document.getElementById('"+c.id+"').style.visibility = 'hidden'", c["at_delay"]);
    setTimeout("popup_iframe.style.visibility = 'hidden'", c["at_delay"]);
  //}
}

// ***** popupParentClick *****

function popupParentClick()
{
  var p = document.getElementById(this["at_parent"]);
  var c = document.getElementById(this["at_child" ]);

  if (c.style.visibility != "visible") popupShowImpl(p.id, c.id);
  else c.style.visibility = "hidden";
  
  return false;
}

// ***** attachPopup *****

// PARAMETERS:
// parent   - id of the parent html element
// child    - id of the child  html element that should be the popup
// showtype - "click" = drop down child html element on mouse click
//            "hover" = drop down child html element on mouse over
// positionX - where to display the child html element (left, right)
// positionY - where to display the child html element (above, below)
// cursor   - omit to use default cursor or specify CSS cursor name for parent
// delay    - delay when an event to close the popup is fired

function attachPopup(parent, child, showtype, positionX, positionY, cursor, delay)
{
  var p = document.getElementById(parent);
  var c = document.getElementById(child);

  p["at_parent"]     = p.id;
  c["at_parent"]     = p.id;
  p["at_child"]      = c.id;
  c["at_child"]      = c.id;
  c["at_positionX"]  = positionX;
  c["at_positionY"]  = positionY;

  c.style.position   = "absolute";
  c.style.visibility = "hidden";

  if (cursor != undefined) p.style.cursor = cursor;

  switch (showtype)
  {
    case "click":
      p.onclick     = popupParentClick;
      //p.onblur      = popupHide;
      //p.onmouseover = popupHide;
      c.onmouseover = popupShow;
      //c.onmouseout  = popupHide;
      c.onblur      = popupHide;
      c["at_delay"] = (delay == undefined ? 0 : delay);
      child_delay   = c["at_delay"];
      break;
    case "hover":
      p.onmouseover = popupShow;
      p.onmouseout  = popupHide;
      c.onmouseover = popupShow;
      c.onmouseout  = popupHide;
      c["at_delay"] = (delay == undefined ? 333 : delay);
      child_delay   = c["at_delay"];
      break;
  }
}
