/* Adds console to browsers with disabled firebug or without it */
if (!window.console || !console.firebug) {
  window.console = {};
  var names = ["log", "debug", "info", "warn", "error", "assert", "dir", "dirxml", "group", "groupEnd", "time", "timeEnd", "count", "trace", "profile", "profileEnd"];
  for (var i = 0, len=names.length; i < len; i++) {
    window.console[names[i]] = function() {};
  }
}



epiton={
	log:null,
	homePath: "http://commerce.wsj.com",
	register:{},
	Registration:function(eid){
		var _eid=eid;
		var _waitDeps=null;
		
		this.getEid=function(){return _eid;}
		this.setWaitDependancies=function(waitDeps){
			_waitDeps=waitDeps;
		}
		this.getWaitDependancies=function(){return _waitDeps;}
	},
	RunQueue:function(){
		function WaitMap(){
			var count=0;
			var map={};
			
			this.addWaitItem=function(key){
				if(map[key]==undefined){
					map[key] = false;
					count++;
				}
			}
			this.remWaitItem=function(key){
				if(map[key]==false){
					count--;
					map[key] = true;
					if(count==0){
						return true;
					}
				}
				return false;
			}
			this.isReady=function(){
				return count==0;
			}
		}
		
		var execQueue=new Array();
		var initQueue=new Array();
		var preInitQueue=new Array();
		
		//wait required code dependancies
		var depMap=new WaitMap();
		
		//wait post dependancy map for wait initializing after startup
		var reqMap=new WaitMap();
		
		var runFunctionQueue=function(funcQueue){
			epiton.log.debug("{Epiton:runFunctionQueue}: Execute");
			var _pop=undefined;
			while((_pop=funcQueue.pop())!=undefined){
				try {
            		_pop();
           		} catch(e) {
                	epiton.log.error("{Epiton:runFunctionQueue} error: %o", e);
           		}
			}
    	}
		
		//adds function to post ready queue or runs immediatly if already ready
		var addFunctionToQueue=function(funcQueue, execFunc){
			if(depMap.isReady()&&reqMap.isReady()){
				try {
					epiton.log.debug("{Epiton:addFunctionToQueue}: Execute");
					execFunc();
				} catch(e) {
					epiton.log.error("{Epiton:addFunctionToQueue} error: %o", e);
				}
			}else{
				funcQueue.push(execFunc);
			}
		}
		
		
		this.addRequiredItem=function(key){
			reqMap.addWaitItem(key);
		}
		
		this.remRequiredItem=function(key){
			if(reqMap.remWaitItem(key)&&depMap.isReady()){
				runFunctionQueue(execQueue);
			}
		}
		
		this.remDependancyItem=function(key){
			if(depMap.remWaitItem(key)){ //if all code loaded
				runFunctionQueue(preInitQueue); //run app preInits
				runFunctionQueue(initQueue); //run app inits
				if(reqMap.isReady()){		//is all required app inits done
					runFunctionQueue(execQueue); //run execs
				}
			}
		}
		this.addDependancyItem=function(key){
			depMap.addWaitItem(key);
		}
		
	
		this.runOnReady=function(execFunc){
			addFunctionToQueue(execQueue,execFunc);
		}
		this.initOnReady=function(initFunc){
			addFunctionToQueue(initQueue,initFunc);
		}
		this.preInitOnReady=function(preInitFunc){
			addFunctionToQueue(preInitQueue,preInitFunc);
		}
	},
	classloader:{
		runQueue:null,

		setLoaded : function(dkey) {
			epiton.log.info("{Epiton:classloader.setLoaded}: "+dkey);
			this.runQueue.remDependancyItem(dkey);
		},
		addDependancy: function(dkey){
			epiton.log.info("{Epiton:classloader.addDependancy}: "+dkey);
			this.runQueue.addDependancyItem(dkey);
			//document.write('<scr'+'ipt type="text/javascript" src="'+epiton.homePath+'/epiton/js/'+dkey+'.js">' + '<\/script>');
			
			var jsNode = document.createElement("script");
     			jsNode.type = "text/javascript";
     			jsNode.src  = epiton.homePath+"/epiton/js/"+dkey+".js";
 			if (document.getElementsByTagName("head").length == 0) {
  				var headNode = document.createElement("head");
    			document.getElementsByTagName("html")[0].appendChild(headNode);
  			}
      		document.getElementsByTagName("head")[0].appendChild(jsNode);
		},
		require: function(rkey){
			epiton.log.info("{Epiton:classloader.require}: "+rkey);
			this.runQueue.addRequiredItem(rkey);
		},
		setRequireLoaded: function(rkey){
			epiton.log.info("{Epiton:classloader.setRequireLoaded}: "+rkey);
			this.runQueue.remRequiredItem(rkey);
		}
	},
	runOnReady: function(runfunc){
		this.classloader.runQueue.runOnReady(runfunc);
	},
	preInitOnReady: function(preinitfunc){
		this.classloader.runQueue.preInitOnReady(preinitfunc);
	},
	initOnReady: function(initfunc){
		this.classloader.runQueue.initOnReady(initfunc);
	},
	addEpitonRegistration: function(er){
		epiton.register[er.getEid]=er;
	},
	displayEpitonDetails:function(){
		for (var p in epiton.register) {
			alert(p);
		}
	},	
	setup: function(){
		this.classloader.runQueue=new epiton.RunQueue();
		this.log=new function(){
			var stack=new Array();
			
			function log_function(msg,e){
				stack.push(msg);
			}
			function error_function(msg,e){
				log_function(msg);
				console.error(msg,e);
			}
	
			this.error=error_function;
			this.warn=log_function;
			this.log=log_function;
			this.debug=log_function;
			this.info=log_function;
			
			this.toString=function(){
				var ret="";
				for(var i=0;i<stack.length;i++){
					ret+=stack[i]+"\r\n";  		
				}
				return ret;
			}
		}();
	}
};
epiton.setup();
epiton.classloader.require("KernelComplete");
epiton.classloader.addDependancy("context");
epiton.classloader.addDependancy("gui");
epiton.classloader.setRequireLoaded("KernelComplete");
