/*
 * e107Helper
 * Miscellaneous JS helper object for functions that don't fit anywhere else
 */
var e107Helper = {
   // Holder for main page HMTL whilst a dialog is displayed
   bodyhtml : "",

   /**
    *
    */
   addTextToField : function(txt, fieldid) {
      document.getElementById(fieldid).value = txt;
      expandit(fieldid+"_box")
   },

   /**
    * Used to confirm an action
    * Normally action is some sort of destroy (e.g. delete row from DB). A Javascript confirm
    * dialog is displayed, if positive response button is selected thenh action is allowed to happen, thenh
    * action being to load the next page (which should effect the destroy)
    * @param   string   the message to be displayed in the confirm dialog
    * @param   string   string representing the URL of the page to load is positive response button selected
    * @return  boolean  true if positive response button selected, otherwise false
    */
   confirmDelete : function (msg, loc){
      if (confirm(msg)) {
         document.location = loc;
         return true;
      } else {
         return false;
      }
   },

   /**
    * Displays a dialog
    * A dialog, in this scenario, is normally a form of some sort. Before the dialog is displayed
    * the page is cleared (inner HTML removed). It is up to the caller to call the <code>storeBodyHTML()</code>
    * function before3 calling this function and to ensure the <code>restoreBodyHTML</code> function is called
    * when the dialog is completed or cancelled.
    * @param   string   the HTML ID attribute to be given to the dialog (actually the DIV that the dialog is dispalyed in)
    * @param   html     the HTML representing the dialog (form) to be displayed
    */
   dialog : function (id, html) {
      var dialog = document.createElement("DIV");
      dialog.style.visibility = "hidden";
      dialog.id               = id;
      dialog.innerHTML        = html;
      document.body.innerHTML = "";
      document.body.appendChild(dialog);
      dialog.style.visibility = "";
   },

   /**
    * Stores the current page
    * To be used before displaying a dialog to save the current page
    */
   storeBodyHTML : function () {
      this.bodyhtml = document.body.innerHTML;
   },

   /**
    * Restores the current page
    * To be used after a dialog has been completed or cancelled to restore the current page
    */
   restoreBodyHTML : function() {
      document.body.innerHTML = this.bodyhtml;
   },

   /**
    * Display a 'popup' message
    * Generates a 'popup' message on the current page. The 'popup' cannot be closed by the user, it must be closed programatically.
    * The aim of this 'popup' is to indicate to the user that something is happening (e.g. "Processing, please wait...")
    * @param   string   the HTML ID attribute to be given to the message (actually the DIV that the message is dispalyed in)
    * @param   text     the text of the message to be displayed
    */
   message : function (id, text) {
      var msgdiv1 = document.createElement("DIV");
      var msgdiv2 = document.createElement("DIV");
      var msgdiv3 = document.createElement("DIV");
      var br      = document.createElement("BR");
      var button  = document.createElement("INPUT");
      var msgtxt  = document.createTextNode(text);

      e107HelperStyle.addClass(msgdiv1, "forumheader");
      e107HelperStyle.addClass(msgdiv2, "forumheader2");
      e107HelperStyle.addClass(msgdiv3, "forumheader3");
      e107HelperStyle.addClass(button, "button");

      msgdiv1.style.visibility   = "hidden";
      msgdiv1.style.position     = "absolute";
      msgdiv1.id                 = id;

      msgdiv3.style.margin       = "10px";
      msgdiv3.style.padding       = "10px";

      button.type                = "button";
      button.value               = "OK";
      button.style.textAlign     = "right";

      msgdiv3.appendChild(msgtxt);
      msgdiv2.appendChild(msgdiv3);
      msgdiv1.appendChild(msgdiv2);
      document.body.appendChild(msgdiv1);
      var vpsize = e107HelperSize.getViewportSize();
      var left = (vpsize.width - msgdiv1.offsetWidth) / 2;
      var top  = (vpsize.height - msgdiv1.offsetHeight) / 3;
      if (e107HelperBrowser.isIE) {
         msgdiv1.style.pixelTop     = top;
         msgdiv1.style.pixelLeft    = left;
      } else {
         msgdiv1.style.top          = top+"px";
         msgdiv1.style.left         = left+"px";
      }
      msgdiv1.style.visibility   = "";
   },

   /**
    * Display a timed 'popup' message (@see e107Helper.message)
    * Additionally, this method will cancel the 'popup' after the sepcified number of milliseconds
    * @param   string   the message text to be displayed
    * @param   integer  the numbner of milliseconds that the message should be displayed for (defaults to 2500 = 2.5 seconds if not supplied)
    */
   timedMessage : function (msg, msecs) {
      this.message("e107HelperTimedMessage", msg)
      if (msecs == null) {
         msecs = 2500;
      }
      var timer = setTimeout(
         function () {
            var el = document.getElementById("e107HelperTimedMessage");
            el.parentNode.removeChild(el);
         }
         , msecs);
   },

   /**
    * Kills (cancels) a 'popup' message (@see e107Helper.message)
    * Used to kill a 'poup' message once processing ahs finished
    * @param   string   the HTML ID attribute of the message to be killed
    */
   killmessage : function (id) {
      var el = document.getElementById(id);
      el.parentNode.removeChild(el);
   },

   /**
    * alert
    * Duplicates the Javascript alert functionality - may be expanded to allow alerts to be turned on/off for debugging.
    */
   alert : function(txt) {
      alert(txt);
   }
};

