﻿//-----------------------------------------------------------------------------
// XPopup
//
// Copyright 2005-2010 - Xcential Group LLC.
//
//-----------------------------------------------------------------------------

XPopup.prototype = new XControl;
XPopup.prototype.constructor = XPopup;

//=============================================================================
// Constructor

function XPopup(
   id,
   uri,
   create
)
{
   id = (id == null) ? null : id;
   uri = (uri == null) ? null : uri;
   create = (create == null) ? true : false;

   if (create)
      return new XPopup(id, uri, false);

   //--------------------------------------------------------------------------
   // Private Interface

   //--------------------------------------------------------------------------
   // Privileged Interface

   this.valueOf = function()
   {

      return oSpec;
   }

   //--------------------------------------------------------------------------

   this.setObjectValue = function(
      id
   )
   {
      id = (id == null) ? null : id;

      oSpec = XPopup.getSpecFrom(id);

      return oSpec;
   }

   //--------------------------------------------------------------------------
   // Initialization

   var oSpec = this.setObjectValue(id);

   XControl.controls[oSpec.id] = this;

}

XPopup.prototype.objectClass = "XPopup";

//=============================================================================
// Static Interface

XPopup.HIDE_FORCE = true;

XPopup.POPUP_DELAY = 1000;

XPopup.ASYNCH = true;
XPopup.NO_ASYNCH = false;

XPopup.activePopup = null;

//-----------------------------------------------------------------------------

XPopup.getSpecFrom = function(
   id,
   uri
)
{
   id = (id == null) ? XUtils.generateId("urn:xcential-com:popup:", XUtils.SCHEME_RANDOM) : id;
   uri = (uri == null) ? null : uri;

   var spec = new Array();
   spec.id = id;
   spec.uri = uri;
   spec.className = "XPopup";
   spec.contentClassName = null;
   spec.tabIndex = 0;
   spec.htmlNode = null;
   spec.mouseIn = false;
   spec.mouseOut = true;
   spec.asynch = true;
   spec.visible = false;
   spec.left = 0;
   spec.top = 0;
   spec.width = 200;
   spec.height = null;
   spec.xOffset = -66;
   spec.yOffset = 20;
   spec.shadowSize = 6;
   spec.activeMenuItemIndex = null;

   return spec;
}

//-----------------------------------------------------------------------------

XPopup.goShowPopup = function(
   controlId,
   popupId
)
{

   var popup = XControl.controls[controlId];
   if (popup && !popup.isVisible() && popup.nextPopup)
   {
      if (popupId == popup.nextPopup.popupId)
      {
         var contentId = popup.nextPopup.contentId;
         var x = popup.nextPopup.x;
         var y = popup.nextPopup.y;
         var popupHTML = (popup.nextPopup.popupFn) ? popup.nextPopup.popupFn(contentId,x,y) : popup.nextPopup.popupHTML;

         if (popupHTML)
         {
            var width = (popup.nextPopup.width != null) ? popup.nextPopup.width : popupHTML.width;
            var height = (popup.nextPopup.height != null) ? popup.nextPopup.height : popupHTML.height;
            if (width != null || height != null)
               popup.setDimensions(width, height, XControl.APPLY);
            var xPos = (popupHTML.xPos != null) ? popupHTML.xPos : x+popup.getXOffset();
            var yPos = (popupHTML.yPos != null) ? popupHTML.yPos : y+popup.getYOffset();
            popup.setPosition((xPos > 0) ? xPos : 0, yPos);
            popup.setContent(popupHTML);
            popup.show();
         }
      }
   }

}

//-----------------------------------------------------------------------------

XPopup.showPopup = function(
   controlId,
   contentId,
   popupFnOrHTML,
   x,
   y,
   width,
   height
)
{
   contentId = (contentId == null) ? null : contentId;
   popupFnOrHTML = (popupFnOrHTML == null) ? null : popupFnOrHTML;
   x = (x == null) ? 0 : x;
   y = (y == null) ? 0 : y;
   width = (width == null) ? null : width;
   height = (height == null) ? null : height;

   var popup = XControl.controls[controlId];
   if (popup && popupFnOrHTML)
   {
      popup.nextPopup = new Array();
      popup.nextPopup.contentId = contentId;
      popup.nextPopup.popupId = (contentId) ? contentId : XUtils.generateId();
      popup.nextPopup.popupFn = (typeof(popupFnOrHTML) == "function") ? popupFnOrHTML : null;
      popup.nextPopup.popupHTML = (typeof(popupFnOrHTML) == "string") ? popupFnOrHTML : null;
      popup.nextPopup.x = x;
      popup.nextPopup.y = y;
      popup.nextPopup.width = width;
      popup.nextPopup.height = height;
      setTimeout("XPopup.goShowPopup(\"" + controlId + "\", \"" + popup.nextPopup.popupId + "\")",XPopup.POPUP_DELAY);
   }

}

