var ch = ch || {};
ch.exm = ch.exm || {};
if(typeof ch.exm.Loader === "undefined"){

    ch.exm.Loader = {
	    wgtNum: 0,
	    storedWidgets: [],
	    transport: null,
	    readyWgt: 0,
	    currentTab: 0,
	    _wcount: 0,
	    _onloadAry: [],
	    loadedSources: [],
        _loadNext: function(){
            var p = this.parameters,
                wgtsToLoad = p["widgets"],
                w = wgtsToLoad[this._wcount]
            ;
            if(!w || this.isLoaded(w["name"] + w["version"])){ return; }
	        document.write("<script "   +
                   "type='text/javascript' " +
                   "src='"                   +
                   p["wgtBaseUrl"]           +
                   "/"                       +
                   w["name"]                 +
                   w["version"]              +
                   ".js"                     +
                   "'></script>"
            );
	        this._wcount++;

	        this.loadedSources.push(w["name"] + w["version"]);
	        
        },
	    isLoaded: function(src){
		    var ret = false;
			for(var i = 0, l = this.loadedSources.length; i < l; i++){
				this.loadedSources[i] === src && (ret = true);
			}
		    return ret;
	    },
	    hideAll: function(){
			for(var i = 0, l = this.storedWidgets.length; i < l; i++){
				this.storedWidgets[i].hide();
			}
	    },
        _loadDeps: function(){
            var p = this.parameters,
                d = p.dependencies
            ;
            for(var i = 0, l = d.length; i < l; i++){
	            if(!this.isLoaded(d[i]["name"])){
		            document.write("<scr" + "ipt "   +
		                   "type='text/javascript' " +
		                   "src='"                   +
		                   p["wgtBaseUrl"]           +
		                   "/"                       +
		                   d[i]["name"]                 +
		                   ".js"                     +
		                   "'><\/script>"
		            );
		            this.loadedSources.push(d[i]["name"]);
	            }
            }
            document.write("<scr" + "ipt "   +
                   "type='text/javascript' " +
                   ">ch.exm.Loader.startup()<\/scr" + "ipt>"
            );
        },
        _init: function(){
            this.getParameters();
            this._loadDeps();
        },
        startup: function(){
            this._loadNext();
            this.wgtNum = this.parameters["widgets"].length;
            // widget construction: script tags
        },
        getWgtById: function(/** String */ wId){
            var wgt = null;
            for(var i = 0, l = this.storedWidgets.length; i < l; i++){
                (this.storedWidgets[i].wgtId === wId) && (wgt = this.storedWidgets[i]);
            }
            return wgt;
        },
        register: function(/** Widget */ wgt){
            var wpos = this.storedWidgets.push(wgt) - 1;
            wgt.parameters = this.parameters["widgets"][wpos]["params"];
            wgt.wgtId = this.parameters["widgets"][wpos]["id"];
            wgt.startup.call(wgt);
            this._loadNext();
            return wpos;
        },
        cback: function(/** Object */ args){
            var id = args.id,
                method  = args.method
            ;
            // aggiungere un livello di complessità nella servlet, l'envelop
            this.getWgtById(id)[method](args);
        },
        _setupTabs: function(){
            var p = this.parameters,
                tabs = p.tabs
	        ;
            if(!tabs){ return }
            var tl = tabs.length,
                self = this,
                m = self.fnMap,
                t,
                ct,
                tx,
                clickHandler = function(x){
                    return function(){
                        for(var j = 0; j < tl; j++){
                            ct = document.getElementById(tabs[j]["id"]);
                            ct.className = ct.className.replace(/selected/g, "");
                        }
                        tx = document.getElementById(tabs[x]["id"]);
                        tx.className = tx.className + " selected";
                        if(self.currentTab != x){
                            self.currentTab = x;
                            var wgt = self.getWgtById(tabs[x].wgt);
                            wgt.execute(tabs[x].action, wgt);
                        }
                    };
                }
	        ;
            this._defaultTab = p["defaultTab"] || 0;
            for(var i = 0; i < tl; i++){
                t = document.getElementById(tabs[i]["id"]);
                t.onclick = clickHandler(i);
            }
	        this.hideAll();
	        this.storedWidgets[this._defaultTab].show();
            tabs.length && clickHandler(this._defaultTab)();
        },
        notify: function(/** Object */ args){
            var status = args.status;
            switch(status){
                case "ready":
                    this.readyWgt++;
                break;
                default:
                break;
            }
            (this.readyWgt === this.wgtNum) && this._onLoad();
        },
        _onLoad: function(){
            this._setupTabs();
	        for(var i = 0, ary = this._onloadAry, l = ary.length; i < l; i++){
		        ary[i].shift()();
	        }
	        this.onLoad = function(fn){
		        fn();  
	        };
        },
        onLoad: function(fn){
	        this._onloadAry.push(fn);
        },
        getData: function(/** Object */ args){
            var id = args.id,
                cback = args.cback,
                url = args.url,
                envelop = args.envelop,
                t = args.ownTransport ? null : this.transport
            ;
            var paramString = "";
            for(var i in envelop){
                paramString += i + ":\"" + envelop[i] + "\"" + ",";
            }
            if(paramString.length){
                paramString = paramString.substring(0, paramString.length - 1) + ",";
            }

            t && t.parentNode.removeChild(t);
            t = document.createElement("script");
            t.type = "text/javascript";
            t.src = url + "&jsonp=ch.exm.Loader.cback({id:'" + id + "',method:'" + cback + "'," + paramString + "data:\"";
            document.getElementsByTagName("head")[0].appendChild(t);
        },
        getParameters: function(){
            var scripts = document.getElementsByTagName("script"),
                cs = null,
                src = "",
                pattern = "/suggester/loader/loader.js",
                p = ""
            ;
            for(var i = 0, l = scripts.length; i < l; i++){
                cs = scripts[i];
                src = cs.src;
                if(src.lastIndexOf(pattern) == (src.length - pattern.length)){
                    p = cs.getAttribute("params");
                    this.parameters = p ? eval("(" + p + ")") : {};
                }
            }
        }
    };
    ch.exm.Loader._init();
}    
