﻿//Dialog window:
//   {header: 'html markup', body: 'html markup', footer: 'html markup', cls: 'className', widthpct: 75, heightpct: 50, onShow: function(dlg){}, onClose: function(dlg, result){return true;}}
published.Dialog = function(init)
{
  if (!WAVE.isObject(init)) init = {};

  var dialog = this,
      fOnShow = WAVE.isFunction(init.onShow) ? init.onShow : function(){},
      fOnClose = WAVE.isFunction(init.onClose) ? init.onClose : function(){ return true;},
      fCloseOnClickOutside = WAVE.strAsBool(init.closeOnClickOutside, false),
      fCloseOnEscape = WAVE.strAsBool(init.closeOnEscape, true),
      fWidthPct = WAVE.intValidPositive(init.widthpct) ? init.widthpct : 0,
      fHeightPct = WAVE.intValidPositive(init.heightpct) ? init.heightpct : 0,
      fPreventScroll = WAVE.strAsBool(init.preventScroll, true),
      headCtn = init.header,
      bodyCtn = init.body,
      footerCtn = init.footer,
      fdivBase = null,
      fdivContent = null,
      fdivHeader = null,
      fdivBody = null,
      fdivFooter = null;

  WAVE.extend(dialog, WAVE.EventManager);

  if (fWidthPct>100) fWidthPct = 100;
  if (fHeightPct>100) fHeightPct = 100;

  function appendContent(el, ctn, dfl) {
    if (WAVE.isObject(ctn)) el.appendChild(ctn);
    else el.innerHTML = WAVE.strDefault(ctn, dfl);
  }

  fdivBase = document.createElement("div");
  fdivBase.__DIALOG = this;
  fdivBase.className = published.CLS_DIALOG_BASE + ' ' + WAVE.strDefault(init['cls']);
  fdivBase.style.position = "fixed";
  fdivBase.style.zIndex = CURTAIN_ZORDER + fCurtains.length;

  document.body.appendChild(fdivBase);

  fCurtains.push(fdivBase);

  fdivContent = document.createElement("div");
  fdivContent.className = published.CLS_DIALOG_CONTENT;
  fdivBase.appendChild(fdivContent);

  fdivHeader = document.createElement("div");
  fdivHeader.className = published.CLS_DIALOG_HEADER;
  appendContent(fdivHeader, headCtn, "Dialog");
  fdivContent.appendChild(fdivHeader);

  fdivBody = document.createElement("div");
  fdivBody.className = published.CLS_DIALOG_BODY;
  appendContent(fdivBody, bodyCtn, "");
  fdivContent.appendChild(fdivBody);

  fdivFooter = document.createElement("div");
  fdivFooter.className = published.CLS_DIALOG_FOOTER;
  appendContent(fdivFooter, footerCtn, "");
  fdivContent.appendChild(fdivFooter);

  function __adjustBounds(){
    if (fWidthPct === 0 && fHeightPct === 0)
      return;

    var sw = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth;
    var sh = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight;
    var cx = sw / 2;
    var cy = sh / 2;

    var w = fWidthPct === 0 ? fdivContent.offsetWidth : Math.round( sw * (fWidthPct/100));
    var h = fHeightPct === 0 ? fdivContent.offsetHeight : Math.round( sh * (fHeightPct/100));
    fdivContent.style.width  = fWidthPct === 0  ? "auto" : w + "px";

    fdivContent.style.left = Math.round(cx - (fdivContent.offsetWidth / 2)) + "px";
    var top = Math.round(cy - (fdivContent.offsetHeight / 2));
    if (top < 0) top = 0;

    fdivContent.style.top = top + "px";

    fdivContent.style.width  = fWidthPct===0  ? "auto" : w - (fdivContent.offsetLeft*2) + "px";
    fdivContent.style.height = fWidthPct===0  ?
                                "auto" :
                                (h - (fdivContent.offsetTop + fdivContent.offsetLeft) + "px");//todo This may need to be put as published.OFFSETY that depends on style
  }

  function outsideClickHandler(e) {
    var target = e.target;
    if (!WAVE.isParentOf(fdivContent, target))
      dialog.close();
  }

  function buttonPressHandler(e) {
    var keyCode = e.keyCode;
    if (keyCode === 27) {
      var dlg = published.currentDialog();
      if (!dlg || dlg !== dialog) return;
      dialog.close();
    }
  }

  function show() {
    if (fCloseOnClickOutside) {
      setTimeout(function() {
        WAVE.addEventHandler(window, "click", outsideClickHandler);
      }, 1);
    }

    if (fCloseOnEscape)
      WAVE.addEventHandler(window, "keyup", buttonPressHandler);

    fOnShow(dialog);
  }

  var tmr = null;
  function __resizeEventHandler() {
    if (tmr) clearTimeout(tmr);//prevent unnecessary adjustments when too many resizes happen
    tmr = setTimeout(function(){  __adjustBounds(); tmr = null; }, 500);
  }

  var fResult = published.DLG_UNDEFINED;

  //returns dialog result or DLG_UNDEFINED
  this.result = function(){ return fResult; };

  // turn on/off CloseOnClickOutside option
  this.closeOnClickOutside = function (val) {
    if (typeof (val) === WAVE.TUNDEFINED || val === null) return fCloseOnClickOutside;
    fCloseOnClickOutside = val === true;
    if (fCloseOnClickOutside)
      setTimeout(function () { WAVE.addEventHandler(window, "click", outsideClickHandler) }, 1);
    else {
      WAVE.removeEventHandler(window, "click", outsideClickHandler);
    }
    return fCloseOnClickOutside;
  }

  //closes dialog with the specified result and returns the result
  this.close = function(result){
    if (typeof (result) === tUNDEFINED) result = published.DLG_CANCEL;
    if (fResult!==published.DLG_UNDEFINED) return fResult;
    if (!fOnClose(this, result)) return published.DLG_UNDEFINED;//aka CloseQuery

    fResult = result;

    document.body.removeChild(fdivBase);
    WAVE.arrayDelete(fCurtains, fdivBase);
    WAVE.removeEventHandler(window, "resize", __resizeEventHandler);
    if (fPreventScroll)
      tryRetrunScrollingToBody();

    if (fCloseOnClickOutside)
      WAVE.removeEventHandler(window, "click", outsideClickHandler);

    if (fCloseOnEscape)
      WAVE.removeEventHandler(window, "keyup", buttonPressHandler);

    fdivBase.__DIALOG = null;
    fdivBase = null,
    fdivContent = null;
    fdivHeader = null;
    fdivBody = null;
    fdivFooter = null;
    fOnClose = null;
    fOnShow = null;
    dialog = null;

    this.eventInvoke(published.EVT_DIALOG_CLOSE, result);

    return result;
  };

  //closes dialog with OK result
  this.ok = function(){ this.close(published.DLG_OK); };

  //closes dialog with CANCEL result
  this.cancel = function(){ this.close(published.DLG_CANCEL); };

  //get/set title
  this.title = function(val){
    if (typeof(val)===tUNDEFINED || val===null) return fdivHeader.innerHTML;
    fdivHeader.innerHTML = val;
    __adjustBounds();
  };

  //get/set content
  this.content = function(val){
    if (typeof(val)===tUNDEFINED || val===null) return fdivBody.innerHTML;
    $(fdivBody).html( val );
    __adjustBounds();
  };

  this.baseDIV = function() { return fdivBase; };
  this.headerDIV = function() { return fdivHeader; };
  this.bodyDIV = function() { return fdivBody; };
  this.footerDIV = function() { return fdivFooter; };

  //gets/sets width in screen size pct 0..100, where 0 = auto
  this.widthpct = function(val){
    if (typeof(val)===tUNDEFINED || val===fWidthPct) return fWidthPct;
    fWidthPct = val;
    __adjustBounds();
  };

  //gets/sets height in screen size pct 0..100, where 0 = auto
  this.widthpct = function(val){
    if (typeof(val)===tUNDEFINED || val===fHeightPct) return fHeightPct;
    fHeightPct = val;
    __adjustBounds();
  };

  this.adjustBounds = function() { __adjustBounds(); };

  WAVE.addEventHandler(window, "resize", __resizeEventHandler);
  show();

  __adjustBounds();
  if (fPreventScroll)
    tryMakeBodyUnscrollable();

  return dialog;
};//dialog