//-----------------------------------------------------------------------------

XPopup.hidePopup = function(
   controlId
)
{

   var popup = XControl.controls[controlId];
   if (popup)
   {
      if (popup.nextPopup)
         popup.nextPopup.popupId = null;
      popup.hide();
   }

}

//-----------------------------------------------------------------------------

XPopup.sortMenuItems = function(
   menuItem1,
   menuItem2
)
{

   return (menuItem1.text > menuItem2.text) ? 1 : (menuItem1.text < menuItem2.text) ? -1 : 0;
}

//=============================================================================
// Event Handlers

XPopup.prototype.onMenuItemMouseEnter = null;
XPopup.prototype.onMenuItemMouseOver = null;
XPopup.prototype.onMenuItemMouseOut = null;
XPopup.prototype.onMenuItemMouseLeave = null;
XPopup.prototype.onMenuItemClick = null;

//-----------------------------------------------------------------------------

XPopup.prototype.doMenuItemMouseEnter = function(
   event,
   index
)
{
   event = (event == null) ? window.event : event;
   index = (index == null) ? -1 : index;

   var spec = this.valueOf();

   try
   {
      spec.mouseIn = true;

      var menuItemNode = $(spec.id + ".menuItem" + index);
      if (menuItemNode)
      {
         menuItemNode.focus();

         if (XApp.isBrowser("Safari")) // Events are not calling correctly
            this.doFocus(event, index);
      }

      if (this.onMenuItemMouseEnter)
         this.onMenuItemMouseEnter(this, index);
   }
   catch (error)
   {
      XApp.logEvent(XApp.EVENT_ERROR, error);
      XMsg.alert(error);
   }

}

//-----------------------------------------------------------------------------

XPopup.prototype.doMenuItemMouseOver = function(
   event,
   index
)
{
   event = (event == null) ? window.event : event;
   index = (index == null) ? -1 : index;

   var spec = this.valueOf();

   try
   {
      this.doMenuItemMouseEnter(event, index);

      spec.mouseOut = false;

      if (this.onMenuItemMouseOver)
         this.onMenuItemMouseOver(this, index);
   }
   catch (error)
   {
      XApp.logEvent(XApp.EVENT_ERROR, error);
      XMsg.alert(error);
   }

}

//-----------------------------------------------------------------------------

XPopup.prototype.doMenuItemMouseOut = function(
   event,
   index
)
{
   event = (event == null) ? window.event : event;
   index = (index == null) ? -1 : index;

   var spec = this.valueOf();

   try
   {
      spec.mouseOut = true;

      setTimeout("XControl.controls['" + spec.id + "'].doMenuItemMouseLeave(null," + index + ")", 100);

      if (this.onMenuItemMouseOut)
         this.onMenuItemMouseOut(this, index);
   }
   catch (error)
   {
      XApp.logEvent(XApp.EVENT_ERROR, error);
      XMsg.alert(error);
   }

}

//-----------------------------------------------------------------------------

XPopup.prototype.doMenuItemMouseLeave = function(
   event,
   index
)
{
   event = (event == null) ? window.event : event;
   index = (index == null) ? -1 : index;

   var spec = this.valueOf();

   try
   {
      if (spec.mouseOut == false)
         return;

      spec.mouseIn = false;
   }
   catch (error)
   {
      XApp.logEvent(XApp.EVENT_ERROR, error);
      XMsg.alert(error);
   }

   if (this.onMenuItemMouseLeave)
      this.onMenuItemMouseLeave(this, index);

}

//-----------------------------------------------------------------------------

XPopup.prototype.doFocus = function(
   event,
   index
)
{
   event = (event == null) ? window.event : event;

   var spec = this.valueOf();

   if (spec.activeMenuItemIndex != null)
      this.doBlur(event, spec.activeMenuItemIndex);

   try
   {
      var menuItemNode = $(spec.id + ".menuItem" + index);
      if (menuItemNode)
      {
         menuItemNode.focus();
         menuItemNode.className = menuItemNode.className.replace(/-Highlight/, "") + "-Highlight";
         spec.activeMenuItemIndex = index;
      }
   }
   catch (error)
   {
      XApp.logEvent(XApp.EVENT_ERROR, error);
      XMsg.alert(error);
   }

}

