﻿
// ScriptBatch : Represents a batch of script files to be loaded 

ScriptBatch = createClass();
ScriptBatch.prototype.init = function(args) {
    /*
        id              : Unique script-batch identifier 	        
        checkBodyLoad   : Is body onload manadatory
        callback        : Function to be called when all mandatory scripts are loaded, or timeout expiry
        timeoutSec		: Wait timeout for batch (is overriden by maximum script timeout)
        extDependency   : To check for external dependencies (Can be a list of script-ids or a function)	        
                          -- type is function, callback is triggered when it returns true
                          -- type is array, callback is triggred when these scripts are loaded.
    */
	if(!isDefined(args))
		args = {};
	defaults = { id: null, checkBodyLoad: true, callback: null, timeoutSec: 0, extDependency: null };

	for(var pr in defaults)
		this[pr] = isDefined(args[pr]) ?args[pr] :defaults[pr];
    
    // List of scripts within this batch
    this.scripts = {};

	// To ensure callback is called only once 
	this.loaded = false;
	// Batch request status
	this.sentRequest = false;
	
	// Add script to batch
    this.add = function(script) {
	    if(!isDefined(this.scripts[script.id])) {
		    script.parentBatch = this;
		    this.scripts[script.id] = script;
    		
		    if(this.timeoutSec < script.timeoutSec)
			    this.timeoutSec = script.timeoutSec;
	    }
	    else 
		    throw new Error("Script already exists for id:" + script.id);
    };

    // Load all scripts in batch
    this.load = function() {
	    for(var script in this.scripts)
		    script.load();
    	
	    this.sentRequest = true;
	    var batch = this;
	    this.timeoutId = window.setTimeout(function() { batch.onTimeout(); }, this.timeoutSec*1000 );
    };

    // Batch onLoad handler
    this.onLoad = function() {
	    window.clearTimeout(this.timeoutId);
	    if(this.callback) {
		    if(!this.loaded) {
			    this.loaded = true;
			    this.callback();
		    }
	    }
    };

    // Batch onTimeout handler
    this.onTimeout = function() {
	    throw new Error("Timeout expired for: " + this.id);
    };

    // Batch onError handler
    this.onError = function() {
	    throw new Error("Error occured for: " + this.id);
    };

    // Child-script load handler
    this.onScriptLoad = function(scriptId) {
	    for(var script in this.scripts)
		    if(script.mandatory && !script.gotResponse)
			    return;

	    if(this.checkBodyLoad && !ScriptMgr.getInstance().bodyLoadStatus)
		    return;

	    this.onLoad();
    };

    // Child-script error handler
    this.onScriptError = function(scriptId) {
	    if(this.scripts[scriptId].mandatory)
		    this.onError();
    };
};