// popup routines
//###############
//###############
//###############

// context popup routines
//=======================
//=======================
//=======================
var pufxContextXOffset = 10; // x-offset (in px) from event context
var pufxContextYOffset = 0; // y-offset (in px) from event context
var pufxContextViewableWidth = false; // x-offset (in px) from screen view width
                                      // if not supplied, popupElem.offsetWidth used
                                     // (which may not always have a value)
var pufxContextViewableHeight = false; // y-offset (in px) from screen view height
                                       // if not supplied, popupElem.offsetHeight used
                                       // (which may not always have a value)

// pufxContextInit - context popup initialization routine
/////////////////////////////////////////////////////////
function pufxContextInit( popupXOffset,
                          popupYOffset,
                          popupViewableWidth,
                          popupViewableHeight) {
  pufxContextXOffset = popupXOffset;
  pufxContextYOffset = popupYOffset;
  pufxContextViewableWidth = popupViewableWidth;
  pufxContextViewableHeight = popupViewableHeight; }

// pufxShowContextPopup( contextId, popupElemId, eventObj, popupPosElemId )
//---------------------------------------------------------
// show event context popup
// contextId should represent a unique value for the item linked to popup
// popupElemId is the DOM id of the popup
// eventObj is the event invoking this method
// popupPosElemId (optional, else use XOff,YOff) element representing position of popup
///////////////////////////////////////////////////////////
function pufxShowContextPopup( contextId,
                               popupElemId,
                               eventObj,
                               popupPosElemId ) {

  // turn off close popup delay timer
  // (if necessary)
  //---------------------------------
  pufxClearCloseContextPopupTimer();

  // check context for this popup request
  //-------------------------------------
  if( (window.pufxContextPopupOpened
        && (window.pufxContextPopupOpened == popupElemId)
        && (window.pufxContextIdPopped == contextId))
      || (window.pufxPreviousStickyContextId == contextId) )
    return( false );

  window.pufxPreviousStickyContextId
    = false;

  if( eventObj ) {

    // close any current popup
    //------------------------
    pufxCloseContextPopup();

    // stop event bubbling
    //--------------------
    eventObj.cancelBubble
      = true;

    // move popup element (try to keep popup in view)
    //-----------------------------------------------
    var xCoord;
    var yCoord;

    var popupPosElem;
    if( popupPosElemId ) 
      popupPosElem
        = sfxGetElement(
            popupPosElemId );

    // move popup - close to cursor position
    //--------------------------------------
    if( !popupPosElem ) {
      xCoord
        = eventObj.pageX
            ? eventObj.pageX + pufxContextXOffset
            : eventObj.x + pufxContextXOffset
                + (document.body.scrollLeft
                    ? document.body.scrollLeft
                    : 0);
      yCoord
        = eventObj.pageY
            ? eventObj.pageY + pufxContextYOffset
            : eventObj.y + pufxContextYOffset
                + (document.body.scrollTop
                    ? document.body.scrollTop
                    : 0); }

    // move popup - to popupPosElem element
    //-------------------------------------
    else {
      xCoord
        = pufxGetElemX(
            popupPosElem ) + pufxContextXOffset;
      yCoord
        = pufxGetElemY(
            popupPosElem ) + pufxContextYOffset; }

    // if popup extends off view, attempt to re-position in view
    //----------------------------------------------------------
    var popupElem
      = sfxGetElement(
          popupElemId );

    var popupViewableWidth
      = pufxContextViewableWidth
          ? pufxContextViewableWidth
          : popupElem.offsetWidth;
    var popupViewableHeight
      = pufxContextViewableHeight
          ? pufxContextViewableHeight
          : popupElem.offsetHeight;

    if( popupElem
        && eventObj.clientX && eventObj.clientY
        && popupViewableWidth && popupViewableHeight ) {
      if( (popupViewableWidth < window.innerWidth)
          && ((eventObj.clientX + popupViewableWidth) > window.innerWidth) )
        xCoord
          = (window.innerWidth - popupViewableWidth);
      if( (popupViewableHeight < window.innerHeight)
          && ((eventObj.clientY + popupViewableHeight) > window.innerHeight) )
        yCoord
          = (window.innerHeight - popupViewableHeight); }

    // move popup to event context position
    //-------------------------------------
    sfxMoveObj(
      popupElemId,
      xCoord,
      yCoord );

    // make popup visible
    //-------------------
    sfxToggleVisibility(
      popupElemId,
      true );

    window.pufxContextPopupOpened
      = popupElemId;
    window.pufxContextIdPopped
      = contextId;

    return( true ); }

  // no event object present
  //------------------------
  else
    return( false ); }

