/*-------------------------------------------------------------------------
* $Id$
* This file is supposed to work around with dialog.
* AUTHOR : Tran Hoang Chuong
* DEPENDENCIES :
* - cg_shared.js : A common file to work with internet browser.
* - Common.js : A common file for common APIs.
* - CatDialog.js : Library of CatGlobe Dialog.
* - virtualAppHost : A global variable standing for ASP.NET virtual application path.
-------------------------------------------------------------------------*/
ICON_YES = "yes.gif";
ICON_NO = "no.gif";
/*-------------------------------------------------------------------------
* Opens a popup dialog
*
* @param strUrl : Page will be loaded.
* @param blnModal : Specifies whether modal or modaless dialog.
* Returns a dialog object.
* Example usage : N/A
--------------------------------------------------------------------------*/
function openDialog(reserved, strUrl, blnModal)
{
 var height = (cg_shared.IsIE) ? window.document.body.offsetHeight - 50 : window.document.body.clientHeight - 50;
   var width = (cg_shared.IsIE) ? window.document.body.offsetWidth - 50 : window.document.body.clientWidth - 50;
   var tempDialog = new CatDialog(window, '', null, null, '', width, height, virtualAppHost + 'Images/Common/CatDialog', 'SteelBlue2_', 'SteelBlue', 'Transparent', null, '', '', false, blnModal, false, true, true, false, false, false, false, false, true, true, true, false, -1);
   tempDialog.setUrl(strUrl);
   tempDialog.destroyOnHide = true;
   tempDialog.setSize(width, height);
   tempDialog.moveCenter();
   tempDialog.show(true);
   return tempDialog;
}

/*-------------------------------------------------------------------------
* Builds style sheets and javascript files which are used in alert and confirm dialog
*
* @param innerDocument : the instance of document of window inside dialog.
* Returns : N/A.
* Example usage : N/A
--------------------------------------------------------------------------*/
function buildBasicHtml(innerDocument) {
 innerDocument.write("<!DOCTYPE html><html><head>" +
  "<link rel='stylesheet' type='text/css' href='" + virtualAppHost + "Styles/CatglobeEx.css'>" +
  "<script type='text/javascript'>var virtualAppHost = '" + virtualAppHost + "'; </script>" +
  "</head><body></body></html>");
 var innerBody = innerDocument.getElementsByTagName("body")[0];
 innerBody.style.overflow = "hidden";
 innerBody.style.margin = "2mm";
}

function appendLinks(innerDocument, callback) {
 var loader = function(src, handler) {
  var script = innerDocument.createElement("script");
  script.src = src;
  script.onload = script.onreadystatechange = function() {
   script.onreadystatechange = script.onload = null;
   setTimeout(handler, 0);
  };
  var head = innerDocument.getElementsByTagName("head")[0];
  (head || innerDocument.body).appendChild(script);
 };
 var array = [virtualAppHost + "Script/Common/PopupCommon.min.js"];
 (function() {
  if (array.length != 0) {
   loader(array.shift(), arguments.callee);
  } else {
   callback && callback();
  }
 })();
}

/*-------------------------------------------------------------------------
* Shows an error message
*
* @param strTitle : Title of alert dialog.
* @param strMessage : The content needs to be informed.
* @param callback : The function preference which will be call when user clicks on OK button.
* Returns : a dialog object.
* Example usage : N/A
--------------------------------------------------------------------------*/
function cgError(strTitle, strMessage, callback)
{
 var message = "<span style='color:red;'>" + strMessage + "</span>";
   cgAlert(strTitle, message, callback);
}

