var RequestManager = (function(){
		var oManager = {
			DEFAULT_PRIORITY : 10,
			INTERVAL : 250,
			AGE_LIMIT : 6000,
			
			_active : new Array(),
			
			_pending : new PriorityQueue(function(oRequest1, oRequest2){
											return oRequest1.priority - oRequest2.priority;
										}),
			
			_state	:	'waiting',
			
			_onworking : function(){return false;},
			
			_oncomplete	: function(){return false;},
			
			_agePromote : function(){
					for(var i=0; i < this._pending.size();i++)
					{
						var oRequest = this._pending.item(i);
						oRequest.age += this.INTERVAL;
						if(oRequest.age >= this.AGE_LIMIT)
						{
							oRequest.age = 0;
							oRequest.priority--;
						}
						this._pending.prioritize();
					}
				},
			
			_stateChange : function(){					
					if(this._active.length > 0 && this._state == "waiting")
					{
						this._state = "working";
						this._onworking();
					}
					else if(this._active.length == 0 && this._state == "working")
					{							
						this._state = "waiting";
						this._oncomplete();
					}
				},
			
			
			_checkActiveRequests : function() {
					var oRequest = null;
					var oTransport = null;
					
					for(var i=this._active.length-1; i >= 0; i--)
					{
						oRequest = this._active[i];
						oTransport = oRequest.transport;
						
						if(typeof oRequest.onstream == "function")
						{		
							fnCallBack = oRequest.onstream;
							if(oTransport.responseText)
							{
								setTimeout((function(fnCallBack, oRequest, oTransport){
												 return function(){
													 fnCallBack.call(oRequest.scope||window,{
																	 status : oTransport.status,
																	 data : oTransport.responseText,
																	 request : oRequest});
												 }
												 
											})(fnCallBack, oRequest, oTransport), 1);
							}
						}
						if(oTransport.readyState == 4)
						{
							oRequest.active = false;
							this._active.splice(i,1);
							var fnCallBack = null;
							if(oTransport.status >= 200 && oTransport.status < 300)
								if(typeof oRequest.onsuccess == "function")
									fnCallBack = oRequest.onsuccess;
							else if(oTransport.status == 304)
								if(typeof oRequest.onnotmodified == "function")
									fnCallBack = oRequest.onnotmodified;
							else
								if(typeof oRequest.onfailure == "function")
									fnCallBack = oRequest.onfailure;
									
							if(fnCallBack != null)
							{
								setTimeout((function(fnCallBack, oRequest, oTransport){
												 return function(){
													 fnCallBack.call(oRequest.scope||window,{
																	 status : oTransport.status,
																	 data : oTransport.responseText,
																	 request : oRequest});
												 }
												 
											})(fnCallBack, oRequest, oTransport), 1);
							}
						}
					}
				},
			
			_createTransport : function() {
					if(typeof XMLHttpRequest != "undefined")
						return new XMLHttpRequest();
					else if(typeof ActiveXObject != "undefined")
					{
						var oHttp = null;
						try{
							oHttp = new ActiveXObject('MSXML2.XmlHttp.6.0');
							return oHttp;
						} catch(oEx) {
							try{
								oHttp = new ActiveXObject('MSXML2.XmlHttp.3.0');
								return oHttp;
							}catch(oEx){
								throw Error("Cannot create XMLHttp object.");
							}
						}
					}
				},
			
			_sendNext : function(){
					if(this._active.length < 2)
					{
						var oRequest = this._pending.get();
						if(oRequest != null)
						{
							this._active.push(oRequest);
							oRequest.transport = this._createTransport();
							oRequest.transport.open(oRequest.type,oRequest.url,true);
							oRequest.transport.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
							oRequest.transport.send(oRequest.data);
							oRequest.active = true;
						}
					}
				},
			
			enabled : function(){
					try{
						this._createTransport();
						return true;
					} catch(oEx){
						return false;
					}
			},
			
			cancel : function(oRequest){
					if(!this._pending.remove(oRequest))
					{
						oRequest.transport.abort();
						
						if(this._active[0] === oRequest)
							this._active.shift();
						else if(this._active[1] === oRequest)
							this._active.pop();
						
						if(typeof oRequest.oncancel == "function")
							oRequest.oncancel.call(oRequest.scope||window,{request : oRequest});
					}
				},
			
		/*	stream : function(oRequest){
				
					oRequest.priority = 0;
					
					oRequest.active = false;
					oRequest.age = 0;
					this._pending.put(oRequest);					
				},	*/
			send : function(oRequest){
					if(typeof oRequest.priority != "number")
						oRequest.priority = this.DEFAULT_PRIORITY;
					
					oRequest.active = false;
					oRequest.age = 0;
					this._pending.put(oRequest);
				},
				
			poll : function(oRequest){
					oRequest.priority = 3;
					this.send(oRequest);
				},
				
			prefetch : function(oRequest){
					oRequest.priority = 5;
					this.send(oRequest);
				},
				
			submit : function(oRequest){
					oRequest.priority = 0;
					this.send(oRequest);
				},
				
			submitPart : function(oRequest){
					oRequest.priority = 2;
					this.send(oRequest);
				},
					
				
			setWorkingFuncs	: function(oFuncs){			
					if(typeof oFuncs.onworking == "function")
						this._onworking = oFuncs.onworking;
					if(typeof oFuncs.oncomplete == "function")
						this._oncomplete = oFuncs.oncomplete;
				}
		};
		
		
		setInterval(function(){
				RequestManager._checkActiveRequests();
				RequestManager._sendNext();
				RequestManager._agePromote();
				RequestManager._stateChange();
			},oManager.INTERVAL);
							 
		
		return oManager;
	})();