// pufxCloseContextPopup( unstickPopup, closePopupDelay )
// -----------------------------------------------------
// close any outstanding popup
// if unstickPopup is true, then close popup and only reshow
// popup for this context item if another context item has invoked a popup
// closePopupDelay (optional) specifies the number of miliseconds until the
// popup should be closed.  if not provided the popup will close immediately.
////////////////////////////////////////////////////////
function pufxCloseContextPopup( unstickPopup,
                                closePopupDelay ) {

  if( unstickPopup )
    window.pufxPreviousStickyContextId
      = window.pufxContextIdPopped;

  if( window.pufxContextPopupOpened ) {

    if( closePopupDelay ) {
     window.pufxClosePopupTimer
       = setTimeout(
           function() {
             pufxCloseContextPopup( false ) },
           closePopupDelay );
     return; }

    pufxClearCloseContextPopupTimer();

    sfxToggleVisibility(
      pufxContextPopupOpened,
      false );
    window.pufxContextPopupOpened
      = false;
    window.pufxContextIdPopped
      = ''; } }

// pufxClearCloseContextPopupTimer()
// --------------------------
// clear any pending close popup timer
// returns true|false if timer was cleared
/////////////////////////////
function pufxClearCloseContextPopupTimer() {

  if( window.pufxClosePopupTimer ) {
    clearTimeout(
      window.pufxClosePopupTimer );
    window.pufxClosePopupTimer
      = null;
    return( true ); }

  return( false ); }

// common popup routines
//======================
//======================
//======================

// pufxInit - popup initialization routine
//////////////////////////////////////////
function pufxInit() {

  var undefined;

  // setup event object for older browsers
  //--------------------------------------
  if( window.event === undefined )
    window.event
      = null; }

// register popup initialization w/ onload runner
/////////////////////////////////////////////////
//var documentOnloadRunner
//  = document.onloadEventRunner;
//if( !documentOnloadRunner )
//  documentOnloadRunner
//    = new efxEventRunner(
//      document,
//      "onload" );
//documentOnloadRunner.addEventListener(
//  pufxInit );
pufxInit();

// pufxGetElemX - determines true x-position of element
//////////////////////////////////////////
function pufxGetElemX( elem ) {

  var x = 0;
  for( var ancesElem = elem;
       ancesElem;
       ancesElem = ancesElem.offsetParent )
    x += ancesElem.offsetLeft;

  for( ancesElem = elem.parentNode;
       ancesElem && (ancesElem != document.body);
       ancesElem = ancesElem.parentNode )
    if( ancesElem.scrollLeft )
      x -= ancesElem.scrollLeft;

  return( x ); }

// pufxGetElemY - determines true y-position of element
//////////////////////////////////////////
function pufxGetElemY( elem ) {

  var y = 0;
  for( var ancesElem = elem;
       ancesElem;
       ancesElem = ancesElem.offsetParent )
    y += ancesElem.offsetTop;

  for( ancesElem = elem.parentNode;
       ancesElem && (ancesElem != document.body);
       ancesElem = ancesElem.parentNode )
    if( ancesElem.scrollTop )
      y -= ancesElem.scrollTop;

  return( y ); }