/*-------------------------------------------------------------------------
* Shows an alert message
*
* @param strTitle : Title of alert dialog.
* @param strMessage : The content needs to be informed.
* @param callback : The function preference which will be call when user clicks on OK button.
* Returns : a dialog object.
* Example usage : N/A
--------------------------------------------------------------------------*/
function cgAlert(strTitle, strMessage, callback)
{
   var dlgAlert = getCenterWindow().openDialog(null, "about:blank", true);
   var _DLGID = (new Date).getTime();
   dlgAlert.papa = window;
   dlgAlert.setIdEx(_DLGID);
   dlgAlert.setTitle(strTitle, true);
   dlgAlert.ForMessage = true;
   dlgAlert.setSize(5, 5);
   dlgAlert.moveCenter();
   dlgAlert.autoFitSize(null, null, true);
   dlgAlert.allowCloseButton(false);
   dlgAlert.allowMinButton(false);
   dlgAlert.allowMaxButton(false);
   dlgAlert.showResizeIcon(false);
   var innerDocument = dlgAlert.getInnerWindow().document;
   buildBasicHtml(innerDocument);

   var table = innerDocument.createElement("table");
   innerDocument.body.appendChild(table);

   var tbody = innerDocument.createElement("tbody");
   table.appendChild(tbody);
   var row = innerDocument.createElement("tr");
   tbody.appendChild(row);
   var cell = innerDocument.createElement("td");
   row.appendChild(cell);

   var nobreak = innerDocument.createElement("nobr");

   var messageSpan = innerDocument.createElement("SPAN");
   messageSpan.innerHTML = strMessage;
   messageSpan.id = "msg";
   nobreak.appendChild(messageSpan);
   innerDocument.body.appendChild(nobreak);

   var content = nobreak;
   var contentWidth = nobreak.offsetWidth; //this line is usefull to make browser calculate the width of content
   if (contentWidth >= (window.screen.availWidth / 2))
   {
      innerDocument.body.removeChild(nobreak);
      innerDocument.body.appendChild(table);
      content = cell;
      cell.appendChild(messageSpan);
      table.width = (window.screen.availWidth / 2);
   }

   var buttonPara = innerDocument.createElement("P");
   buttonPara.setAttribute("align", "center");
   content.appendChild(buttonPara);

   var alertButton = new ConfirmButton("okButton", "OK", "ok", ICON_YES, callback); alertButton.DLGID = _DLGID;
 appendLinks(innerDocument, function() {
  buttonPara.appendChild(alertButton.render(innerDocument));
  adjustAutoFitness(dlgAlert);
 });

 return dlgAlert;
}

/*-------------------------------------------------------------------------
* Resizes dialog to fit with its content
--------------------------------------------------------------------------*/
function adjustAutoFitness(dlg) {
 var innerDocument = dlg.getInnerWindow().document;
 dlg.getInnerWindow().focus();
 dlg.setSize(innerDocument.documentElement.scrollWidth + 15, innerDocument.documentElement.scrollHeight + 33);
 //32px = the height of Top + bottom bar
 //add 1 more pixel to make the text inside not be scrolled in some special cases that the dialog has button (max, min, restore, close)
 dlg.moveCenter();
}

/*-------------------------------------------------------------------------
* Shows an confirm dialog which enable to add more button into it
*
* @param strTitle : Title of confirm dialog.
* @param strMessage : The content needs to be informed.
* @params user-defined buttons.
* Returns : a dialog object.
* Example usage : N/A
--------------------------------------------------------------------------*/
function cgConfirm(strTitle, strMessage, callback /*user-defined buttons*/)
{
   var dlgConfirm = getCenterWindow().openDialog(null, "about:blank", true);
   var _DLGID = (new Date).getTime();
   dlgConfirm.papa = window;
   dlgConfirm.setIdEx(_DLGID);
   dlgConfirm.setTitle(strTitle, true);
   dlgConfirm.setSize(5, 5);
   dlgConfirm.moveCenter();
   dlgConfirm.autoFitSize();
   dlgConfirm.allowCloseButton(false);
   dlgConfirm.allowMinButton(false);
   dlgConfirm.allowMaxButton(false);

   //Styles and javaaascript files
   var innerDocument = dlgConfirm.getInnerWindow().document;
   buildBasicHtml(innerDocument);

   var table = innerDocument.createElement("table");
   innerDocument.body.appendChild(table);

   var tbody = innerDocument.createElement("tbody");
   table.appendChild(tbody);
   var row = innerDocument.createElement("tr");
   tbody.appendChild(row);
   var cell = innerDocument.createElement("td");
   row.appendChild(cell);

   var nobreak = innerDocument.createElement("nobr");

   var messageSpan = innerDocument.createElement("SPAN");
   messageSpan.innerHTML = strMessage;
   nobreak.appendChild(messageSpan);
   innerDocument.body.appendChild(nobreak);

   var content = nobreak;
   var contentWidth = nobreak.offsetWidth; //this line is usefull to make browser calculate the width of content
   if (contentWidth >= (window.screen.availWidth / 2))
   {
      innerDocument.body.removeChild(nobreak);
      innerDocument.body.appendChild(table);
      content = cell;
      cell.appendChild(messageSpan);
      table.width = (window.screen.availWidth / 2);
   }

   var buttonPara = innerDocument.createElement("P");
   buttonPara.setAttribute("align", "center");
   content.appendChild(buttonPara);

   var buttons = new Array;
   // collects buttons   
   if (typeof (arguments[2]) == 'function' || typeof (arguments[2]) == 'string')
   {
      var btnConfirmButton = new ConfirmButton("yesButton", "Yes", "yes", ICON_YES, callback);
      buttons[buttons.length] = btnConfirmButton;

      btnConfirmButton = new ConfirmButton("noButton", "No", "no", ICON_NO, callback);
      buttons[buttons.length] = btnConfirmButton;
   }
   else
   {
      if (arguments[2] instanceof ConfirmButton)
      {
         for (var idx = 2; idx < arguments.length; idx++)
            buttons[buttons.length] = arguments[idx];
      }
      else
      {
         for (var idx = 0; idx < arguments[3].length; idx++)
            buttons[buttons.length] = arguments[3][idx];
      }
   }

 appendLinks(innerDocument, function() {
  //buttons
  for (var i = 0; i < buttons.length; i++) {
   var b = buttons[i];
   b.DLGID = _DLGID;
   if (i > 0) {
    var seperate = innerDocument.createElement("span");
    seperate.innerHTML = "&nbsp;";
    buttonPara.appendChild(seperate);
   }
   buttonPara.appendChild(b.render(innerDocument));
  }
  adjustAutoFitness(dlgConfirm);
  buttons = null;
 });

   return dlgConfirm;
}
///////////////////// CONFIRM BUTTON CLASS ////////////////////////////////
/*-------------------------------------------------------------------------
* This class stands for a user-defined button added into the confirm dialog
*
* @param strId : unique id of button.
* @param strCaptionKey : button caption.
* @param strIconFilename : button icon standing in from of button caption.
* Returns : object.
* Example usage : N/A
--------------------------------------------------------------------------*/
function ConfirmButton(strId, strCaptionKey, strKey, strIconFilename, clickHanler)
{
   this.DLGID = "";
   this.Id = strId;
   this.Key = strKey;
   
   var culture;
   if (typeof (window.__cguiculture) != "undefined")
      culture = window.__cguiculture;
   else if (typeof (window.parent) != "undefined" && window.parent && typeof (window.parent.__cguiculture) != "undefined")
      culture = window.parent.__cguiculture;
   else
      culture = Math.random();

   //Culture is not actually respected if you change it. But it makes the url unique to the culture. And thus avoid any caching issues
   this.ImageUrl = virtualAppHost + "Images/GetButtonImage.aspx?cap=" + strCaptionKey + "&icon=/Images/Common/Icons/Plain/" + strIconFilename + "&culture=" + culture;
   this.ImageHoverUrl = virtualAppHost + "Images/GetButtonImage.aspx?cap=" + strCaptionKey + "&icon=/Images/Common/Icons/Shadow/" + strIconFilename + "&culture=" + culture;
   this.ClickEventHandler = clickHanler;

   return this;
}

