/**
 * Javascript ResourceManager definition inc preloaders
 * @author Adam J Benson
 * @todo Add in the CSS on demand loaders
 * @version 1.3.1
 *
 * EXAMPLE PACKAGE DEFINITION: (All packages should be defined prior to trying to load them)
 *
 * var pack={
 *    name: "ExamplePack",
 *    description:"This is an example 'package object' which is used by the resource managers",
 *    scripts:["url1","url2","url3","url4"],
 *    callback: function(){},
 *    requires:["packageName"] //Dependancies for this package to be loaded before it...
 * }
 *
 * EXAMPLE USAGE (with callback)
 * ScriptManager('Common', function(){
 *   //YOUR CODE HERE
 *   var simple = new Ext.FormPanel();
 * });
 *
 * EXAMPLE USAGE (without callback)
 * ScriptManager('Common');
 *
 */
var ScriptManager = window.ScriptManager = function(packageName, callback){
    /**
     * Constructor
     */
    ScriptManager.load(packageName, callback);
}

ScriptManager.prototype = {
    registeredPackages: [], //List of packages that have been registered
    loadQueue: [], //Queue of packages that have been requested to load (we load sequentially to avoid dependancy issues)
    processing: false,
    isdebug: true,
    urlBase: "/res/",
    
    register: function(packageConfig){
        //Register the package for loading
        this.registeredPackages[packageConfig.name] = packageConfig;
        this.registeredPackages[packageConfig.name].loaded = false;
    },
    debug: function(debug){
		ScriptManager.isdebug = debug;
	},
    load: function(packageName, callback){
        /**
         * Load the specified package, with an optional callback (in addition to the callback configured by the packages config)
         */
        if (!this.registeredPackages[packageName]) {
            //Package Not Found
            console.log("SPCore Notice: The package " + packageName + " has not been registered but was requested by a script.");
            return;
        }
        if (this.registeredPackages[packageName].loaded == true) {
            //Already loaded... Trigger the scripted callback
            ScriptManager.prototype.nextQueueItem();
            if (callback) 
                callback.call();
            return;
        }
        if (this.registeredPackages[packageName].requires) {
            //Required Scripts
            var required = this.registeredPackages[packageName].requires
            for (var i = 0, m = required.length; i < m; i++) {
                if (this.registeredPackages[required[i]]) {
					if (this.registeredPackages[required[i]].loaded != true) {
						//There is a dependant not loaded, so add self to the queue and load it instead...
						
						this.loadQueue.push([packageName, callback]);
						this.load(required[i]);
					}
				} else {
					console.log("SPCore Notice: The package " + packageName +" requres module" +required[i] + " but module is not defined.");
				}
            }
        }
        if (ScriptManager.processing) {
            //Already proccessing a script (or document body hasn't finished loading)! Add it to the queue...
            this.loadQueue.push([packageName, callback]);
            return;
        }
        ScriptManager.processing = true;
        ScriptManager.prototype.setMask(this.registeredPackages[packageName].description);
        ScriptManager.srcPackage(this.registeredPackages[packageName], callback);
    },
    genScriptNode: function(){
        var scriptNode = document.createElement("script");
        scriptNode.setAttribute("type", "text/javascript");
        return scriptNode;
    },
    genStyleNode: function(name){
        var styleNode = document.createElement("link");
        styleNode.setAttribute("rel", "stylesheet");
        styleNode.setAttribute("type", "text/css");
        styleNode.setAttribute("id", "css-" + name);
		return styleNode;
    },
    srcScript: function(packageConfig, callback){
        var scriptNode = ScriptManager.prototype.genScriptNode();
	var url = ScriptManager.prototype.urlBase + "js?debug=" + ScriptManager.prototype.isdebug;
	scriptNode.setAttribute("src", url + "&files[]=" + packageConfig.scripts.join("&files[]="));
        scriptNode.onload = scriptNode.onreadystatechange = function(){
	    if (!scriptNode.readyState || scriptNode.readyState == "loaded" || scriptNode.readyState == "complete" ||
            scriptNode.readyState == 4 && scriptNode.status == 200) {
                setTimeout(function(){
                    ScriptManager.registeredPackages[packageConfig.name].loaded = true;
                    ScriptManager.prototype.scriptLoaded();
                    if (packageConfig.callback) packageConfig.callback.call();
                    if (callback) callback.call();
                }, 10);
            }
        };
        var headNode = document.getElementsByTagName("head")[0];
        headNode.appendChild(scriptNode);
    },
    srcPackage: function(packageConfig, callback){
        if ( "styles" in packageConfig && packageConfig.styles.length > 0) {
            var styleNode = ScriptManager.prototype.genStyleNode(packageConfig.name);
            var urlBase = ScriptManager.prototype.urlBase + "css?debug=" + ScriptManager.prototype.isdebug;
			styleNode.setAttribute("href", urlBase + "&files[]=" + packageConfig.styles.join("&files[]="));
            /*
			styleNode.onload = styleNode.onreadystatechange = function(){
				alert("ladujemy");
                if (!styleNode.readyState || styleNode.readyState == "loaded" || styleNode.readyState == "complete" ||
                styleNode.readyState == 4 && styleNode.status == 200) {
                    setTimeout(function(){
						alert("ladujemy3");
                        
                    }, 200);
                }
            }*/
            var headNode = document.getElementsByTagName("head")[0];
            headNode.appendChild(styleNode);
			ScriptManager.srcScript(packageConfig, callback);
        }
        else {
            ScriptManager.srcScript(packageConfig, callback);
        }
    },
    nextQueueItem: function(){
        if (this.loadQueue.length > 0) {
            var currentItem = this.loadQueue.shift();
            ScriptManager.prototype.load(currentItem[0], currentItem[1]);
        }
        
    },
    scriptLoaded: function(){
        /**
         * Callback function for whenever a script finishes loading
         */
        ScriptManager.processing = false;
        ScriptManager.prototype.clearMask();
        ScriptManager.prototype.nextQueueItem();
    },
    
    setMask: function(maskText){
        ScriptManager.prototype.clearMask();
        var mask = document.createElement("div");
        mask.className = "ext-el-mask";
        mask.id = "ScriptManagerMask";
        mask.setAttribute("style", "text-align:center;background:#c3daf9;");
        mask.innerHTML = "&nbsp;";
        document.body.appendChild(mask);
        var maskMessage = document.createElement("div");
        maskMessage.className = "ext-el-mask-msg x-mask-loading";
        maskMessage.setAttribute("style", "position:absolute;top:-500px;z-index:2000000;")
        maskMessage.innerHTML = "<div>Ładowanie... " + maskText + "</div>";
        maskMessage.id = "ScriptManagerMaskMessage";
        document.body.appendChild(maskMessage);
        //Fix by cboden for IE masking
        var winWidth = (window.innerWidth || document.getElementsByTagName('body')[0].clientWidth);
        var winHeight = (window.innerHeight || document.getElementsByTagName('body')[0].clientHeight);
        
        maskMessage.style.left = ((winWidth / 2) - (maskMessage.offsetWidth / 2)) + "px";
        maskMessage.style.top = ((winHeight / 2) - (maskMessage.offsetHeight / 2)) + "px";
    },
    clearMask: function(){
        var mask = document.getElementById("ScriptManagerMask");
        var maskMessage = document.getElementById("ScriptManagerMaskMessage");
        if (mask) 
            document.body.removeChild(mask);
        if (maskMessage) 
            document.body.removeChild(maskMessage);
    }
};
ScriptManager.register = ScriptManager.prototype.register;
ScriptManager.debug = ScriptManager.prototype.debug;
ScriptManager.load = ScriptManager.prototype.load;
ScriptManager.loadQueue = ScriptManager.prototype.loadQueue;
ScriptManager.registeredPackages = ScriptManager.prototype.registeredPackages;
ScriptManager.srcScript = ScriptManager.prototype.srcScript;
ScriptManager.srcPackage = ScriptManager.prototype.srcPackage;
ScriptManager.nextQueueItem = ScriptManager.prototype.nextQueueItem();