//Displays a simple confirmation propmt dialog
published.showConfirmationDialog = function (title, content, buttons, callback, options) {
  if (!WAVE.isObject(options)) options = {};
  if (!WAVE.isArray(buttons)) buttons = [];

  content = WAVE.strDefault(content, 'Please confirm');
  var btnCls = WAVE.strDefault(options['btnCls']);
  var footerCls = WAVE.strDefault(options['footerCls']);

  function createButtonHtml(lbl, rslt) {
      var btnTemplate = '<button class="@btnClass@" onclick="WAVE.GUI.currentDialog().close(\'@result@\');">@label@</button>';
      return WAVE.strHTMLTemplate(
                                  btnTemplate,
                                  {
                                    btnClass: published.CLS_DIALOG_CONFIRM_BUTTON + ' ' + btnCls,
                                    result: rslt,
                                    label: lbl
                                  });
  }

  var btnYes = '';
  var btnNo = '';
  var btnOk = '';
  var btnCancel = '';

  if (WAVE.inArray(buttons, published.DLG_YES))
      btnYes = createButtonHtml('Yes', published.DLG_YES);
  if (WAVE.inArray(buttons, published.DLG_NO))
      btnNo = createButtonHtml('No', published.DLG_NO);
  if (WAVE.inArray(buttons, published.DLG_OK))
      btnOk = createButtonHtml('OK', published.DLG_OK);
  if (WAVE.inArray(buttons, published.DLG_CANCEL))
      btnCancel = createButtonHtml('Cancel', published.DLG_CANCEL);

  var fullContent = '<div>' + content + '<div>';

  var divButtons = '<div class="' + published.CLS_DIALOG_CONFIRM_FOOTER + ' ' + footerCls + '">' +
                      btnYes + btnNo + btnOk + btnCancel +
                    '</div>';

  var dialog = new published.Dialog({
    header: WAVE.strDefault(title, 'Confirmation'),
    body: fullContent,
    footer: divButtons,
    cls: WAVE.strDefault(options['cls']),
    onShow: function(dlg){},
    onClose: callback
  });
};

//Returns currently active dialog or null
published.currentDialog = function () {
  for (var i = fCurtains.length - 1; i >= 0; i--)
    if (typeof (fCurtains[i].__DIALOG) !== tUNDEFINED) return fCurtains[i].__DIALOG;
  return null;
};