﻿var userAgent    = navigator.userAgent.toLowerCase();
var appVersion   = navigator.appVersion.toLowerCase();
var appName      = navigator.appName.toLowerCase();

var isWin        = (appVersion.indexOf('windows') != -1);
var isOpera      = (userAgent.indexOf('opera') != -1);
var isIE         = (appName.indexOf('internet explorer') != -1) && !isOpera;
var isSafari     = (userAgent.indexOf('applewebkit') != -1);
var isMozilla    = (appName.indexOf('netscape') != -1) && !isSafari;

var Tools = {

  post: function() {
    function handleReadyState(o, callback) {
      var poll = window.setInterval(function() {
        if(o && o.readyState == 4) {
          window.clearInterval(poll);
          if ( callback ){
            callback(o);
          }
        }
      },
      50);
    }
    var http;
    try {
      http = new XMLHttpRequest();
    }
    catch(e) {
      var msxml = [
        'MSXML2.XMLHTTP.3.0', 
        'MSXML2.XMLHTTP', 
        'Microsoft.XMLHTTP'
      ];
      for ( var i=0, len = msxml.length; i < len; ++i ) {
        try {
          http = new ActiveXObject(msxml[i]);
          break;
        }
        catch(e) {}
      }
    }
    return function(method, uri, callback, postData, async) {
      http.open(method, uri, async === false ? false : true);
      http.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
      handleReadyState(http, callback);
      http.send(Tools.objectToQueryString(postData) || null);
      return http;
    };
  }(),
  
  objectToQueryString: function(obj)
  {
    var s = "";
    for (var k in obj)
      s += (s != "" ? "&" : "") + encodeURIComponent(k) + "=" + encodeURIComponent(obj[k]);
    return s;
  },
  
  insertHTMLBefore: function(parent, html, beforeNode)
  {
    var temp = document.createElement("div");
    temp.innerHTML = html;
    document.body.appendChild(temp);
    
    var child = null;
    for (var i=temp.childNodes.length-1; i>=0; i--)
    {
			child = temp.childNodes[i];
			if (child)
				if (child.nodeType == 1)
					parent.insertBefore(child, beforeNode);
    }
    document.body.removeChild(temp);
  },  
  
  getParentWithClassName: function(el, className)
  {
    for (; el.parentNode != null && !Spif.ClassNameAbstraction.contains(el, className); el = el.parentNode)
      ; // do nothing
    return el;
  },
  
  joinNodeLists: function(list1, list2)
  {
  debugger;
    var i = list2.length - 1;
    do
    {
      list1[list1.length] = list2[i];
    }
    while(i--);
    return list1;
  },

  attachEventHandler: function(theEl, theEvent, theHandler, theScope)
  {		
    //verify the variables
    theEvent = theEvent.toLowerCase();
    if (theEvent.substring(0,2) == "on")
      theEvent = theEvent.substring(2);
	  if (theScope)
		  theHandler = theHandler.closure(theScope);
    if(typeof(theEl) == 'string')
      theEl = document.getElementById(el);

    // attach for IE or firefox
    if (isIE)
    {
      theEl.attachEvent("on" + theEvent, theHandler);
    }
    else
    {
      if (theEl == document.body)
        theEl = document;
      if (theEvent == "ondragstart")
        theEvent = "ondraggesture";

      theEl.addEventListener(theEvent, theHandler, true);
    }
  }
};

function selectSingleNode(node, xpath)
{
  if (typeof(node.selectSingleNode) != "undefined")
    return node.selectSingleNode(xpath);
  else
  {
    var xpe = new XPathEvaluator();
    return xpe.evaluate(xpath, node, xpe.createNSResolver(node), XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
  }
}

// check for XPath implementation 
if( document.implementation.hasFeature("XPath", "3.0") ) 
{ 
  // prototying the XMLDocument 
  XMLDocument.prototype.selectSingleNode = function(cXPathString, xNode) 
  { 
    if( !xNode ) { xNode = this; }
    var xItems = this.selectNodes(cXPathString, xNode);
    
    if( xItems.length > 0 )  
      return xItems[0];
    else 
      return null;
  } 
  
  // prototying the Element 
  Element.prototype.selectSingleNode = function(cXPathString) 
  {
    if(this.ownerDocument.selectSingleNode) 
      return this.ownerDocument.selectSingleNode(cXPathString, this); 
    else
      throw "For XML Elements Only";
  } 
} 

if( document.implementation.hasFeature("XPath", "3.0") ) 
{ 
  // prototying the XMLDocument 
  XMLDocument.prototype.selectNodes = function(cXPathString, xNode) 
  { 
    if( !xNode ) { xNode = this; }
    var oNSResolver = this.createNSResolver(this.documentElement) 
    var aItems = this.evaluate(cXPathString, xNode, oNSResolver,
                 XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null) 
    var aResult = [];
    for( var i = 0; i < aItems.snapshotLength; i++) 
    { 
      aResult[i] = aItems.snapshotItem(i);
    } 
    return aResult;
  } 

  // prototying the Element 
  Element.prototype.selectNodes = function(cXPathString) 
  { 
    if(this.ownerDocument.selectNodes) 
    { 
      return this.ownerDocument.selectNodes(cXPathString, this);
    } 
    else{throw "For XML Elements Only";} 
  } 
}

Function.prototype.closure = function(obj)
{
  // Init object storage.
  if (!window.__objs)
  {
    window.__objs = [];
    window.__funs = [];
  }

  // For symmetry and clarity.
  var fun = this;

  // Make sure the object has an id and is stored in the object store.
  var objId = obj.__objId;
  if (!objId)
    __objs[objId = obj.__objId = __objs.length] = obj;

  // Make sure the function has an id and is stored in the function store.
  var funId = fun.__funId;
  if (!funId)
    __funs[funId = fun.__funId = __funs.length] = fun;

  // Init closure storage.
  if (!obj.__closures)
    obj.__closures = [];

  // See if we previously created a closure for this object/function pair.
  var closure = obj.__closures[funId];
  if (closure)
    return closure;

  // Clear references to keep them out of the closure scope.
  obj = null;
  fun = null;

  // Create the closure, store in cache and return result.
  return __objs[objId].__closures[funId] = function ()
  {
    return __funs[funId].apply(__objs[objId], arguments);
  };
};
