var Prototype = {
  Version: '1.5.1',
  Ext: '019',

  Browser: {
    UserAgent: navigator.userAgent.toLowerCase(),
    Version: (navigator.userAgent.toLowerCase().match(/.+(?:rv|it|ra|ie)[\/: ]([\d.]+)/) || [])[1],

    WebKit: /applewebkit/.test(navigator.userAgent.toLowerCase()),
    Gecko:  /gecko/.test(navigator.userAgent.toLowerCase()) && !/khtml/.test(navigator.userAgent.toLowerCase()),

    IE: /msie/.test(navigator.userAgent.toLowerCase()) && !/opera/.test(navigator.userAgent.toLowerCase()),
    Mozilla: /mozilla/.test(navigator.userAgent.toLowerCase()) && !/(compatible|webkit)/.test(navigator.userAgent.toLowerCase()),
    Opera: /opera/.test(navigator.userAgent.toLowerCase()),
    Safari: /webkit/.test(navigator.userAgent.toLowerCase()),

    documentListener: {
        observers: {},

        initialize: function() {
            this.observers["load"] = [];
            this.observers["unload"] = [];

            if(Prototype.Browser.Mozilla || Prototype.Browser.Opera) {
                document.addEventListener("DOMContentLoaded", this._actionPerformed.bindAsEventListener(this), false);
            } else if(Prototype.Browser.IE || Prototype.Browser.Safari) {
                Event.observe(document, "readystatechange", this._actionPerformed.bindAsEventListener(this));
            } else {
                Event.observe(document, "load", this._actionPerformed.bindAsEventListener(this));
            }

            Event.observe(document, "unload", this._actionPerformed.bindAsEventListener(this));
        },

        add: function(event, observer) {
            if(this.observers[event] != null) {
                this.observers[event].push(observer);
            }
        },

        _actionPerformed: function(event) {
            if(event.type == "DOMContentLoaded" || event.type == "readystatechange" || event.type == "load") {
                if(Prototype.Browser.Mozilla || Prototype.Browser.Opera) {
                    notify(this.observers, "load");
                } else if(Prototype.Browser.IE || Prototype.Browser.Safari) {
                    if(document.readyState == "loaded" || document.readyState == "complete") {
                        notify(this.observers, "load");
                    }
                } else {
                    notify(this.observers, "load");
                }
            } else if(event.type == "unload") {
                notify(this.observers, "unload");
            }

            function notify(observers, event) {
                if(observers[event] != null) {
                    observers[event].each(function(observer) { observer(); });
                }
            }
        }
    }
  },

  BrowserFeatures: {
    XPath: !!document.evaluate,
    ElementExtensions: !!window.HTMLElement,
    SpecificElementExtensions:
      (document.createElement('div').__proto__ !==
       document.createElement('form').__proto__)
  },

  ScriptFragment: '<script[^>]*>([\u0001-\uFFFF]*?)</script>',
  JSONFilter: /^\/\*-secure-\s*(.*)\s*\*\/\s*$/,

  emptyFunction: function() { },
  K: function(x) { return x }
}

Prototype.Browser.documentListener.initialize();

document.onready = function(fn) {
    Prototype.Browser.documentListener.add("load", fn);
}

document.ondispose = function(fn) {
    Prototype.Browser.documentListener.add("unload", fn);
}

String.prototype.replaceAll = function(s, r) {
    v = this;
    r = new String(r);
    if(!(s instanceof Array)) {
        s = new String(s);
        while(v.indexOf(s) != -1) {
            v = v.replace(s, r);
        }
    } else {
        for(var i = 0; i < s.length; i++) {
            v = v.replaceAll(s[i], r);
        }
    }
    return v;
}

Object.extend(Element.Methods, {
    clear: function() {
        for(var i = 0; i < arguments.length; i++) {
            var element = $(arguments[i]);
            var childNodes = element.childNodes;
            for(var j = 0; j < childNodes.length; j++) {
                element.removeChild(childNodes[j]);
            }
        }
    }
});
Element.addMethods();

Event.observe = function(element, name, observer, useCapture) {
    element = $(element);
    Event._observeAndCache(element, name, observer, useCapture);
}

Event.stopObserving = function(element, name, observer, useCapture) {
    element = $(element);
    if(element.removeEventListener) {
        element.removeEventListener(name, observer, useCapture);
    } else if(element.detachEvent) {
        try {
            element.detachEvent('on' + name, observer);
        } catch (e) {}
    }
}
