﻿// --
var JavascriptLoader = Class.create();

JavascriptLoader.CallbackList = new Array();

JavascriptLoader.ProcessCallbacks = function (scriptID)
{
    var i = 0;
    
    while (i < JavascriptLoader.CallbackList.length)
    {
        if (JavascriptLoader.CallbackList[i].scriptBlockID == scriptID)
        {
            //exec the callback
            JavascriptLoader.CallbackList[i].callback();
            //remove it from the list
            JavascriptLoader.CallbackList.splice(i,1);
        }
        else
        {
            i++;
        }
    }
};

JavascriptLoader.CreateWait = function (prefixedID, callback)
{
    var entry = Class.create();
    entry.callback = callback;
    entry.scriptBlockID = prefixedID;
    
    JavascriptLoader.CallbackList.push(entry);
};

JavascriptLoader.prototype = {

    initialize: function() 
    {
    
    }
};

JavascriptLoader.CaptureDocWrites = function()
{
    var oldWrite = document.write;
    
    document.write = function(s) 
    {
        var a = s.match(/<script src="(.+)" type="text.javascript">/);
        if (a) 
        {
            // dodgy... need to let current script load first
            setTimeout('JavascriptLoader.LoadScript(null, "' + a[1] + '");', 250);
            return;
        }
        
        /*
        a = s.match(/<style type="text\/css" media="(\w+)">([^<]+)<\/style>/);        
        if (a) 
        {
            // can do css right away
            addStyle(a[1], a[2]);
            return;
        }
        */
        
        oldWrite(s);
    }
};

JavascriptLoader.LoadScript = function(id, src, callback)
{
//    debugger
    if (callback == null)
        callback = Prototype.emptyFunction;
        
    if (id == null)
        id = new Date().getTime().toString();
        
    var prefixedID = "JSLoader_" + id;

    // If we already have this loaded, just call the callback
    if ($(prefixedID) == null)
    {    
        var e = document.createElement("script");
        e.id = prefixedID;
        e.src = src;
        e.type = "text/javascript";

        JavascriptLoader.CreateWait(prefixedID, callback);

        if (Prototype.Browser.IE)
            Event.observe(e, "readystatechange", function(x, id) { if (x.srcElement.readyState == 'loaded' || x.srcElement.readyState == 'complete') JavascriptLoader.ProcessCallbacks(id);  }.bindAsEventListener(this, prefixedID));
        else
            Event.observe(e, "load", function(x, id) { JavascriptLoader.ProcessCallbacks(id); $(id).readyState = 'complete'; /* Workaround for Firefox not supporting readyState */ }.bindAsEventListener(this, prefixedID));
        
        document.getElementsByTagName("head")[0].appendChild(e);
    }
    else
    {
        //  a race condition can occure if a second call to LoadScript is invoked on the same page, for the same function.
        // essentially, you can get here before the loading in the then clause above is done.
        if ($(prefixedID).readyState == 'loaded' || $(prefixedID).readyState == 'complete')
            callback();
        else
            JavascriptLoader.CreateWait(prefixedID, callback);
    }        
};


// --
var JavascriptMultiLoader = Class.create();

JavascriptMultiLoader.prototype = {

    initialize: function() 
    {
        this.scripts = new Hash();
        this.loadCallback = null;
        
        this.loading = false;
    },
    
    addJS : function(id, src, callback)
    {
        if (this.loading)
            return;
            
        if (callback == null)
            callback = Prototype.emptyFunction;
    
        var callbackWrapper = function(id, callback)
            {
                this.scripts.get(id).loaded = true;
                
                callback();
                                
                // Check to see if all scripts have
                // been loaded and call the loadCallback if so
                var allLoaded = true;
                
                this.scripts.each(
                    function(js) 
                    {            
                        if (!js.value.loaded)
                            allLoaded = false;
                    }.bind(this));
                    
                if (allLoaded)
                    this.loadCallback();
                
            }.bind(this, id, callback);
    
        this.scripts.set(id, { src: src, callback: callbackWrapper, loaded: false});
    },
    
    load : function(callback)
    {
        if (this.loading)
            return;
            
        if (callback == null)
            callback = Prototype.emptyFunction;
    
        this.loadCallback = function()
            {            
                this.loading = false;
            
                callback();                
            }.bind(this);
        
        this.scripts.each(
            function(js) 
            {
                JavascriptLoader.LoadScript(js.key, js.value.src, js.value.callback);                
            }.bind(this));
    }
};