/*-------------------------------------------------------------------------
* This method generates html content of user-defined button
*
* Returns : outer html string.
* Example usage : N/A
--------------------------------------------------------------------------*/
ConfirmButton.prototype.render = function(doc)
{
   var imageButton = doc.createElement("input");
   imageButton.setAttribute("type", "image");
   imageButton.setAttribute("id", this.Id);
   imageButton.setAttribute("name", this.Id);
   imageButton.setAttribute("src", this.ImageUrl);
   imageButton.setAttribute("border", "0");
   imageButton.setAttribute("language", "javascript");
   imageButton.setAttribute("disableimage", "");
   imageButton.setAttribute("normalimage", this.ImageUrl);
   imageButton.setAttribute("hoverimage", this.ImageHoverUrl);

   if (imageButton.addEventListener)
   {
      imageButton.addEventListener("click", this.click(), false);
      imageButton.addEventListener("mouseleave", this.mouseleave(), false);
      imageButton.addEventListener("mouseenter", this.mouseenter(), false);
      imageButton.addEventListener("keydown", this.keydown(), false);
   }
   else if (imageButton.attachEvent)
   {
      imageButton.attachEvent("onclick", this.click());
      imageButton.attachEvent("onmouseleave", this.mouseleave());
      imageButton.attachEvent("onmouseenter", this.mouseenter());
      imageButton.attachEvent("onkeydown", this.keydown());
   }
   return imageButton;
}

ConfirmButton.prototype.click = function()
{
   var me = this;

   var fncbody = function()
   {
      var dlg = getCenterWindow().findDialog(me.DLGID);
      var parent = dlg.papa;
      dlg.show(false, false, true); //remove alert/ confirm dialog from DialogList.
      if (typeof (fncbody.button.ClickEventHandler) == 'function')
         fncbody.button.ClickEventHandler(fncbody.button.Key);
      else if (typeof (fncbody.button.ClickEventHandler) == 'string')
         parent.eval(fncbody.button.ClickEventHandler + "('" + fncbody.button.Key + "')");
      return false;
   }
   fncbody.button = me;
   return fncbody;
}

