String.prototype.trim = function () {
    return this.replace(/^\s*/, "").replace(/\s*$/, "");
};

String.prototype.contains = function (s) {
    return this.indexOf(s) != -1;
};

Array.prototype.contains = function(s) {
    for (var i = 0; i < this.length; i++) {
        if (s == this[i]) return true;
    }
    return false;
};

Array.prototype.remove = function(s) {
    for (var i = 0; i < this.length; i++) {
        if (s == this[i]) this.splice(i, 1);
    }
};
var Powered = {};
Powered.contextPath = '';
Powered.sessionKeyPrefix = '';

Powered.Loader = Class.create({
    initialize:function() {
        this.loadedLibs = new Array();
        this.pendingLibs = new Array();

        // init context path
        var pattern = /\/resources\/scripts\/widget\/loader.js(\?.*)?$/;
        $A(document.getElementsByTagName("script")).findAll( function(s) {
          return (s.src && s.src.match(/loader.js(\?.*)?$/))
        }).each( function(s) {
          Powered.contextPath = s.src.replace(pattern,'');
        });
    },

    setContextPath: function(contextPath) {
        Powered.contextPath = contextPath;
    },

     setSessionKeyPrefix: function(prefix) {
        Powered.sessionKeyPrefix = prefix;
    },
    setVersion : function(version) {
        this.libVersion = version;
    },

    setLoadedLibs: function(jsLibs) {
        var libs = (jsLibs).split(',');
        for (var i = 0; i < libs.length; i++) {
            if (!this.loadedLibs.contains(libs[i])) {
                this.loadedLibs.push(libs[i].trim())
            }
        }
    },

    addLib: function(lib) {
        var scriptSrc = Powered.contextPath + '/resources/scripts/' + lib;
        if (this.libVersion) {
            scriptSrc += "?version=" + this.libVersion;
        }
        if (this.loadedLibs.contains(scriptSrc))  return;
        if (this.pendingLibs.contains(scriptSrc)) return;

        //push it to pending
        Powered.Loader.domReady.done = false;
        this.pendingLibs.push(scriptSrc);
        var headElem = document.getElementsByTagName('head')[0];
        var script = document.createElement('script');
        script.type = 'text/javascript';
        // IE 6 & 7
        script.onreadystatechange = function() {
            if (this.readyState == 'loaded' || this.readyState == 'complete') {
                poweredLoader.scriptDoneCallback(scriptSrc);
            }
        }
        script.onload = function() {
            poweredLoader.scriptDoneCallback(scriptSrc);
        }
        script.src = scriptSrc;
        headElem.appendChild(script);
    },

    scriptDoneCallback: function(scriptSrc) {
        //move to the completed lib list on finished loading
        if (this.pendingLibs.contains(scriptSrc)) {
            this.pendingLibs.remove(scriptSrc);
            this.loadedLibs.push(scriptSrc);
        }
    },

    isReady: function() {
        return (this.pendingLibs.length == 0);
    }
});


var poweredLoader = new Powered.Loader();

//  This function loads the js libs in the resources/scripts folder. This
//  method can be called multiple times and includes comma separated list of libs
Powered.Loader.require = function(jsLib) {
    (jsLib).split(',').each(
            function(include) {
                poweredLoader.addLib(include.trim())
            });
};

// register a function call to be invoked once the page is fully loaded including
// all libraries.
Powered.Loader.domReady = function(f) {
    var domReady = Powered.Loader.domReady;
    if (domReady.done) return f();
    if (domReady.timer) {
        domReady.ready.push(f);
    } else {
        domReady.ready = [f];
        domReady.timer = setInterval(Powered.Loader.isDOMReady, 13);
    }
};

// private method to check if dom is ready.
Powered.Loader.isDOMReady = function() {
    var domReady = Powered.Loader.domReady;
    if (domReady.done) return false;

    if (document && document.getElementsByTagName && document.getElementById && document.body
            && poweredLoader.isReady() && domReady.isReady) {
        clearInterval(domReady.timer);
        domReady.timer = null;
        for (var i = 0; i < domReady.ready.length; i++) {
            domReady.ready[i]();
        }
        domReady.ready = null;
        domReady.done = true;
    }
};

document.observe('dom:loaded', function(){
  Powered.Loader.domReady.isReady = true;
});