/**
* require(script) is used for on demand loading of JavaScript
*
* // basic usage
* require("script.js");
*
* @param  script string string holding the js script file name to load
* @author Generalov Eugene <e.generalov@gmail.com>
*
* require r1 // 2010.02.18 // jQuery 1.3.2
*/

(function(){

    var Require = {
        
        baseUri: '',
        loadedLib: {},
        backend: {
            load: function(uri) {
                throw "Abstract method"
            },
            isScriptLoaded: function (scriptPath) {
                throw "Abstract method"
            },
            scriptBase: function() {
                throw "Abstract method"
            }
        },

        require: function (script) {
            if (!this.isScriptLoaded(script)) {
                this.backend.load(this.scriptAbsoluteUri(script));
                this.markScriptLoaded(script);
            }
        },
        setBackend: function(backend) {
            this.backend = backend;
        },
        
        markScriptLoaded: function(scriptPath) {
            this.loadedLib[scriptPath] = true;
        },
        isScriptLoaded: function(scriptPath) {
            if (this.loadedLib[scriptPath]) return true;
            if (this.backend.isScriptLoaded(scriptPath)) {
                this.markScriptLoaded(scriptPath);
                return true;
            }
            return false;
        },
        scriptAbsoluteUri: function(scriptPath) {
            if ( !this.getScriptBaseUri() ) {
                this.setScriptBaseUri(this.backend.scriptBase());
            }
            return this.getScriptBaseUri() + scriptPath;
        },
        setScriptBaseUri: function(baseUri) {
            this.baseUri = baseUri;
            return this;
        },
        getScriptBaseUri: function() {
            return this.baseUri;
        }
    };

    window.require = function(script) {
        Require.require(script);
    };
    window.require.setBackend = function(backend) {
        Require.setBackend(backend);
    };
})();


/**
 * jQuery backend for require.
 */
(function(){

    var RequireJQueryBackend = {
        cache: true,
        load: function(uri) {
            jQuery.ajax({
                type: "GET",
                url: uri,
                dataType: "script",
                cache: this.cache,
                async: false
            });
        },
        isScriptLoaded: function (scriptPath) {
            var status = false;
            jQuery('script[src]').each(function(){
                var src = jQuery(this).attr('src');
                if (src.substr(src.length-scriptPath.length) === scriptPath) {
                    status = true;
                    return false; // break .each()
                }
            });
            return status;
        },
        scriptBase: function() {
            return jQuery('link[rel=javascriptbase]').attr('href') || jQuery('script[src]').attr('src').replace(/\w+\.js$/, '');
        }
    };
    
    window.require.setBackend(RequireJQueryBackend);

})();