/*
 * e107HelperStyle
 * Helper object for style handling
 */
var e107HelperStyle = {
   addClass : function(el, clazz) {
      if (!this.hasClass(el, clazz)) {
         el.className += (" " + clazz);
      }
   },
   removeClass : function(el, clazz) {
      if (el.className == null) {
         return;
      }
      var list = el.className.split(" ");
      for (var i=0; i<list.length; ++i ) {
         if (list[i] == clazz) {
            list[i] = "";
         }
      }
      el.className = list.join(" ");
   },
   hasClass : function(el, clazz) {
      var list = el.className.split(" ");
      for (var i=0; i<list.length; ++i ) {
         if (list[i] == clazz) {
            return true;
         }
      }
      return false;
   }
}

/*
 * e107HelperSize
 * Helper object for size information
 */
var e107HelperSize = {
   getViewportSize : function() {
      function isMozHorizScollBarShowing() {
         return ((document.body.offsetWidth < window.innerWidth ) && ( document.documentElement.offsetWidth > document.body.offsetWidth));
      }
      return {
          width : document.body.clientWidth,
          height: e107HelperBrowser.isIE ? document.body.clientHeight : window.innerHeight - (isMozHorizScollBarShowing() ? 15 : 0)
      }
   }
}

/*
 * e107HelperEvent
 * Helper object for event handling (onclick, onkeydown, etc.)
 */
var e107HelperEvents = {
   getEvent : function(evt) {
      if (typeof window.event != "undefined") {
         evt = window.event;
      }
      return evt;
   },
   getCharCode : function( evt ) {
      // Old versions of IWB populate keyCode incorrectly.
      var cc = evt.charCode;
      if ( Browser.isIWB ) {
         // for Ctrl+cursor key/Insert/Delete/Home/End/Page Up/Page Down we
         // get cc of 945 instead of 0. The keyCode is correct.
         if ( cc == 945 && evt.type == "keypress" && evt.ctrlKey ) {
            cc = 0;
         }
      }
      return cc;
   },
   getKeyCode : function( evt ) {
      // Old versions of IWB populate keyCode incorrectly.
      var kc = evt.keyCode;
      if ( Browser.isIWB20 ) {
         // The VKs for lowercase should be the same as uppercase
         if ( evt.type == "keyup" ) {
            // kc has flags in high byte
            if ( kc > 255 ) {
               kc &= 0xff;
               if ( 97 <= kc && kc <= 122 ) {
                  kc -= 32;
               }
            }
         } else if ( evt.type == "keydown" ) {
            // This is not perfect e.g. lowercase W is the same as F8
            if ( 97 <= kc && kc <= 122 ) {
               kc -= 32;
            }
         }
      }
      return kc;
   },
   getTarget : function (event) {
      return ( (Browser.isMoz) ? event.target : window.event.srcElement)
   },
   boundEvents : [],
   bindHandler : function( target, eventName, handler ) {
      if ( target.addEventListener ) {
         target.addEventListener( eventName, handler, false );
      } else if ( target.attachEvent ) {
         target.attachEvent( "on" + eventName, handler );
      }
      e107HelperEvents.boundEvents.push( arguments );
   },
   unbindHandler : function( target, eventName, handler ) {
      if ( target.removeEventListener ) {
         target.removeEventListener( eventName, handler, false );
      } else if ( target.removeEvent ) {
         target.removeEvent( "on" + eventName, handler );
      }
   },
   dispose : function() {
      for(var i = e107HelperEvents.boundEvents.length - 1; i >= 0; --i ) {
         var be = e107HelperEvents.boundEvents[i];
         if (be[1] != "unload") {
            e107HelperEvents.unbindHandler( be[0], be[1], be[2] );
         }
         be[i] = null;
      }
   }
}