ConfirmButton.prototype.keydown = function()
{
   var me = this;
   var fncbody = function(evnt)
   {
      if (evnt.keyCode == 13) //if Enter isp pressed, do the same as Click. Note: should not call fncbody.button.click() ==> failed
      {
         var dlg = getCenterWindow().findDialog(me.DLGID);
         var parent = dlg.papa;
         dlg.show(false);

         //hack to focus on top dialog (fix for case: focus on light search when add existing item to EditAccessGrid)
         var listWin;
         if(parent.top.centerFrame != null) //I faced an issue with alert dlg enter key pressed here
             listWin = parent.top.centerFrame.getDialogList();
         if (listWin != null)
            listWin[listWin.length - 1].getInnerWindow().focus();

         if (typeof (fncbody.button.ClickEventHandler) == 'function')
            fncbody.button.ClickEventHandler(fncbody.button.Key);
         else if (typeof (fncbody.button.ClickEventHandler) == 'string')
            parent.eval(fncbody.button.ClickEventHandler + "('" + fncbody.button.Key + "')");
         return false;
      }
   }
   fncbody.button = me;
   return fncbody;
}

ConfirmButton.prototype.mouseleave = function()
{
   var me = this;

   var fncbody = function(evnt)
   {
      var target = evnt.srcElement || evnt.target;
      target.src = target.getAttribute("normalimage"); ;
   }
   fncbody.button = me;
   return fncbody;
}

ConfirmButton.prototype.mouseenter = function()
{
   var me = this;

   var fncbody = function(evnt)
   {
      var target = evnt.srcElement || evnt.target;
      target.src = target.getAttribute("hoverimage"); ;
   }
   fncbody.button = me;
   return fncbody;
}

function createConfirmButton(strId, strCaptionKey, strKey, strIconFilename, clickHanler)
{
   return new ConfirmButton(strId, strCaptionKey, strKey, strIconFilename, clickHanler);
}
///////////////////// CONFIRM BUTTON CLASS ////////////////////////////////

///////////////////// POPUP MANAGER ///////////////////////////////////////
if (typeof (PopupManager) == 'undefined')
{
   PopupManager = new Array;
   $(document).one("unload", null, PopupManager_Dispose);
}

PopupManager.register = function(alertMethod)
{
   PopupManager[alertMethod.Name] = alertMethod.getBody();
}

function PopupManager_Dispose()
{
   if (PopupManager != null)
   {
      for (var name in PopupManager)
      {
         var method = PopupManager[name];
         if (method && method.method)
         {
            method.method.dispose();
            method.method = null;
            method = null;
            PopupManager[name] = null;
         }
      }
      PopupManager = null;
   }
}

///////////////////// POPUP MANAGER ///////////////////////////////////////

///////////////////// ALERT METHOD ////////////////////////////////////////
function AlertMethod(strName, strTitle, strMessage, fncCallback)
{
   this.Name = strName;
   this.Title = strTitle;
   this.Message = strMessage;
   this.Callback = fncCallback;
}

AlertMethod.prototype.getBody = function()
{
   var me = this;
   var fncBody =
      function()
      {
         return cgAlert(fncBody.method.Title, fncBody.method.Message, fncBody.method.Callback);
      }

   fncBody.method = me;

   return fncBody;
}

AlertMethod.prototype.dispose = function()
{
   this.Callback = null;
}
///////////////////// ALERT METHOD ////////////////////////////////////////

///////////////////// CONFIRM METHOD //////////////////////////////////////
function ConfirmMethod(strName, strTitle, strMessage, fncCallback/*and user-defined buttons*/)
{
   this.Name = strName;
   this.Title = strTitle;
   this.Message = strMessage;
   if (!(arguments[3] instanceof ConfirmButton))
      this.Callback = fncCallback;
   this.CustomButtons = new Array;
   if (arguments[3] instanceof ConfirmButton)
   {
      for (var id = 3; id < arguments.length; id++)
      {
         this.CustomButtons[id - 3] = arguments[id];
      }
   }
}

ConfirmMethod.prototype.getBody = function()
{
   var me = this;
   var fncBody =
      function()
      {
         if (fncBody.method.CustomButtons.length == 0)
            return cgConfirm(fncBody.method.Title, fncBody.method.Message, fncBody.method.Callback);
         return cgConfirm(fncBody.method.Title, fncBody.method.Message, fncBody.method.Callback, fncBody.method.CustomButtons);
      }

   fncBody.method = me;

   return fncBody;
}

ConfirmMethod.prototype.dispose = function()
{
   this.Callback = null;
   this.CustomButtons = null;
}
///////////////////// CONFIRM METHOD //////////////////////////////////////

