﻿/*
  init : {
    DIV: control|Id
    title: text|html
    altTitle: text|html
    titleCtrl: control|id
    content: text|html
    contentCtrl: control|id
    isTitleHtml: bool
    isContentHtml: bool
    mode: swap|modal
    modalTitle: text
    modalCls: css class

    contentUrl: url for ajax
    loadCallback: function(data) { optional returns text }

    showOnClick: bool
    showOnFocus: bool
    hideOnClick: bool
    hideOnFocus: bool
    hideOnTimer: bool
    hideOnScroll: bool
    hideOnResize: bool
    timeout: int
  }
*/
var fDetailsIdSeed = 0;
published.Details = function (init) {
  if (typeof(init) === tUNDEFINED || init === null) throw "Details.ctor(init)";

  var details = this;
  WAVE.extend(details, WAVE.EventManager);

  var fId = "wvDetails_" + fDetailsIdSeed++;
  var fDiv;
  var fTitleControl;
  var fContentControl;
  var fTitle = WAVE.strDefault(init.title);
  var fAltTitle = WAVE.strDefault(init.altTitle, fTitle);
  var fContent = WAVE.strDefault(init.content);

  var fContentUrl = WAVE.strDefault(init.contentUrl);
  var fContentType = WAVE.strDefault(init.contentType);
  var fLoadCallback = WAVE.isFunction(init.loadCallback) ? init.loadCallback : null;

  var fIsTitleHtml = WAVE.strAsBool(init.isTitleHtml, true);
  var fIsContentHtml = WAVE.strAsBool(init.isContentHtml, true);
  var fModalCls = WAVE.strDefault(init.modalCls, published.CLS_DETAILS_MODAL);
  var fModalTitle = "<div class='wvDetailsHeader'>" + WAVE.strDefault(init.modalTitle) + "</div><div class='wvCloseDetails' id='" + fId + "close'></div>";

  var fShowOnClick = WAVE.strAsBool(init.showOnClick, true);
  var fShowOnFocus = WAVE.strAsBool(init.showOnFocus, false);
  var fHideOnTitle = WAVE.strAsBool(init.hideOnTitle, true);
  var fHideOnClick = WAVE.strAsBool(init.hideOnClick, true);
  var fHideOnFocus = WAVE.strAsBool(init.hideOnFocus, false);
  var fHideOnTimer = WAVE.strAsBool(init.hideOnTimer, false);
  var fHideOnScroll = WAVE.strAsBool(init.hideOnScroll, false);
  var fHideOnResize = WAVE.strAsBool(init.hideOnResize, false);

  var fMode = WAVE.strDefault(init.mode, "swap");
  var r = WAVE.tryParseInt(init.timeout);
  var fTimeout = r.ok ? r.value : 0;
  var titleId = fId + "_title";
  var contId = fId + "_content";
  var fDialog = null;
  var fHiddenState = false;

  if (WAVE.has(init, 'DIV'))
    fDiv = WAVE.isString(init.DIV) ? WAVE.id(init.DIV) : init.DIV;
  if (WAVE.has(init, 'titleCtrl'))
    fTitleControl = WAVE.isString(init.titleCtrl) ? WAVE.id(init.titleCtrl) : init.titleCtrl;
  if (WAVE.has(init, 'contentCtrl'))
    fContentControl = WAVE.isString(init.contentCtrl) ? WAVE.id(init.contentCtrl) : init.contentCtrl;

  function hideContent() {
    if (fHideOnTimer) {
      setTimeout(function() {
        __hide();
      }, fTimeout);
    }
    if (fHideOnFocus) {
      WAVE.addEventHandler(window, "focus", outsideClickHandler);
      setTimeout(function(){
        WAVE.addEventHandler(window, "mousemove", outsideMouseMoveHandler);
      } , 1);
    }
    if (fHideOnClick)
      setTimeout(function(){
        WAVE.addEventHandler(window, "click", outsideClickHandler, true);
      }, 1);
    if (fHideOnScroll)
      setTimeout(function(){
        WAVE.addEventHandler(window, "scroll", __hide);
      }, 1);
    if (fHideOnResize)
      setTimeout(function(){
        WAVE.addEventHandler(window, "resize", __hide);
      }, 1);
  }

  function outsideClickHandler(e) {
    var target = e.target;
    var container = ((fMode === "modal") && (fDialog !== null)) ? fDialog.baseDIV() : fContentControl;
    if ((fDialog !== null && e.target === fDialog.baseDIV()) || !WAVE.isParentOf(container, target)) {
      __hide();
    }
  }

  function outsideMouseMoveHandler(e) {
    var target = e.target;
    if ((!WAVE.isParentOf(fContentControl, target) && !WAVE.isParentOf(fTitleControl, target))) __hide();
  }

  function build()
  {
    if(typeof(fDiv) !== tUNDEFINED && fDiv !== null) {
      WAVE.addClass(fDiv, published.CLS_DETAILS);
      var html;

      if (fMode === "modal") {
        if (!fTitleControl) {
          html = "<span id='@titleId@' class='@titleClass@' tabindex='0'></span>";
          fDiv.innerHTML = WAVE.strHTMLTemplate(html, {
            titleId: titleId,
            titleClass: published.CLS_DETAILS_TITLE
          });
          fTitleControl = WAVE.id(titleId);
          setTitle(fTitle);
        }
      } else {

        html = "<span id='@titleId@' class='@titleClass@' tabindex='0'></span><div id='@contId@' class='@contClass@'></div>";
        fDiv.innerHTML = WAVE.strHTMLTemplate(html, {
          titleId: titleId,
          titleClass: published.CLS_DETAILS_TITLE,
          contId: contId,
          contClass: published.CLS_DETAILS_CONTENT
        });
        fTitleControl = WAVE.id(titleId);
        fContentControl = WAVE.id(contId);

        setContent(fContent);
      }
    } else if (fTitleControl !== null && fContentControl !== null) {
      WAVE.addClass(fTitleControl, published.CLS_DETAILS_TITLE);
      WAVE.addClass(fContentControl, published.CLS_DETAILS_CONTENT);
    } else
      throw "Details.build(unacceptable init)";

    setTitle(fTitle);

    if (fShowOnClick)
      WAVE.addEventHandler(fTitleControl, "click", __show);
    if (fShowOnFocus) {
      WAVE.addEventHandler(fTitleControl, "mouseover", __show);
      WAVE.addEventHandler(fTitleControl, "focus", __show);
    }

    __hide();
  }

  function setTitle(cont) {
    if(WAVE.strEmpty(fTitle)) return;

    if (fIsTitleHtml)
      fTitleControl.innerHTML = cont;
    else
      fTitleControl.innerText = cont;
  }

  function setContent(cont) {
    if (fIsContentHtml)
      fContentControl.innerHTML = cont;
    else
      fContentControl.innerText = cont;
  }

  function __hide() {
    if(fHiddenState) return;

    var evtArgsBefore = { phase: published.EVT_PHASE_BEFORE, abort: false };
    details.eventInvoke(published.EVT_DETAILS_HIDE, evtArgsBefore);
    if (evtArgsBefore.abort === true) return;

    setTitle(fTitle);
    if (fShowOnClick)
      WAVE.addEventHandler(fTitleControl, "click", __show);
    if (fHideOnTitle)
      WAVE.removeEventHandler(fTitleControl, "click", __hide);

    if (fMode === "modal" && fDialog !== null) fDialog.close();
    else {
      WAVE.addClass(fContentControl, published.CLS_DETAILS_CONTENT_HIDDEN);
      WAVE.removeClass(fContentControl, published.CLS_DETAILS_CONTENT_VISIBLE);
    }
    WAVE.removeEventHandler(window, "focus", outsideClickHandler);
    WAVE.removeEventHandler(window, "click", outsideClickHandler, true);
    WAVE.removeEventHandler(window, "mousemove", outsideMouseMoveHandler);

    WAVE.addClass(fTitleControl, published.CLS_DETAILS_TITLE_HIDDEN);
    WAVE.removeClass(fTitleControl, published.CLS_DETAILS_TITLE_SHOWN);

    setTimeout(function() {
      fHiddenState = true;
      details.eventInvoke(published.EVT_DETAILS_HIDE, { phase: published.EVT_PHASE_AFTER });
    }, 1);
  }

  function __show() {
    if (!fHiddenState) return;

    var evtArgsBefore = { phase: published.EVT_PHASE_BEFORE, abort: false };
    details.eventInvoke(published.EVT_DETAILS_SHOW, evtArgsBefore);
    if (evtArgsBefore.abort === true) return;

    setTitle(fAltTitle);
    if (fShowOnClick)
      WAVE.removeEventHandler(fTitleControl, "click", __show);
    if (fHideOnTitle)
      WAVE.addEventHandler(fTitleControl, "click", __hide);

    if (fMode === "modal") {
      fDialog = new published.Dialog({
        cls: published.CLS_DETAILS_CONTENT + " " + fModalCls,
        body: fContent,
        onShow: function(dialog) {
          hideContent();

          if (WAVE.strEmpty(fContentUrl)) return;

          WAVE.ajaxCall(
            "GET",
            fContentUrl,
            null,
            function(data) {
              if (fLoadCallback !== null) {
                var result = fLoadCallback(data);
                if(!WAVE.strEmpty(result))
                  dialog.content(result);
              } else {
                dialog.content(data);
              }
            },
            console.error,
            console.error,
            fContentType,
            fContentType
          );
        },
        header: fModalTitle
      });
      fContentControl = fDialog.bodyDIV();
      WAVE.id(fId + "close").onclick = __hide;
    } else {//"swap" - default
      WAVE.removeClass(fContentControl, published.CLS_DETAILS_CONTENT_HIDDEN);
      WAVE.addClass(fContentControl, published.CLS_DETAILS_CONTENT_VISIBLE);
      hideContent();
    }
    fHiddenState = false;
    WAVE.addClass(fTitleControl, published.CLS_DETAILS_TITLE_SHOWN);
    WAVE.removeClass(fTitleControl, published.CLS_DETAILS_TITLE_HIDDEN);

    details.eventInvoke(published.EVT_DETAILS_SHOW, { phase: published.EVT_PHASE_AFTER });
  }

  this.hide = function() {
    __hide();
  };

  this.show = function() {
    __show();
  };

  this.toggle = function() {
    if(fHiddenState) __show();
    else __hide();
  };

  this.content = function(value) {
    if (typeof(value) === tUNDEFINED || value === null)
      return fContent;

    fContent = value;
    setContent(fContent);
  };

  build();

  return details;
};//Details