//-----------------------------------------------------------------------------

XPopup.prototype.doBlur = function(
   event,
   index
)
{
   event = (event == null) ? window.event : event;

   var spec = this.valueOf();

   try
   {
      var menuItemNode = $(spec.id + ".menuItem" + index);
      if (menuItemNode)
      {
         menuItemNode.className = menuItemNode.className.replace(/-Highlight/, "");
         spec.activeMenuItemIndex = null;
      }
   }
   catch (error)
   {
      XApp.logEvent(XApp.EVENT_ERROR, error);
      XMsg.alert(error);
   }

}

//-----------------------------------------------------------------------------

XPopup.prototype.doKeyDown = function(
   event,
   index
)
{
   event = (event == null) ? window.event : event;
   index = (index == null) ? 0 : index;

   var spec = this.valueOf();

   try
   {
      var keyCode = event.keyCode;
      switch (keyCode)
      {
         case 13: // EnterKey
            this.doMenuItemClick(event, index);
            break;
         case 38: // Up Arrow
            if (index > 0)
            {
               this.doBlur(event, index);
               this.doFocus(event, index-1);
            }
            break;
         case 40: // Down Arrow
            if (this.menuItems)
            {
               if (index < this.menuItems.length-1)
               {
                  this.doBlur(event, index);
                  this.doFocus(event, index+1);
               }
            }
            break;
      }
   }
   catch (error)
   {
      XApp.logEvent(XApp.EVENT_ERROR, error);
      XMsg.alert(error);
   }

}

//-----------------------------------------------------------------------------

XPopup.prototype.doMenuItemClick = function(
   event,
   index
)
{
   event = (event == null) ? window.event : event;
   index = (index == null) ? -1 : index;

   var spec = this.valueOf();

   try
   {
      this.hide(XPopup.HIDE_FORCE);

      // Note: Do this via a setTimeout to allow the menu to hide before the click
      //       event starts

      if (this.onMenuItemClick)
      {
         if (!spec.asynch)
            XControl.controls[spec.id].onMenuItemClick(XControl.controls[spec.id], index);
         else
            setTimeout("XControl.controls['" + spec.id + "'].onMenuItemClick(XControl.controls['" + spec.id + "'], " + index + ")", 100);
      }
   }
   catch (error)
   {
      XApp.logEvent(XApp.EVENT_ERROR, error);
      XMsg.alert(error);
   }

}

//-----------------------------------------------------------------------------

XPopup.prototype.goHide = function(
   force
)
{
   force = (force == null) ? false : force;

   try
   {
      this.hide(force)
   }
   catch (error)
   {
      XApp.logEvent(XApp.EVENT_ERROR, error);
      XMsg.alert(error);
   }
}

//=============================================================================
// Public Interface

XPopup.prototype.content = null;
XPopup.prototype.menuItems = [];

//-----------------------------------------------------------------------------

XPopup.prototype.setClass = function(
   className
)
{
   className = (className == null) ? "XPopup" : className;

   var spec = this.valueOf();
   spec.className = className;

   return className;
}

//-----------------------------------------------------------------------------

XPopup.prototype.setContent = function(
   content
)
{
   content = (content == null) ? this.content : content;

   var spec = this.valueOf();

   this.content = content;

   var contentNode = $(spec.id + ".content");
   if (contentNode && content)
      contentNode.innerHTML = (content != null) ? ((typeof(content) == "function") ? content() : content) : "";

}

//-----------------------------------------------------------------------------

XPopup.prototype.setContentClassName = function(
   contentClassName
)
{
   contentClassName = (contentClassName == null) ? null : contentClassName;

   var spec = this.valueOf();
   spec.contentClassName = contentClassName;

   return contentClassName;
}

//-----------------------------------------------------------------------------

XPopup.prototype.setAsynch = function(
   asynch
)
{
   asynch = (asynch == null) ? true : asynch;

   var spec = this.valueOf();
   spec.asynch = asynch;

   return asynch;
}

//-----------------------------------------------------------------------------

XPopup.prototype.setOffsets = function(
   xOffset,
   yOffset
)
{
   xOffset = (xOffset == null) ? -66 : xOffset;
   yOffset = (yOffset == null) ? 20 : yOffset;

   var spec = this.valueOf();

   spec.xOffset = xOffset;
   spec.yOffset = yOffset;

}

//-----------------------------------------------------------------------------

XPopup.prototype.getXOffset = function()
{

   var spec = this.valueOf();


   return spec.xOffset;
}

