sapiRequest={
	setup:function(){
		var defaultTimeout=30;
		var requests=new Array();

		_defCallback=function(){ return true; }

		_setupCallbacks=function(callbacks){
			if(!callbacks) callbacks=new Object();
			if(!callbacks.onError) callbacks.onError=_defCallback;
			if(!callbacks.onCancel) callbacks.onCancel=callbacks.onError;
			if(!callbacks.onTimeout) callbacks.onTimeout=callbacks.onError;
			if(!callbacks.onSubmit) callbacks.onSubmit=_defCallback;
			if(!callbacks.onStarted) callbacks.onStarted=_defCallback;
			if(!callbacks.onDone) callbacks.onDone=_defCallback;
			return callbacks;
		}

		_isFormAlreadyRequested=function(o){
			for(var cnt=0;cnt<requests.length;cnt++)
				if(requests[cnt].form==o)
					return true;
			return false;
		}

		_isUrlAlreadyRequested=function(o){
			for(var cnt=0;cnt<requests.length;cnt++)
				if(requests[cnt].url==o)
					return true;
			return false;
		}

		sapiRequest.submitForm=submitForm=function(form,callbacks,userData){
			if(!form) return false;
			if(_isFormAlreadyRequested(form)) return false; 
			var objectToHide=form;
			if(arguments.length>3) objectToHide=arguments[3];
			callbacks=_setupCallbacks(callbacks);
			if(callbacks.onSubmit(userData)===false) return false;
			var httprequest=_GetXmlHttp();
			if(!httprequest){
				callbacks.onError(userData);
			} else {
				var o=new _RequestForm(form,callbacks,defaultTimeout*1000,userData,httprequest,objectToHide);
				requests.push(o);
			};
		}

		sapiRequest.submitUrl=submitUrl=function(url,callbacks,userData){
			if(!url) return false;
			if(_isUrlAlreadyRequested(url)) return false; 

			var objectToHide=null;
			if(arguments.length>3) objectToHide=arguments[3];
//			if(!objectToHide) objectToHide=document.getElementById("pages");
			callbacks=_setupCallbacks(callbacks);
			if(callbacks.onSubmit(userData)===false) return false;
			var httprequest=_GetXmlHttp();
			if(!httprequest){
				callbacks.onError(userData);
			} else {
				var o=new _RequestUrl(url,callbacks,defaultTimeout*1000,userData,httprequest,objectToHide);
				requests.push(o);
			};
		}

		_hideObject=function(o){
			if(o)
				o.style.visibility="hidden";
			return(o);
		}
		_showObject=function(o){
			if(o)
				o.style.visibility="visible";
			return(o);
		}

		_RequestForm=function(form,callbacks,timeout,userData,httprequest,objectToHide){
			this.objectToHide=_hideObject(objectToHide);

			this.form=form;
			this.httprequest=httprequest;
			this.callbacks=callbacks;
			this.userData=userData;
			var d=new Date();
			this.endtime=d.getTime()+timeout;
			if(!timeout) this.endtime=0;
			var url=this.form.action;
			var method=this.form.method.toUpperCase();
			var params="rnd="+d.getTime()+"&snark=1";

			var e=this.form.elements;
			for(var cnt=0;cnt<e.length;cnt++){
				var o=e[cnt];
				var t=o.type.toUpperCase();
				var p="";
				switch(t){
					case "CHECKBOX":
						if(o.checked){
							p=o.name+"="+encodeURIComponent(o.value);
						} else {
							p=o.name+"=";
						};
					break;
					case "RADIO":
						if(o.checked)
							p=o.name+"="+encodeURIComponent(o.value);
					break;
					case "BUTTON":
					case "IMAGE":
					case "SUBMIT":
					case "RESET":
					break;
					default:
						p=o.name+"="+encodeURIComponent(o.value);
					break;
				};
				if(p){
					if(params) params+="&";
					params+=p;
				};
			};

			if(method=="GET"){
				if(params)
					url+="?"+params;
				params=null;
			};
			try{
				this.httprequest.open(method,url,true);
				if(method=="POST")
					this.httprequest.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');	

				this.callbacks.onStarted(this.userData);
				this.httprequest.send(params);
				if(!timer)
					timer=setInterval(_onInterval,100);
			} catch (e) {
				_showObject(this.objectToHide);
				this.callbacks.onError(this.userData);
			}

		}

		_RequestUrl=function(url,callbacks,timeout,userData,httprequest,objectToHide){
			this.url=url;
			this.objectToHide=_hideObject(objectToHide);
			this.httprequest=httprequest;
			this.callbacks=callbacks;
			this.userData=userData;
			var d=new Date();
			this.endtime=d.getTime()+timeout;
			if(!timeout) this.endtime=0;

			var params="rnd="+d.getTime()+"&snark=1";
			var mask=/\?/;
			if(mask.test(url)){
				url+="&"+params;
			} else {
				url+="?"+params;
			};

			try{
				this.httprequest.open("GET",url,true);
				this.callbacks.onStarted(this.userData);
				this.httprequest.send(null);
				if(!timer)
					timer=setInterval(_onInterval,100);
			} catch (e) {
				_showObject(this.objectToHide);
				this.callbacks.onError(this.userData);
			}
		}

		_onInterval=function(){
			var buf=new Date();
			var t=buf.getTime();
			buf="";
			for(var cnt=0;cnt<requests.length;cnt++){
				try{
					var o=requests[cnt];
					if(!o.endtime){
						requests[cnt]=null;
						o.endtime=0;
						o.httprequest.abort();
						o.httprequest=null;
						_showObject(request[cnt].objectToHide);
						continue;
					}
					if(o.httprequest.readyState != 4){
						if(o.endtime<t){
							o.endtime=0;
							o.httprequest.abort();
							o.httprequest=null;
							o.callbacks.onTimeout(o.userData);
							_showObject(o.objectToHide);
							requests[cnt]=null;
						}
					} else {
						if(o.httprequest.status == 200){
							o.endtime=0;
							sapiRequest.serverDebugCatch(o.httprequest.responseText);
							o.callbacks.onDone(o.userData,o.httprequest.responseText);
							o.httprequest=null;
							_showObject(o.objectToHide);
							requests[cnt]=null;
						} else if(o.httprequest.status){
							o.endtime=0;
							o.callbacks.onError(o.userData);
							o.httprequest=null;
							_showObject(o.objectToHide);
							requests[cnt]=null;
						} else {
							dputs("what the hell?!");
						};
					};
				} catch(e) {
					dputs("Error in _onInterval");
					dputo(e);
				}
			};
			var a=new Array();
			for(var cnt=0;cnt<requests.length;cnt++)
				if(requests[cnt])
					a.push(requests[cnt]);
			requests=a;
			if(requests.length==0){
				clearInterval(timer);
				timer=0;
			};
		}
		sapiRequest.serverDebugCatch=serverDebugCatch=function(txt){
/*
			try{
				var o=eval("("+txt+")");
				if(o.phpdebug){
dputs("}Server Debug");
dputs(o.phpdebug);
dputs("Server Debug{");
				};
								
			} catch(e){
dputs(txt);
dputs("Server Debug catch Error: can't parse server responce");
			}
*/
		}

		sapiRequest.Destroy=Destroy=function(){
			if(timer){
				clearInterval(timer);
				timer=0;
				for(var cnt=0;cnt<requests.length;cnt++){
					var o=requests[cnt];
					o.httprequest.abort();
					o.httprequest="";
					o.callbacks.onCancel(o.userData);
					requests[cnt]="";
				}

			};
			timer=0;	
		}

		_GetXmlHttp=function(){
			var xmlhttp;
			try {
				xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
			} catch (e) {
				try {
					xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
				} catch (E) {
					xmlhttp = false;
				}
			}
			if (!xmlhttp && typeof XMLHttpRequest!='undefined') {
				xmlhttp = new XMLHttpRequest();
			}
			return xmlhttp;
		}

//start the heart
		var timer=0;

		dropEvent=function(e){
			if(!e) e=window.event;
			e.cancelBubble=false;
			e.returnValue=false;
			if(e.preventDefault)		
				e.preventDefault()
			return false;			
		}

	}
}

sapiRequest.setup();