var api = {
  addEvent: function(obj, type, fn) {
    if (obj.addEventListener) {
      obj.addEventListener(type, fn, false);
    } else if (obj.attachEvent) {
      obj["e"+type+fn] = fn;
      obj[type+fn] = function() { obj["e"+type+fn](window.event); }
      obj.attachEvent("on"+type, obj[type+fn]);
    }
  },
  stopEvent: function(event) {
    if (event.preventDefault) {
      event.preventDefault();
      event.stopPropagation();
    } else {
      event.returnValue = false;
      event.cancelBubble = true;
    }
  },
  testDOM: function() {
    return (document.getElementById ||
            document.getElementsByTagName ||
            document.createElement);
  },
  map: function(fn, elems) {
    for (var i = 0; i < elems.length; i++) {
      fn(elems[i]);
    }
  },
  clearTextNodes:function(node, recursive)
  {
    if (node.nodeType)
    {
        if (node.nodeType == 3)
        {
            node.parentNode.removeChild(node);
        }
        else
        {
            if (node.childNodes)
            {
                for (nui=0;nui<node.childNodes.length;nui++)
                {
                    if (node.childNodes[nui])
                    {
                        if (node.childNodes[nui].nodeType == 3)
                        {
                            node.removeChild(node.childNodes[nui]);
                            continue;
                        }
                        if (recursive) api.clearTextNodes(node.childNodes[nui], true);
                    }
                }
            }
        }
    }
  },
  clearChildNodes: function(node)
  {
    for (ccn = node.childNodes.length; ccn != 0 ; ccn--) node.removeChild(node.childNodes[ccn-1]);
  },
  getElementNodes: function(node) {
    var a = [];
    while (node) {
      if (node.nodeType == 1) {
        a.push(node);
      }
      node = node.nextSibling;
    }
    return a;
  },
  getFirstChild: function(node) {
    return (node.firstChild.nodeType == 1) ?
      node.firstChild :
      api.getNextSibling(node.firstChild);
  },
  getLastChild: function(node) {
    return (node.lastChild.nodeType == 1) ?
      node.lastChild :
      api.getPreviousSibling(node.lastChild);
  },
  getPreviousSibling: function(node) {
    while (node = node.previousSibling) {
      if (node.nodeType == 1) {
        break;
      }
    }
    return node;
  },
  getNextSibling: function(node) {
    while (node = node.nextSibling) {
      if (node.nodeType == 1) {
        break;
      }
    }
    return node;
  },
  countPreviousSiblings: function(node) {
    var i = 0;
    while (node = node.previousSibling) {
      if (node.nodeType == 1) {
        ++i;
      }
    }
    return i;
  },
    /**
    *Gets the dimensions of a DOM object*/
  getSize: function(obj) {
    if (obj.offsetWidth) if (obj.offsetHeight) 
        return {width: obj.offsetWidth, height: obj.offsetHeight};
    var originalVisibility = obj.style.visibility;
    var originalPosition = obj.style.position;
    obj.style.visibility = 'hidden';
    obj.style.position = 'absolute';
    obj.style.display = '';
    var originalWidth = obj.clientWidth;
    var originalHeight = obj.clientHeight;
    obj.style.display = 'none';
    obj.style.position = originalPosition;
    obj.style.visibility = originalVisibility;
    return {width: parseInt(originalWidth), height: parseInt(originalHeight)};
  },
  getOffset: function(obj) {
    var offset = {x: obj.offsetLeft, y: obj.offsetTop};
    while(obj = obj.offsetParent) 
    {
      offset.x += parseInt(obj.offsetLeft);
      offset.y += parseInt(obj.offsetTop);
    }
    if (document.all) 
    {
        offset.x += parseInt(document.body.scrollLeft);
        offset.y += parseInt(document.body.scrollTop);
    }
    return offset;
  },
  removeClassName: function(oldClass, elem) {
    var a = [];
    var classes = elem.className.split(" ");
    for (var i in classes) {
      if (classes[i] != oldClass) {
        a.push(classes[i]);
      }
    }
    elem.className = a.join(" ");
  },
  removeLastClassName: function(elem) {
    var classes = elem.className.split(" ");
    classes.pop();
    return classes.join(" ");
  },
  /*** getElementsByClassName 1.03 | Muffin Research Labs ***/
  getElementsByClassName: function(strClass, strTag, objContElm) {
    strTag = strTag || "*";
    objContElm = objContElm || document;
    var objColl = objContElm.getElementsByTagName(strTag);
    if (!objColl.length && strTag == "*" && objContElm.all) objColl = objContElm.all;
    var arr = new Array();
    var delim = strClass.indexOf("|") != -1  ? "|" : " ";
    var arrClass = strClass.split(delim);
    for (var i = 0, j = objColl.length; i < j; i++) {
      var arrObjClass = objColl[i].className.split(" ");
      if (delim == " " && arrClass.length > arrObjClass.length) continue;
      var c = 0;
      comparisonLoop:
      for (var k = 0, l = arrObjClass.length; k < l; k++) {
        for (var m = 0, n = arrClass.length; m < n; m++) {
          if (arrClass[m] == arrObjClass[k]) c++;
          if (( delim == "|" && c == 1) || (delim == " " && c == arrClass.length)) {
            arr.push(objColl[i]);
            break comparisonLoop;
          }
        }
      }
    }
    return arr;
  },
  getCursorPosition: function(event) {
    event = event || window.event;
    var coords = {x:0, y:0};
    if (event.pageX || event.pageY) {
      coords.x = event.pageX;
      coords.y = event.pageY;
    } else {
      var de = document.documentElement;
      var b = document.body;
      coords.x = event.clientX + (de.scrollLeft || b.scrollLeft) - (de.clientLeft || 0);
      coords.y = event.clientY + (de.scrollTop || b.scrollTop) - (de.clientTop || 0);
    }
    return coords;
  },
  getRelatedTarget: function(event, obj) {
    event = event || window.event;
    var relatedTarget = event.relatedTarget || event.toElement;
    while (relatedTarget && relatedTarget != obj) {
      relatedTarget = relatedTarget.parentNode;
    }
    return (relatedTarget == obj);
  },
  // ------------------------------------------------------------------------------------------------
  getViewPortSize : function()
  {
    var viewportwidth;
    var viewportheight;
    if (typeof window.innerWidth != 'undefined')
    {
        viewportwidth = window.innerWidth,
        viewportheight = window.innerHeight
    }
    else if (typeof document.documentElement != 'undefined'
            && typeof document.documentElement.clientWidth !=
            'undefined' && document.documentElement.clientWidth != 0)
    {
        viewportwidth = document.documentElement.clientWidth,
        viewportheight = document.documentElement.clientHeight
    }
    else
    {
        viewportwidth = document.getElementsByTagName('body')[0].clientWidth,
        viewportheight = document.getElementsByTagName('body')[0].clientHeight
    }
    return {width: viewportwidth, height: viewportheight}
  },
  getScrollXY : function () {
        var scrOfX = 0, scrOfY = 0;
        if( typeof( window.pageYOffset ) == 'number' )
        {
            //Netscape compliant
            scrOfY = window.pageYOffset;
            scrOfX = window.pageXOffset;
        }
            else if( document.body && ( document.body.scrollLeft || document.body.scrollTop ) )
        {
            //DOM compliant
            scrOfY = document.body.scrollTop;
            scrOfX = document.body.scrollLeft;
        }
            else if( document.documentElement && ( document.documentElement.scrollLeft || document.documentElement.scrollTop ) )
        {
            //IE6 standards compliant mode
            scrOfY = document.documentElement.scrollTop;
            scrOfX = document.documentElement.scrollLeft;
        }
        return {x:scrOfX, y:scrOfY};
    },
   setScrollXY : function(x, y)
   {
        if( typeof( window.pageYOffset ) == 'number' )
        {
            //Netscape compliant
            window.pageYOffset = y;
            window.pageXOffset = x;
            return;
        }
        if( document.body && ( document.body.scrollLeft || document.body.scrollTop ) )
        {
            //DOM compliant
            document.body.scrollTop = y;
            document.body.scrollLeft = x;
            return;
        }
        if( document.documentElement && ( document.documentElement.scrollLeft || document.documentElement.scrollTop ) )
        {
            //IE6 standards compliant mode
            document.documentElement.scrollTop = y;
            document.documentElement.scrollLeft = x;
        }
   },
  
  // ------------------------------------------------------------------------------------------------
  // additions to api.classEventMap should only be done via api.setClassEventMapping() function below
  classEventMap : new Array(), 
  setClassEventMapping : function(className, behaviour, functionName)
  {
    if (api.classEventMap[className]==null) api.classEventMap[className] = new Array();
    api.classEventMap[className].push({attribute: behaviour, name: functionName});
  },
  // ------------------------------------------------------------------------------------------------
  
  
  /**
     *opens a window with no toolbars
     *
     * {url}                url to open
     * {name}               should not include spaces
     * {width}              width in pixesl
     * {height}             height in pixels
     * [{position}]         translates to point A(p,p)
     * [{hide scrollbar}]   hides the scrollbar
   */ 
  nuWin : function() {
    a = api.sccWin.arguments;
    if (a[4] == null) p = 100;
    else p = a[4];
    return window.open(
    a[0],
    a[1],
    'height='+a[3]
    +',width='+a[2]
    +',left='+p
    +',top='+p
    +',resizable=no,scrollbars='+(a[5] ? a[5] : "yes" )+',toolbar=no,status=no'
    );
  },
  // -------------------------------------------------------------------------------------------------
  /**
  * Allows you do something like:
  * 
  * function a(b,c){ alert(b+c); };
  * var params = new Array();
  * params.push(a);
  * params.push(2);
  * params.push(3);
  * api.doFunction(params); <--- alerts '5'
  */
  doFunction : function(params)
  {
    call = "params[0](";
    for(i = 1; i < params.length; i++) call += "params["+i+"]" + (i == params.length-1 ? "" : ",");
    return eval(call+")");
  },
  
  // -------------------------------------------------------------------------------------------------
  /**
  * Calls .NET's Ajax methods however adds our pre-loader to a given div;
  * 
  *  USAGE:
  *         api.callAtlas(
  *             [id of DOM element to hold the animated gif or its direct reference],
  *             [Reference to WebMethod, eg: Softchoice.Web.WebServices.Foo.Bar],
  *             {ARG1 for Bar()}, __
  *             {ARG2 for Bar()},   |
  *             ....                |---> optional
  *             {ARG# for Bar()}, __|
  *             [reference to function to call onSuccess of Bar()] or null
  *             );
  */
  callAtlas : function()
  {
    if (arguments.length < 3) return;
    var params = new Array();
    for (argi = 1; argi < arguments.length - 1; argi++) params.push(arguments[argi]);    
    if (!this.holder) this.holder = new Object();
    if (!this.holder.events) this.holder.events = new Array();
    if (!this.holder.caller) this.holder.caller = function(iinti) { this.events[iinti](); }
    var hndl = new Object();
    hndl.container = null;
    hndl.showImage = function() { }
    if (arguments[0])
    {
        if (typeof arguments[0] == "string") hndl.container = document.getElementById(arguments[0]);
        else hndl.container = arguments[0];
        hndl.showImage = function() 
        {
            if(!hndl.showImage) return;
            api.clearChildNodes(hndl.container);
            if($.browser.msie) var imgloader = new Image();
            else var imgloader = document.createElement("img");
            imgloader.src = "images/ajax-loader.gif";
            hndl.container.appendChild(imgloader);
        }
        this.holder.events.push(hndl.showImage);
    }
    hndl.history = arguments[arguments.length -1];
    hndl.onSuccess = function() 
    {
        hndl.showImage = null;
        api.clearChildNodes(hndl.container);
        var mp = new Array(); 
        if (hndl.history) mp.push(hndl.history); 
        for (thisi = 0; thisi < arguments.length; thisi++) mp.push(arguments[thisi]); 
        api.doFunction(mp); 
    }
    params.push(hndl.onSuccess);
    setTimeout('api.holder.caller('+(api.holder.events.length-1)+')', 1000);
    api.doFunction(params);
  }
  
}

