/**
* @brief compatibility functions for older browsers; IMPORTANT: this file should be included as early as possible!
* @author Marcus Hauser, 2009
*/


// Provide the XMLHttpRequest prototype for IE 5.x-6.x:
// Other browsers (including IE 7.x-8.x) ignore this
//   when XMLHttpRequest is predefined
// copied from <http://en.wikipedia.org/wiki/XMLHttpRequest#Support_in_Internet_Explorer_versions_5.2C_5.5_and_6>
if (window.XMLHttpRequest == undefined) {
  XMLHttpRequest = function() {
    try { return new ActiveXObject("Msxml2.XMLHTTP.6.0"); }
      catch(e) {}
    try { return new ActiveXObject("Msxml2.XMLHTTP.3.0"); }
      catch(e) {}
    try { return new ActiveXObject("Msxml2.XMLHTTP"); }
      catch(e) {}
    try { return new ActiveXObject("Microsoft.XMLHTTP"); }
      catch(e) {}
    throw new Error("This browser does not support XMLHttpRequest.");
  };
}



// add a basic getElementsByClassName method for document object TODO: doesn't work with other node objects yet
if(!document.getElementsByClassName)
{
    document.getElementsByClassName = function(className)
    {
        var all_obj, ret_obj = new Array(), j = 0, teststr;
        if(this.all)
            all_obj = this.all;
        else if(this.getElementsByTagName && !this.all)
            all_obj = this.getElementsByTagName("*");

        for(var i = 0; i < all_obj.length; i++)
        {
            if(all_obj[i].className.indexOf(className) != -1)
            {
                teststr = "," + all_obj[i].className.split(" ").join(",") + ",";
                if(teststr.indexOf("," + className + ",") != -1)
                {
                    ret_obj[j] = all_obj[i];
                    j++;
                }
            }
        }
        return ret_obj;
    };
}


// create a forEach() method for Array prototype (no ECMAScript standard!)
if(!Array.prototype.forEach)
{
    Array.prototype.forEach = function(fun /*, thisp*/)
    {
        var len = this.length >>> 0;
        if(typeof fun != "function")
        {
            throw new TypeError();
        }

        var thisp = arguments[1];
        for(var i = 0; i < len; i++)
        {
            if(i in this)
            {
                fun.call(thisp, this[i], i, this);
            }
        }
    };
}


// define String.trim() method (ECMAScript 5)
if(!String.prototype.trim)
{
    String.prototype.trim = function()
    {
        return this.replace(/^\s+|\s+$/g,"");
    };
}


// implement getPrototypeOf(), but is not accurate 100% of the time
if(typeof Object.getPrototypeOf !== "function" )
{
    if(typeof "test".__proto__ === "object" )
    {
        Object.getPrototypeOf = function(object)
        {
            return object.__proto__;
        };
    }
    else
    {
        Object.getPrototypeOf = function(object)
        {
            // may break if the constructor has been tampered with
            return object.constructor.prototype;
        };
    }
}


// create DOM-compliant add event listener method in IE5+
if(!document.addEventListener && document.attachEvent)
{
    document.addEventListener = function(event_type, handler, use_capture)
    {
        if(event_type == "DOMContentLoaded")
        {
            window.attachEvent("onload", handler);  // not accurate, but better than nothing
            return;
        }
        else if(event_type == "unload")
        {
            window.attachEvent("onunload", handler);
            return;
        }
        else
        {
            event_type = "on"+event_type;
            this.attachEvent(event_type, handler);  // "use_capture" in IE is always "false"
        }
    };
    window.addEventListener = document.addEventListener;
}


// create DOM-compliant remove event listener method in IE5+
if(!document.removeEventListener && document.detachEvent)
{
    document.removeEventListener = function(event_type, handler, use_capture)
    {
        if(event_type == "DOMContentLoaded")
        {
            window.detachEvent("onload", handler);  // not accurate, but better than nothing
            return;
        }
        else if(event_type == "unload")
        {
            window.detachEvent("onunload", handler);
            return;
        }
        else
        {
            event_type = "on"+event_type;
            this.detachEvent(event_type, handler);  // "use_capture" in IE is always "false"
        }
    };
    window.removeEventListener = document.removeEventListener;
}


// add method to add/remove a class to/from an element
// Element.prototype.addClassName = function(className)
// {
//     if(!this.className.match(new RegExp("\\b"+className+"\\b")))
//     {
//         this.className += " "+className;
//     }
//     return true;
// }
// Element.prototype.removeClassName = function(className)
// {
//     if(this.className.match(new RegExp("\\b"+className+"\\b")))
//     {
//         var classes = this.className.split(" ");
//         var new_className = "";
//         for(var i = 0; i < classes.length; i++)
//         {
//             if(!classes[i].match(new RegExp("\\b"+className+"\\b")))
//             {
//                 new_className += classes[i]+" ";
//             }
//         }
//         this.className = new_className;
//     }
//     return true;
// }