e107HelperEvents.bindHandler(window, "unload", e107HelperEvents.dispose);

/*
 * e107HelperBrowser
 * Helper object to determine the client browser
 */
var e107HelperBrowser = {
   ua       : navigator.userAgent,
   isMoz    : /Gecko/i.test(navigator.userAgent),
   isIE55   : /msie 5\.5/i.test(navigator.userAgent),
   isIE6    : /msie 6/i.test(navigator.userAgent),
   isIE     : /msie/i.test(navigator.userAgent),
   isIWB    : /Gecko/i.test(navigator.userAgent) && (/OS\/2/.test(navigator.platform) || /^Warp/.test(navigator.platform)),
   isIWB20  : /Gecko/i.test(navigator.userAgent) && /^Warp/.test(navigator.platform),
   platform : navigator.platform
}

/*
 * e107HelperAjax
 * Ajax helper object for JavasCript/HTTP Request communication with the server
 */
var e107HelperAjax = {
   parms : "",
   getRequester : function() {
      // Create an instance of the XML HTTP Request object
      var oXMLHTTP;

      try {
         oXMLHTTP=new ActiveXObject("Msxml2.XMLHTTP")
      } catch (e) {
         try {
            oXMLHTTP=new ActiveXObject("Microsoft.XMLHTTP")
         } catch (e) {
         }
      }

      // Non IE browsers start here.
      if (typeof oXMLHTTP == "undefined") {
         try {
            oXMLHTTP = new XMLHttpRequest();
         } catch (e) {
         }
      }
      return oXMLHTTP;
   },
   post : function(uri, async) {
      //alert("Posting");
      // default to async
      if (typeof async == "undefined") {
         async = true;
      }
      var req = this.getRequester();
      if (async) {
         req.onreadystatechange = function() {
            // 0 uninitialized   Object created, open not called yet
            // 1 loading         Called open but not send
            // 2 loaded          Called send, got status and headers but not body
            // 3 interactive     Some data received (and available) but not all
            // 4 completed       All the data has been received
            //alert(req.readyState);
            if (req.readyState == 4) {
               e107HelperAjax.responseHandler(req);
            }
         };
      }

      req.open("POST", uri, async);
      req.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
      //alert(this.parms);
      req.send(this.parms);
      this.parms = "";
      if (!async) {
         this.responseHandler(req);
      }
   },
   addParm : function(name, value) {
      if (this.parms.length > 0){
         this.parms += "&";
      }
      this.parms += escape(name) + "=" + escape(value);
   },
   responseHandler : function (req) {
      if (req.responseXML == null) {
         // It's text
      } else {
         // It's an XML message


// basis for an (simple) XML parser?
//         var doc      = req.responseXML.documentElement;
//alert(doc.tagName);
//         var els = doc.getElementsByTagName("*");
//         for (var i=0; i<els.length; i++) {
//            alert(els[i]);
//            alert(els[i].tagName);
//         }

         var response = req.responseXML.getElementsByTagName("e107helperajax");
         var nodes = response[0].childNodes;
         for (i=0; i<nodes.length ; i++) {
            if (nodes[i].nodeType != 1) {
               continue;
            }
            //alert(nodes[i].getAttribute("type"));
            switch (nodes[i].getAttribute("type")) {
               case "alert" : {
                  alert(this.getText(nodes[i]));
                  break;
               }
               case "dialog" : {
                  e107Helper.dialog(nodes[i].getAttribute("id"), this.getText(nodes[i]));
                  break;
               }
               case "innerhtml" : {
                  document.getElementById(nodes[i].getAttribute("id")).innerHTML = this.getText(nodes[i]);
                  break;
               }
               case "js" : {
                  eval(nodes[i].getAttribute("func"));
                  break;
               }
               case "killmessage" : {
                  e107Helper.killmessage(nodes[i].getAttribute("id"));
                  break;
               }
               case "restorebody" : {
                  e107Helper.restoreBodyHTML();
                  break;
               }
               case "timedmessage" : {
                  e107Helper.timedMessage(this.getText(nodes[i]), nodes[i].getAttribute("msecs"));
                  break;
               }
               default : {
                  // Do nothing
               }
            }
         }
      }
   },
   refreshImageTag : function(uri, tagId, base) {
      this.addParm("action", "refreshImageTag");
      this.addParm("id", tagId+"_box");
      this.addParm("base", base);
      var dir = document.getElementById(tagId+"_dir");
      this.addParm("dir", dir.value);
      this.post(uri);
   },
   getText : function (node) {
      var i;
      var contentStr = "";
      if (node.xml) {
         for ( i = 0 ; i < node.childNodes.length ; i++ )
            contentStr += node.childNodes[i].xml;
      } else {
         var xmlSerializer = new XMLSerializer();
         for ( i = 0 ; i < node.childNodes.length ; i++ ) {
            if (node.childNodes[i].nodeType == 4) {
               // CDATAsection
               contentStr += node.childNodes[i].data;
            } else {
               // Element
               contentStr += xmlSerializer.serializeToString(node.childNodes[i]);
            }
         }
      }
      return contentStr;
   }
}


