// vim:et:sw=4:ts=4
// useful X-browser functions, 2006.
// by Kevin Ko <kevin.s.ko@gmail.com>
// $Id: lib.js,v 1.13 2006/06/01 22:02:22 scrabbly Exp $
//
// Licensed under the Creative Commons Attribution 2.5 License
//   http://creativecommons.org/licenses/by/2.5/
// (open use, as long as credit is given to the author)

if (!window.Node) {
    var Node = {
        ELEMENT_NODE: 1,
        ATTRIBUTE_NODE: 2,
        TEXT_NODE: 3,
        COMMENT_NODE: 8,
        DOCUMENT_NODE: 9,
        DOCUMENT_FRAGMENT_NODE: 11
    }
}

function LibEvent() {
        this.count = 0;
        this.events = new Object();
}

LibEvent.prototype = {
        add : function(e) {
                this.count++;
                this.events[e] = e;
        },
        remove : function(e) {
                if (this.events[e]) {
                        this.count--;
                        delete this.events[e];
                }
                return this.count;
        },
        call : function(arg) {
                var rv = null;
                for (var i in this.events) {
                        rv = this.events[i](arg);
                }
                return rv;
        }
}

function Lib() {}

Lib.prototype = {
        // for IE, assume action on the object, not propagation or
        // similar variants
        addEvent: function(elem, event, func, onPropagate) {
                var evtName = "on" + event;
                var ef = elem[evtName];
                var levt;
                // assume elem[evtName] invariant: elem['_'+evtName]
                // entry if elem[evtName] exists
                if (ef) {
                        levt = elem['_' + evtName];
                } else {
                        levt = new LibEvent();
                        ef = Lib.prototype.handlerWrapper(levt);
                        elem[evtName] = ef;
                        elem['_' + evtName] = levt;
                }
                levt.add(func);
        },
        removeEvent: function(elem, event, func, onPropagate) {
                var evtName = "on" + event;
                var ef = elem[evtName];
                if (ef) {
                        var levt = elem['_' + evtName];
                        if (levt.remove(func) == 0) {
                               // maintain elem[evtName] invariance
                               elem[evtName] = null; 
                               elem['_' + evtName] = null;
                        }
                }
        },
        handlerWrapper: function(le) {
                // fake a mix of the DOM2 handler interface
                return function(e) {
                        if (!e) {
                                e = window.event;
                        }
                        if (!e.target) {
                                e.target = e.srcElement;
                        }
                        return le.call(e);
                }
        },
        // general technique courtesy of quirksmode.org; additional 
        // improvements regarding amortized complexity
        getPosX: function(elem) {
                var curr = 0;
                if (elem.x) {
                        curr = elem.x;
                } else if (elem.offsetParent) {
                        var currelem = elem;
                        do {
                                curr += currelem.offsetLeft;
                                currelem = currelem.offsetParent;
                                if (currelem.x) {
                                        curr += currelem.x;
                                        break;
                                }
                                // assume top-most has position 0
                        } while (currelem.offsetParent);
                        elem.x = curr;
                }
                return curr;
        },
        getPosY: function(elem) {
                var curr = 0;
                if (elem.y) {
                        curr = elem.y;
                } else if (elem.offsetParent) {
                        var currelem = elem;
                        do {
                                curr += currelem.offsetTop;
                                currelem = currelem.offsetParent;
                                if (currelem.y) {
                                        curr += currelem.y;
                                        break;
                                }
                                // assume top-most has position 0
                        } while (currelem.offsetParent);
                        elem.y = curr;
                }
                return curr;
        },
        // courtesy of quirksmode & lightbox source
        getPageSize: function() {
                var xScroll, yScroll;
	
                if (window.innerHeight && window.scrollMaxY) {	
                        xScroll = document.body.scrollWidth;
                        yScroll = window.innerHeight + window.scrollMaxY;
                } else if (document.body.scrollHeight > 
                           document.body.offsetHeight){ 
                        // all but Explorer Mac
                        xScroll = document.body.scrollWidth;
                        yScroll = document.body.scrollHeight;
                } else {// Explorer Mac...would also work in Explorer 6 
                        //Strict, Mozilla and Safari
                        xScroll = document.body.offsetWidth;
                        yScroll = document.body.offsetHeight;
                }
	
                var windowWidth, windowHeight;
                if (self.innerHeight) {	// all except Explorer
                        windowWidth = self.innerWidth;
                        windowHeight = self.innerHeight;
                } else if (document.documentElement && 
                           document.documentElement.clientHeight) { 
                        // Explorer 6 Strict Mode
                        windowWidth = document.documentElement.clientWidth;
                        windowHeight = document.documentElement.clientHeight;
                } else if (document.body) { // other Explorers
                        windowWidth = document.body.clientWidth;
                        windowHeight = document.body.clientHeight;
                }	
        	
                // for small pages with total height less then height of 
                // the viewport
                if (yScroll < windowHeight){
                        pageHeight = windowHeight;
                } else { 
                        pageHeight = yScroll;
                }

                // for small pages with total width less then width of the 
                // viewport
                if (xScroll < windowWidth){	
                        pageWidth = windowWidth;
                } else {
                        pageWidth = xScroll;
                }
                arrayPageSize = new Array(pageWidth, pageHeight,
                                          windowWidth, windowHeight) 
                return arrayPageSize;
        },
        mouseX: function(evt) {
                var posx = 0;
                if (evt.pageX) {
                        posx = evt.pageX;
                } else if (evt.clientX) {
                        posx = e.clientX + document.body.scrollLeft;
                }
                return posx;
        },
        mouseY: function(evt) {
                var posy = 0;
                if (evt.pageY) {
                        posy = evt.pageY;
                } else if (evt.clientY) {
                        posy = e.clientY + document.body.scrollTop;
                }
                return posy;
        },
        createXMLHttp: function() {
          var xmlhttp = false;
          /*@cc_on @*/
          /*@if (@_jscript_version >= 5)
          try {
            xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
          } catch(e) {
            try {
              xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
            } catch (e) {
              xmlhttp = false;
            }
          }
          @end @*/
          if (!xmlhttp && typeof XMLHttpRequest != 'undefined') {
            xmlhttp = new XMLHttpRequest();
          }
          if (!xmlhttp) {
            alert('XMLhttp not supported');
          }
          return xmlhttp;
        },
        xmlHttpReq: function(xmlhttp, chkAccept, url, actionF, succF) {
                xmlhttp.open("GET", url);
                xmlhttp.onreadystatechange = function() {
                        if (xmlhttp.readyState == 4) {
                                if (xmlhttp.status != 404) { 
                                        succF(xmlhttp.responseText);
                                } else {
                                        alert("not found on xmlHttp request");
                                }
                        }
                }
                if (chkAccept) {
                        xmlhttp.setRequestHeader('Accept', 'message/x-jl-tabform');
                }
                actionF();
                xmlhttp.send(null);
        },
        // example fetch function
        xmlFetch: function(flag) {
                  var thePage = this;
                  function succF(data) {
                          // thePage.update(data);
                          // thePage.clearLoading();
                  };
                  function actionF() {
                          // thePage.setLoading();
                  };
                  this.xmlHttpReq(flag, this.reqUrl, actionF, succF);
        },
        getElementsByClassName: function(elem, c) {
                var elems = elem.getElementsByTagName('*'); 
                var res = [];
                for (var i = 0; i < elems.length; i++) {
                        if (elems[i].className == c)
                                res.push(elems[i]);
                }
                return res;
        },
        replaceFirstChild: function(parent, elem) {
                if (parent.firstChild) {
                        parent.replaceChild(elem, parent.firstChild);
                } else {
                        parent.appendChild(elem);
                }
        },
        isMSIE: function() {
            return (navigator.userAgent.toLowerCase().indexOf('msie')+1);
        }
}