//-----------------------------------------------------------------------------

XPopup.prototype.getYOffset = function()
{

   var spec = this.valueOf();

   return spec.yOffset;
}

//-----------------------------------------------------------------------------

XPopup.prototype.show = function()
{

   var spec = XControl.getSpecFrom(this.valueOf());

   if (XPopup.activePopup)
   {
      XPopup.activePopup.hide(XPopup.HIDE_FORCE);
      XPopup.activePopup = null;
   }

   spec.visible = true;

   if (spec.htmlNode)
   {
      XUI(spec.htmlNode).setRuntimeStyle("display", "block");

      XPopup.activePopup = this;

      var shadowXUI = XUI(spec.id + ".shadow");
      var contentXUI = XUI(spec.id + ".content");
      if (contentXUI.exists())
      {
         if (spec.htmlNode.clientWidth != contentXUI.valueOf().clientWidth)
            contentXUI.setRuntimeStyle("width", XUtils.dimText(spec.htmlNode.clientWidth - spec.shadowSize));
         if (spec.htmlNode.clientHeight != contentXUI.valueOf().clientHeight)
            contentXUI.setRuntimeStyle("height", XUtils.dimText(spec.htmlNode.clientHeight - spec.shadowSize));
      }
      if (shadowXUI.exists() && contentXUI.exists())
      {
         shadowXUI.setRuntimeStyle("top", XUtils.dimText(spec.shadowSize));
         shadowXUI.setRuntimeStyle("left", XUtils.dimText(spec.shadowSize));
         shadowXUI.setRuntimeStyle("width", XUtils.dimText(contentXUI.valueOf().clientWidth));
         shadowXUI.setRuntimeStyle("height", XUtils.dimText(contentXUI.valueOf().clientHeight));
      }

      var firstMenuItem = $(spec.id + ".menuItem0");
      if (firstMenuItem)
         firstMenuItem.focus();
   }

   if (this.onShow)
      this.onShow(this);

   return spec.htmlNode;
}

//-----------------------------------------------------------------------------

XPopup.prototype.hide = function(
   force
)
{
   force = (force == null) ? false : force;

   var spec = this.valueOf();

   if (force == XPopup.HIDE_FORCE || !spec.mouseIn)
   {
      spec.visible = false;

      if (spec.htmlNode)
      {
         XUI(spec.htmlNode).setRuntimeStyle("display", "none");

         XPopup.activePopup = null;
      }

      if (this.onHide)
         this.onHide(this);
   }

   return spec.htmlNode;

}

//-----------------------------------------------------------------------------

