newsi.JsodProcess=function(loadPath, processId, feedId, feedName, jsodDataManagerListener, loadFunctionCallback, maxCheckTime) {
	this._json = loadPath;
	this._loadFunc = (loadFunctionCallback == undefined) ? "onLoad" : loadFunctionCallback;
	this._dataManager = jsodDataManagerListener;
	this._processId = processId;
	this._feedId = feedId;
	this._feedName = feedId;
	this._eb = new newsi.EventBroadcaster(this);
	this._maxchecktime = 60;//maxCheckTime;
	// Maybe this should be set by the loadmanager
}
newsi.JsodProcess.prototype = Object;
newsi.JsodProcess.prototype.buildTag = function(){
	
	var instance = this;
	
	global_reference_to_this = this;
	
	//make an element
	var obj = document.createElement("script");
	
	this.addListener(this._dataManager);
	var counter = 0;
	var jsonURL = this._json;
	// IE Workaround -  flag up // 
	if(jsonURL.indexOf("anticache") == -1){
    		jsonURL += "&anticache=" + Math.floor(Math.random() * 1000000);
	}

	obj.setAttribute("type","text/javascript");
	obj.setAttribute("charset", "utf-8");
	obj.setAttribute("id", "feedId_" + this._feedId);
	obj.setAttribute("src",jsonURL);
	
	//attach to the head element
	document.getElementsByTagName("head")[0].appendChild(obj);
	
	window[this._loadFunc] = function (dataobj){
		//instance[instance._loadFunc](dataobj);
		instance._jsodcomplete = true;
		instance.generateResult(true,dataobj);
	}
	
	function loadChecker(){
		
		counter++;

		if(instance._jsodcomplete){
			//pass back the callback
			clearInterval(instance._intervalTimer);
		}
		else if(counter == instance._maxchecktime){
			clearInterval(instance._intervalTimer);
			instance.generateResult(false , null);
			
		}
	}
	
	//start a timer and wait for a result
	this._intervalTimer = setInterval(loadChecker,100);
}
newsi.JsodProcess.prototype.generateResult = function(result, obj){
	
	//package data into object to return
	var broadcastObj = new Object({"success":result,"data":obj,"processId":this._processId,"feedId":this._feedId,"feedName":this._feedName});
	//send it
	this.broadcastMessage('jsodComplete', 
						  broadcastObj);
}
newsi.JsodProcess.prototype.onLoad = function(obj){
	this._jsodcomplete = true;
	this.generateResult(true,obj);
}
newsi.JsodLoadManager=function(loadArray, warnTime, failTime, debugOn, oneOutAllOut) {
	this._loadArray = loadArray;
	this._currentlyLoadingQueuePosition = this._FEEDLISTID = 0;
	this._processQueue = new Array();
	this._recievedProcesses = 0;
	this._listener = new Object();
	this._loopInterval = 100;
	this._timer = 0;
	this._warnTime = Number((warnTime * 1000) / this._loopInterval);
	this._failTime = Number((failTime * 1000) / this._loopInterval);
	this._contentLoadComplete = false;
	this._eb = new newsi.EventBroadcaster(this);
	this._resultJson = new Object();
	this._resultDebug = new Object();
	this._elapsedTime = new Object;
	this._oneOutAllOut = oneOutAllOut;
	this._debugOn = debugOn;
	this._PROCESS_RESULT_OK = "Data Loader successfully recieved JsodProcess ID ";
	this._PROCESS_RESULT_FAIL = "Data Loader failed to load JsodProcess ID ";
}
newsi.JsodLoadManager.prototype.init = function() {
	
	//a local reference to this
	var instance = this;
	
	//is there any data to load
	if(this._loadArray == undefined){
		//abort
		this.broadcastResult('onOperationError', new Object({"level":"fail","description":"No operations to load"}) );
		this.broadcastResult('onComplete', undefined );
		return false;
	}
	else if(!this._hasCapability() ){
		//if test fails, opeartion unsupported
		this.broadcastResult('onOperationError', new Object({"level":"fail","description":"Browser can't support operation"}) );
		this.broadcastResult('onComplete', undefined );
		return false;
	}
	else if(this._warnTime >= this._failTime ){
		//if test fails, opeartion unsupported
		this.broadcastResult('onOperationError', new Object({"level":"fail","description":"Warn time value must be less than fail time value"}) );
		this.broadcastResult('onComplete', undefined );
		return false;
	}
	else if(this._debugOn ){
		//if test fails, opeartion unsupported
		this.broadcastResult('onOperationError', new Object({"level":"warning","description":"Debug switch is on"}) );
	}
	
	//set up the listener to get events back with the status of the load
	this._listener.jsodComplete=function(broadcastObject){	
			//increment the counter
			instance._recievedProcesses++;
			
			//get hold of time lapses
			if(broadcastObject.success){
				//if we are debugging, populate the debug objects with their data
				if(instance._debugOn){
					instance._resultDebug[broadcastObject.feedId]._processTime = Number(new Date() - instance._elapsedTime);
					instance._resultDebug[broadcastObject.feedId]._processResult = true;
					instance._resultDebug[broadcastObject.feedId]._processInfo = instance._PROCESS_RESULT_OK + broadcastObject.feedId;
				}
				else{
					instance._resultDebug[broadcastObject.feedId] = undefined;
				}
				var data = new Object({"content":broadcastObject.data,"id":broadcastObject.feedId,"success":broadcastObject.success});
				//tell the controlling class data is received
				instance.broadcastResult('onData', new Object({"data":data,"debug":instance._resultDebug[broadcastObject.feedId]}) );

			}
			else{
				if(instance._debugOn){
					instance._resultDebug[broadcastObject.feedId]._processTime = Number(new Date() - instance._elapsedTime);
					instance._resultDebug[broadcastObject.feedId]._processResult = false;
					instance._resultDebug[broadcastObject.feedId]._processInfo = instance._PROCESS_RESULT_FAIL + broadcastObject.feedId;
				}
				else{
					instance._resultDebug[broadcastObject.feedId] = undefined;
				}
				var data = new Object({"content":undefined,"id":broadcastObject.feedId,"success":broadcastObject.success});
				//tell the controlling class data is received
				instance.broadcastResult('onData', new Object({"data":data,"debug":instance._resultDebug[broadcastObject.feedId]}) );
				
				if(instance._oneOutAllOut){
					clearInterval(instance._timer);
					instance.broadcastResult('onComplete', undefined );
					return;
				}
			}
			
			if(instance._recievedProcesses < instance._processQueue.length){
				instance.processLoadQueue(instance._processQueue[instance._recievedProcesses]);
			}
			//if it is, write the data and complete the load flag	
			else if(instance._recievedProcesses == instance._processQueue.length){
				clearInterval(instance._timer);
				instance.broadcastResult('onComplete', undefined );
			}
		}
	//start the timer
	this._timer = setInterval(checkLoaded,100);
	

	var counter = 0;
	for (var i = 0; i <  this._loadArray.length; i++){
	
		//create a key in the results data
		this._resultJson[this._loadArray[i].name] = new Object();
		
		//and if debug is on, a key in the debug results
		if(this._debugOn) this._resultDebug[this._loadArray[i].name] = new newsi.JsodDebugObject();
	
		//increment the load queue counter
		this._currentlyLoadingQueuePosition++;
		
		var jsodProcess = new newsi.JsodProcess(this._loadArray[i].url, 
												this._currentlyLoadingQueuePosition,
												this._loadArray[i].name,
												this._loadArray[i].name,
												this._listener,
												(this._loadArray[i].callback == undefined) ? undefined : this._loadArray[i].callback,
												50); 
		this._processQueue.push(jsodProcess);
	}
	
	//start the queue processing				
	this.processLoadQueue(this._processQueue[this._recievedProcesses]);
	
	
	function checkLoaded(){
		
		//increment the counter
		counter++;

		//no load confirmation yet
		if(counter == instance._warnTime){
			//tell the client there has been a warning time exceeded
			instance.broadcastResult('onOperationError', new Object({"level":"warn","description":"Operation not complete warning"}) );
		}
		else if(counter == instance._failTime){	
			//and trigger the error callback
			instance.broadcastResult('onOperationError', new Object({"level":"fail", "description":"Operation not complete timeout"}) );
			instance.broadcastResult('onComplete', undefined );
			clearInterval(instance._timer);
		}
		
	}//end checkLoaded
}
newsi.JsodLoadManager.prototype.broadcastResult = function( type, obj){
	this.broadcastMessage(type,obj);
}
newsi.JsodLoadManager.prototype._hasCapability = function(){

	if(!document.getElementById){
		return false;
	}
	var obj = document.createElement("script");
	obj.setAttribute("type","text/javascript");
	obj.setAttribute("charset", "utf-8");
	obj.setAttribute("id", "jsod_header");
	obj.setAttribute("src","undefined");
	
	
	//get the head element
	document.getElementsByTagName("head")[0].appendChild(obj);
		
	//script tag written, see if it exists
	if(newsi.gebid("jsod_header") ){
		var nde = newsi.gebid("jsod_header");
		//remove
		//CAUSED ERROR IN IE6: document.getElementsByTagName("head")[0].removeChild(nde)
		return true;
	}
	else{
		return false;
	}
}
newsi.JsodLoadManager.prototype.processLoadQueue = function(jsodProcess){
	this._elapsedTime = new Date();
	jsodProcess.buildTag();
}
newsi.JsodLoadManager.prototype.cancelTimer=function(){
	clearInterval(this._timer);
}
newsi.JsodDebugObject=function( time, result, info) {
	this._processTime = time;
	this._processResult = result;
	this._processInfo = info;	
}