/// <reference path="yui/yahoo-dom-event/yahoo-dom-event.js" />
/// <reference path="yui/get/get.js" />
/*
var sConfig = {
'yahoo':
{
path: '',
requires: []
},
'dom':
{
path: '',
requires: ['yahoo']
},
'event':
{
path: '',
requires: ['yahoo']
}
};
*/
var Script_Loader = function(config, loaded) {
    var self = this;
    this.config = config;
    this.scripts = {};
    this.quee = [];
    var connection = null;
    var loadNext = function() {
        var shift = function() {
            self.quee.splice(0, 1);
            connection = null;
            loadNext();
        };
        if (self.documentReady && !connection) {
            if (self.quee.length > 0) {
                var next = self.quee[0];
                var itempath = next.config.path;
                if (!(itempath.match("http://"))) {
                    itempath = self.httproot + itempath;
                }
                if (itempath.match(".css")) {
                    connection = YAHOO.util.Get.css(itempath, {
                        onSuccess: function() { next.successEvent.fire(); shift(); },
                        onFailure: function() { next.failureEvent.fire(); shift(); },
                        onTimeout: function() { next.failureEvent.fire(); shift(); }
                    });
                } else {
                    connection = YAHOO.util.Get.script(itempath, {
                        onSuccess: function() { next.successEvent.fire(); shift(); },
                        onFailure: function() { next.failureEvent.fire(); shift(); },
                        onTimeout: function() { next.failureEvent.fire(); shift(); }
                    });
                }
            }
        }
    };
    this.addToQuee = function(script) {
        if (!script.loaded) {
            for (var i = 0; i < this.quee.length; i++) {
                if (this.quee[i] == script) {
                    return;
                }
            }
            self.quee.push(script);
            if (self.quee.length == 1) {
                loadNext();
            }
            script.onSuccess(loadNext);
            script.onFailure(loadNext);
        }
    };
    this.requireScript = function(name) {
        var script = this.scripts[name];
        if (script) {
            return script;
        }
        script = new JScript(this, name);
        this.scripts[name] = script;
        return script;
    };
    this.requireScripts = function(list, _success, _failure) {
        var requires = [];
        var fail = false;
        var loaded = false;
        var __success = function() {
            if (!loaded) {
                for (var i = 0; i < requires.length; i++) {
                    if (!requires[i].loaded || requires[i].wrong) {
                        return;
                    }
                }
                loaded = true;
                if (_success)
                    _success();
            }
        };
        var __failure = function() {
            if (!fail) {
                fail = true;
                if (_failure)
                    _failure();
            }
        };
        for (var i = 0; i < list.length; i++) {
            requires.push(this.requireScript(list[i]));
        }
        if (_success) {
            for (var i = 0; i < requires.length; i++) {
                requires[i].onSuccess(__success);
            }
        }
        if (_failure) {
            for (var i = 0; i < requires.length; i++) {
                requires[i].onFailure(__failure);
            }
        }
        if (!fail) {
            __success();
        }
    };
    for (var i = 0; i < loaded.length; i++) {
        var script = loaded[i];
        if (!this.scripts[script]) {
            this.scripts[script] = new JScript(self, script, true);
        }
    }
    /*   DocumentReady begin */
    var documentReadyEvent = new YAHOO.util.CustomEvent('documentReady');
    documentReadyEvent.subscribe(loadNext);
    this.documentReady = false;
    this.onDocumentReady = function(callback) {
        if (this.documentReady) {
            return callback();
        }
        else {
            documentReadyEvent.subscribe(callback);
        }
    };
    var ready = function() {
        if (!self.documentReady) {
            self.documentReady = true;
            documentReadyEvent.fire();
        }
    };
    YAHOO.util.Event.onDOMReady(function() {

        if (document.all && navigator.userAgent.indexOf("Opera") == -1) {
            var d = window.document;
            (function() {
                try {
                    d.documentElement.doScroll('left');
                } catch (e) {
                    setTimeout(arguments.callee, 50);
                    return;
                }
                ready();
            })();
        } else {
            ready();
        }
    });
    /*   DocumentReady end */
};

function JScript(ScriptLoader, name, loaded, requires) {
    var self = this;
    this.name = name;
    this.loaded = loaded;
    this.wrong = false;
    if (name.indexOf('http://') == 0) {
        this.config = { path: name, requires: requires || [] };
    }
    else {
        this.config = ScriptLoader.config[name];
        if (!this.config) {
            alert('script "' + name + '" is undefined');
            this.config = { path: name, requires: [] };
        }
    }
    this.successEvent = new YAHOO.util.CustomEvent("success");
    this.failureEvent = new YAHOO.util.CustomEvent("failure");
    this.successEvent.subscribe(function() { self.loaded = true; });
    this.failureEvent.subscribe(function() { self.wrong = true; });
    this.onSuccess = function(callback) {
        if (this.loaded) {
            callback();
        }
        else {
            this.successEvent.subscribe(callback);
        }
    };
    this.onFailure = function(callback) {
        if (this.wrong) {
            callback();
        }
        else {
            this.failureEvent.subscribe(callback);
        }
    };

    var ready = function() {
        if (!self.loaded) {
            ScriptLoader.addToQuee(self);
        }
    };
    var fail = function() {
        if (!self.wrong) {
            self.wrong = true;
            self.failureEvent.fire();
        }
    };
    if (!loaded) {
        ScriptLoader.requireScripts(this.config.requires, ready, fail);
    }
}

function formattemplate(tmpl, repls) {

    var res = tmpl.replace(
    /(?:\{\{|\%7B\%7B)(.*?)(?:\}\}|\%7D\%7D)/g,
    function(m) { return getPropertyFromVar(repls, m); }
  );

    return res;

}

function getPropertyFromVar(obj, m, errors) {
    var ret;
    var localobj = obj;


    var props = m.match(/(?:\{\{|%7B%7B)(.*?)(?:\}\}|%7D%7D)/);
    if (props) {
        var proppath = props[1].split(".");
        for (var i = 0; i < proppath.length; i++) {
            localobj = localobj[proppath[i]];
            if (typeof (localobj[proppath[i]]) != "undefined") break;
        }
        /* options typed or untyped json:*/
        ret = (localobj)
         ? ((localobj.content) ? localobj.content : localobj)
         : ((errors) ? "No value for '" + props[1] + "' (" + m + ")" : "");

    } else {
        ret = (errors) ? "No key in '" + m + "'" : "";
    }

    return ret;
}