XPopup.prototype.toHTML = function(
   state
)
{
   state = (state == null) ? [] : state;

   var menuItemHeight = 20;

   var spec = this.valueOf();

   var controlHTML = "";

   if (this.menuItems && this.menuItems.length > 0)
      spec.height = (menuItemHeight + ((XApp.isBrowser("MSIE",null,7.0) && this.getQuirksMode()) ? 0 : 3)) * this.menuItems.length;

   controlHTML += "<div " +
      "id=\"" + spec.id + "\" " +
      "class=\"" + spec.className + " Popup Control\" " +
      "style=\"" +
         "display: " + ((spec.visible) ? "block" : "none" ) + "; " +
         "left: " + XUtils.dimText(spec.left) + "; " +
         "top: " + XUtils.dimText(spec.top) + "; " +
         ((spec.width) ? "width: " + XUtils.dimText(spec.width + spec.shadowSize) + "; " : "") +
         ((spec.height) ? "height: " + XUtils.dimText(spec.height + spec.shadowSize) + "; " : "") +
      "\" " +
      ((XApp.isBrowser("MSIE")) ? "onmouseenter=\"XControl.controls['" + spec.id + "'].doMouseEnter(event)\" " : "") +
      ((!XApp.isBrowser("MSIE")) ? "onmouseover=\"XControl.controls['" + spec.id + "'].doMouseOver(event)\" " : "") +
      ((!XApp.isBrowser("MSIE")) ? "onmouseout=\"XControl.controls['" + spec.id + "'].doMouseOut(event)\" " : "") +
      ((XApp.isBrowser("MSIE")) ? "onmouseleave=\"XControl.controls['" + spec.id + "'].doMouseLeave(event)\" " : "") +
      "onclick=\"XControl.controls['" + spec.id + "'].doClick(event)\" " +
   ">";

   // Workaround for the IE6 Select/Z-Order bug
   if (XApp.isBrowser("MSIE",6.0,6.0))
   {
      controlHTML += "<iframe " +
         "id=\"" + spec.id + ".mask\" " +
         "class=\"" + spec.className + "Mask\" " +
         "style=\"" +
            ((spec.width) ? "width: " + XUtils.dimText(spec.width + spec.shadowSize) + "; " : "") +
            ((spec.height) ? "height: " + XUtils.dimText(spec.height + spec.shadowSize) + "; " : "") +
         "\" " +
         "frameborder=\"no\" " +
         "scrolling=\"no\" " +
      ">";
      controlHTML += "</iframe>";
   }

      controlHTML += "<div " +
         "id=\"" + spec.id + ".shadow\" " +
         "class=\"" + spec.className + "Shadow\" " +
         "style=\"" +
            "left: " + spec.shadowSize + "; " +
            "top: " + spec.shadowSize + "; " +
            ((spec.width) ? "width: " + XUtils.dimText(spec.width) + "; " : "") +
            ((spec.height) ? "height: " + XUtils.dimText(spec.height) + "; " : "") +
         "\" " +
      ">&#160;</div>";

      controlHTML += "<div " +
         "id=\"" + spec.id + ".content\" " +
         "class=\"" + spec.className + "Content Content" + ((spec.contentClassName) ? " " + spec.contentClassName : "") + " Background1\" " +
         "style=\"" +
            ((spec.width) ? "width: " + XUtils.dimText(spec.width) + "; " : "") +
            ((spec.height) ? "height: " + XUtils.dimText(spec.height) + "; " : "") +
         "\" " +
      ">";

      if (this.content)
      {
         controlHTML += (typeof(this.content) == "function") ? this.content() : this.content;
      }
      else if (this.menuItems)
      {
         for (var i=0; i<this.menuItems.length; i++)
         {
            var menuItem = this.menuItems[i];
            if (menuItem.type == "Separator")
            {
               controlHTML += "<div " +
                  "id=\"" + spec.id + ".menuItem" + i + "\" " +
                  "class=\"" + spec.className + "MenuItem Hotspot" + "\" " +
                  "style=\"" +
                       "height: " + menuItemHeight + "px; " +
                  "\" " +
               ">";
                  controlHTML += "<hr/>";
               controlHTML += "</div>";
            }
            else
            {
               var menuItemDisabled = (menuItem.disabled == true);
               controlHTML += "<div " +
                  "id=\"" + spec.id + ".menuItem" + i + "\" " +
                  "class=\"" + spec.className + ((menuItemDisabled) ? "MenuItem-Disabled HotSpot-Disabled" : "MenuItem HotSpot") + "\" " +
                  "style=\"" +
                       "height: " + menuItemHeight + "px; " +
                  "\" " +
                  ((XApp.isBrowser("MSIE")) ? "onmouseenter=\"XControl.controls['" + spec.id + "'].doMenuItemMouseEnter(event," + i +")\" " : "") +
                  ((!XApp.isBrowser("MSIE")) ? "onmouseover=\"XControl.controls['" + spec.id + "'].doMenuItemMouseOver(event," + i +")\" " : "") +
                  ((!XApp.isBrowser("MSIE")) ? "onmouseout=\"XControl.controls['" + spec.id + "'].doMenuItemMouseOut(event," + i +")\" " : "") +
                  ((XApp.isBrowser("MSIE")) ? "onmouseleave=\"XControl.controls['" + spec.id + "'].doMenuItemMouseLeave(event," + i +")\" " : "") +
                  ((!menuItemDisabled) ?
                     "tabindex=\"" + (spec.tabIndex + i) + "\" " +
                     "onfocus=\"XControl.controls['" + spec.id + "'].doFocus(event," + i + ")\" " +
                     "onblur=\"XControl.controls['" + spec.id + "'].doBlur(event," + i + ")\" " +
                     "onkeydown=\"XControl.controls['" + spec.id + "'].doKeyDown(event," + i + ")\" " +
                     "onclick=\"XControl.controls['" + spec.id + "'].doMenuItemClick(event," + i + ")\" "
                     :
                     "") +
               ">";
                  if (menuItem.img)
                     controlHTML += "<img class=\"" + spec.className + "MenuItemImage\" src=\"" + menuItem.img + "\"/>";
                  else
                     controlHTML += "<img class=\"" + spec.className + "MenuItemImage\" src=\"/app/pkgs/xfw/images/Blank.gif\"/>";
                  controlHTML += menuItem.text;
               controlHTML += "</div>";
            }
         }
      }

      controlHTML += "</div>";

   controlHTML += "</div>";

   return controlHTML;
}

//=============================================================================