/*
 * Prototyping stuff - not for general use
 */


// ****************************************************************************
// IE emulation stuff for Mozilla based browsers
// ****************************************************************************
if (e107HelperBrowser.isMoz) {
   Event.prototype.__defineSetter__("returnValue",
      function (b) {
         alert(b);
         if (!b)
            this.preventDefault();
         return b;
      }
   );
   Event.prototype.__defineSetter__("cancelBubble",
      function (b) {
         alert(b);
         if (b)
            this.stopPropagation();
         return b;
      }
   );
   Event.prototype.__defineGetter__("srcElement",
      function () {
         var node = this.target;
         while (node.nodeType != 1 && node.nodeType != 9)
            node = node.parentNode;
         return node;
      }
   );
}


function editCell(id, cellSpan) {
   var inputWidth = (document.getElementById(id).offsetWidth / 7);
   var oldCellSpan = cellSpan.innerHTML;
   var temp = "<form name='activeForm' onsubmit='parseForm(\""+id+"\", \""+id+"input\");return false;' style='margin:0;' action=''>";
   temp += "<input type='text' id='"+id+"input' size='"+inputWidth+"' onblur='parseForm(\""+id+"\", \""+id+"input\");return false;'>";
   temp += "<br /><noscript><input value='OK' type='submit'></noscript></form>";
   document.getElementById(id).innerHTML = temp;
   document.getElementById(id+"input").value = oldCellSpan;
   document.getElementById(id+"input").focus();
   document.getElementById(id).style.background = '#ffc';
//   document.getElementById(id).style.border = '1px solid #fc0';
}
function parseForm(cellID, inputID) {
   var st = document.getElementById(inputID).value + '~~|~~' + cellID;
   document.getElementById(cellID).innerHTML = "<span class=\"update\">Updating...</span>";
   //x_changeText(st, textChanger_cb);
//   document.getElementById(cellID).style.border = 'none';
}