/**
 * MsgQueueSidebar.js
 * Creates the object to access the message queue in the webview sidebar.
 * The idea is for the site to be able to insert short messages for display
 * to the user.
 */

// Create as a singleton
var MsgQSidebar = (function(){
  var queue = {
    // Message type constants
    T_NONE       : 0x01,               // No type
    T_ERR        : 0x02,               // Error message
    T_OK         : 0x04,               // Success message

    // If exists on insert constants
    I_NONE       : 0x01,               // Do nothing
    I_INSERT     : 0x02,               // Insert like normal
    I_REPLACE    : 0x04,               // Insert new and remove old

    // Defaults
    DEF_DURATION : 3000,               // 3 Seconds
    DEF_TYPE     : 0x01,               // Default message type
    DEF_EXISTS   : 0x04,               // Default if exists

    /**
     * clickMessage
     * Event handler for when user clicks on a message
     */
    clickMessage : function(oEvent){
      oEvent = oEvent || window.event;
      var oNode = oEvent.srcElement || oEvent.target;
      if(!oNode.parentNode){ return; } // Already detached
      if(oNode.tagName.toLowerCase() == "span"){
        oNode.parentNode.parentNode.removeChild(oNode.parentNode);
      }else{
        oNode.parentNode.removeChild(oNode);
      }
    },

    /**
     * tmrDuration
     * Function for the duration timer; this updates the display to countdown
     * until the node is removed.
     */
    tmrDuration : function(span){
      if(!span.parentNode){            // Already detached
        return;
      }
      var dur = parseInt(span.firstChild.nodeValue.substr(1));
      dur = dur - 1;
      span.firstChild.nodeValue = "(" + dur + ")";
      if(dur > 1){                     // Invoke the timer again
        setTimeout(function(){
          var tmp_span = span;
          MsgQSidebar.tmrDuration(tmp_span);
        }, 1000);
      }
    },

    /**
     * addMsg
     * Adds a message to our queue.  Takes an object as it's parameter.
     * Param:
     *   name                optional | Message name
     *   msg                 The message
     *   type                optional | One of the T_ constants
     *   exists              optional | One of the I_ constants
     *   dur                 optional | Duration in milliseconds
     */
    addMsg : function(obj){
      // Set defaults
      if(!obj.name){ obj.name = null; }
      if(!obj.type){ obj.type = this.DEF_TYPE; }
      if(!obj.exists){ obj.exists = this.DEF_EXISTS; }
      if(!obj.dur){ obj.dur = this.DEF_DURATION; }
      if(!obj.msg){ obj.msg = "No message provided!"; }
      if(obj.type == this.T_ERR){
        obj.msg = "Error: " + obj.msg;
      }else if(obj.type == this.T_OK){
        obj.msg = "OK: " + obj.msg;
      }
      obj.msg += " ";
      var msgs = document.getElementById("MsgQSidebar");
      // Before we continue, we must check the prefered action if it already
      // exists
      var existing = this.findMsg(obj.name); // Search for existing
      if(existing){
        if(obj.exists == this.I_NONE){
          return;                      // Exists and do nothing, so return
        }
        if(obj.exists == this.I_REPLACE){ // Remove existing node
          existing.parentNode.removeChild(existing);
        }
      }
      var created = this.createMsgNode( obj.name,
                                        obj.msg,
                                        obj.type,
                                        obj.exists,
                                        obj.dur );
      msgs.insertBefore(created.container, msgs.firstChild);
      // Attach a click event handler to the message
      Events.addEvent(created.container, "click", this.clickMessage);
      // We need to attach a couple of timers.  The first timer will remove
      // the node from DOM after the specified duration.  The second timer will
      // update the duration span to countdown
      setTimeout( function(){          // Duration timer
        var span = created.span;
        MsgQSidebar.tmrDuration(span);
      }, 1000);
      setTimeout( function(){          // Remove timer
        var container = created.container;
        if(!container.parentNode){ return; } // Already detached
        container.parentNode.removeChild(container);
      }, obj.dur);
    },

    /**
     * findMsg
     * Return reference of DOM node if message already exists, searched by
     * name attribute.
     */
    findMsg : function(name){
      var msgs = document.getElementById("MsgQSidebar");
      var node = null;
      if(!name || !name.length){
        return node;
      }
      for(var n = msgs.firstChild; n != null; n = n.nextSibling){
        if(n.nodeType != 1 /*HTML*/){
          continue;                    // Skip this node
        }
        if(n.getAttribute("name") == name){
          node = n;                    // Found it
          break;
        }
      }
      return node;
    },

    /**
     * createMsgNode
     * Creates the message node and returns an object:
     * Returns:
     *  node                 Container node
     *  node                 Duration node
     *
     * Parameters:
     *  string               Node name
     *  string               The message
     *  int                  Message type
     *  int                  If exists
     *  int                  Duration
     */
    createMsgNode : function(name, msg, type, exists, dur){
      var container = document.createElement("p");
      var span = document.createElement("span");
      var txtMsg = document.createTextNode(msg);
      var txtDur = document.createTextNode("(" + (dur / 1000) + ")");
      if(name && name.length){         // Container name, if set
        container.setAttribute("name", name);
      }
      switch(type){                    // Container class, if set
        case this.T_ERR:
          container.className = "msgq_err";
          break;
        case this.T_OK:
          container.className = "msgq_ok";
          break;
      }
      container.appendChild(txtMsg);
      container.appendChild(span);
      span.appendChild(txtDur);
      return { container : container, span : span };
    }
  };

  return queue;
})();
