// copyright (c) 2006-2008 Franz Inc, Oakland, CA - All rights reserved.
//
// The software, data and information contained herein are proprietary
// to, and comprise valuable trade secrets of, Franz, Inc.  They are
// given in confidence by Franz, Inc. pursuant to a written license
// agreement, and may be stored and used only in accordance with the terms
// of such license.
//
// Restricted Rights Legend
// ------------------------
// Use, duplication, and disclosure of the software, data and information
// contained herein by any agency, department or entity of the U.S.
// Government are subject to restrictions of Restricted Rights for
// Commercial Software developed at private expense as specified in
// DOD FAR Supplement 52.227-7013 (c) (1) (ii), as applicable.

// Apart from the header stuff, the page contains two basic areas: The
// main page area, where the stuff that the current URL fragment
// refers to is shown, and the message area, which is used for dynamic
// messages, alert, etcetera.

(function() {
  var message, page;
  // Produce initial page layout, save nodes to put dynamic content
  // into.
  window.initLayout = function() {
    var nodes = Mold.cast($("content"), template("body"));
    message = nodes.message;
    page = nodes.page;
  }

  // Clear all non-persistent messages, and the main page.
  window.clearPage = function() {
    var toRemove = [];
    forEach(message.childNodes, function(node) {
      if (node.disappear) toRemove.push(node);
    });
    forEach(toRemove, removeNode);

    page.innerHTML = "";
    window.scrollTo(0, 0);
  }

  // The main content area.
  window.getPage = function() {
    return page;
  }

  var verticalMargin = 15;

  function smooth(t) {
    function once(t) {return .5 - .5 * Math.cos(t * Math.PI);}
    return once(once(t));
  }

  // Fade and remove a message node.
  function fadeOut(node) {
    var t = 1, height = node.offsetHeight + verticalMargin;
    var interval = setInterval(function() {
      t -= .08;
      if (t <= 0 || !node.parentNode) {
        if (node.parentNode) removeNode(node);
        clearInterval(interval);
      }
      else {
        setOpacity(node, t);
        node.style.marginBottom = "-" + Math.round((1 - smooth(t)) * height) + "px";
      }
    }, 100);
  }

  // Create a new message node. When disappear is true, the node will
  // stay until the page is cleared, when it is false it stays until
  // closed explicitly, when it is a number, the node will fade out
  // after that many seconds. Important determines the style of the
  // message, and whether to scroll it into view.
  function messageDIV(disappear, important) {
    var container = document.createElement("DIV");
    container.className = "message " + (important ? "important" : "regular");
    container.disappear = disappear;
    if (typeof disappear == "number")
      setTimeout(partial(fadeOut, container), Math.round(disappear * 1000));

    message.appendChild(container);
    if (important) window.scrollTo(0, 0);
    return container;
  }

  // A simple alert-like message.
  window.showMessage = function(text, disappear, important) {
    var div = messageDIV(disappear, important);
    Mold.cast(div, template("message/alert"), {text: text, close: partial(removeNode, div)});
  }

  // Yes/no question dialog.
  window.showDialog = function(text, yes, no, disappear, important) {
    var div = messageDIV(disappear, important);
    Mold.cast(div, template("message/confirm"), {
      text: text,
      yes: function(){yes && yes(); removeNode(div);},
      no: function(){no && no(); removeNode(div);}
    });
  }

  // Text input message.
  window.showPrompt = function(label, ok, cancel, disappear, important) {
    var div = messageDIV(disappear, important);
    Mold.cast(div, template("message/prompt"), {
      label: label,
      ok: function(text){ok && ok(text); removeNode(div);},
      cancel: function(){cancel && cancel(); removeNode(div);}
    });
  }

  // A message showing a throb animation, no close button.
  window.activityPane = function(label) {
    var div = messageDIV(false, false);
    Mold.cast(div, template("message/activity"), label);
    return partial(removeNode, div);
  }

  // Create a message from a custom template.
  window.customDialog = function(templ, data, disappear, important) {
    var div = messageDIV(disappear, important);
    Mold.cast(div, template(templ), data);
    return partial(removeNode, div);
  }
})();
