
function Request(str, obj, cbk, html_tgt){
	if(cbk==undefined || cbk==null) cbk=function(){};//could wire up to a debug handler if needed
	str=str.split(' ');
	Server.server_post_target = str[0];
	if(obj==null || obj==undefined || Object.keys(obj).length==0){
		obj = {empty:true};
	}
	Server.send(obj, cbk, html_tgt);
}



var Server = {
  send:function(o,cbk,html_tgt){
		 // var sendformdata = this.send_form_data_by_default;//delta later from args if you want
	  var obj_for_server = o;
	  if(html_tgt != null && html_tgt != undefined){
			Loading(html_tgt);
		}
	  // if(sendformdata){
	  // 			var formdata = Server.collect_all_form_data();
	  // 			Object.keys(formdata).collect(function(y){obj_for_server[y]=formdata[y];});
	  // }
	  
	  this.queueup(this.server_post_target, obj_for_server, function(r){
      var obj;
      try{
        obj = eval('('+r+')');
			}catch(ex){
				Fatal("Can't parse JSON: "+r);
				try{
					Loaded(html_tgt);
				}catch(ex){}
				return false;
			}	
			if(obj['site_offline'] != undefined && obj['site_offline'] != null && obj['site_offline'] == true){
				Offline();
				return false;
			}
			Notice.respond(obj);
			if(obj.ok && html_tgt != undefined && html_tgt != null && obj.html != undefined && obj.html != null){
				Loaded(html_tgt);
				$(html_tgt).update(obj.html);
				Card.content_changed();
			}
			if(Window.development_mode){
				cbk(obj);
			}else{
				try{
					cbk(obj);
				}catch(ex){
					Panic();
				}
			}
	  });
	  this.last_cmd = o;
	},
	
	////////////////////////////////////////////////////////////////////////////////////////////////
	//internals below
	//persistent_data:{},//holds the last object passed to the server. probably not very useful, so i removed it
	last_cmd:null,
	
	//xmlhttp object
	xh:false,
	//queue for requests
	queue_being_processed:false,
	/*
	var: xhreq_queue
	Holds XmlHttp requests before they are sent
	*/
	xhreq_queue:[],
	/*
	func: queueup
	Calls send using an object--turns the object into post data. Sends a request to the specified handler with the specified arguments and attached the passed function as the callback
	*/
	queueup:function(handlerpath, argobj, on_request_complete){
		//& in json must be escaped, as must ;, otherwise the server breaks
		this.send_underlying(handlerpath, "obj=" + Object.toJSON(argobj).gsub('&', '%26').gsub(';', '%3B'), on_request_complete);	
	},
	/*
	func: send
	Sends a request to the specified handler with the specified arguments and attached the passed function as the callback. Uses a queue to make sure these async calls don't back up (which they will in FireFox without a queue).

	Remarks:
	send the args to the handlerpath, and add the appropriate folder if it's not part of the handler path

	*/
	send_underlying:function(handlerpath, argstring, on_request_complete){
		this.add_to_queue(handlerpath, argstring, on_request_complete);
	},
	/* func: add_to_queue
	Adds XmlHttp requests to a queue (<xhreq_queue>) because FireFox will throw errors if you send too many at once.
	*/
	add_to_queue:function(handlerpath, argstring, on_request_complete){
		this.xhreq_queue = $A(this.xhreq_queue);
		this.xhreq_queue[this.xhreq_queue.length] = {'handlerpath':handlerpath, 'argstring':argstring, 'on_request_complete':on_request_complete};
	    
		if(!this.queue_being_processed){
			this.queue_being_processed = true;
			this.process_xh_queue();
		}
	},
	process_xh_queue:function(){
		if(this.xhreq_queue.length > 0){
			var reqitem = this.xhreq_queue[0];
			this.sendtoserver(reqitem.handlerpath, reqitem.argstring, reqitem.on_request_complete, function(){
				Server.xhreq_queue = Server.xhreq_queue.without(reqitem);
				Server.process_xh_queue();
			});
		}else{
			this.queue_being_processed = false;
		}
	},
	sendtoserver:function(handlerpath, argstring, on_request_complete, queue_callback){
		try{
			this.xh.open("POST", handlerpath, true);
			this.xh.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
			this.xh.onreadystatechange = function(){
				if(Server.xh.readyState==4){
					on_request_complete(Server.xh.responseText);
					queue_callback();
				}
			};
			this.xh.send(argstring);
		}catch(e){
			Fatal('core::send->' + e.message + "," + e.name + "," + e.stack + "," + e.lineNumber + "," + e.fileName);
		}
	},
  init:function(){
    /*@cc_on @*/
    /*@if (@_jscript_version >= 5)
        try{
          Server.xh = new ActiveXObject("Msxml2.XMLHTTP");
        }catch(e){
          try{
            Server.xh = new ActiveXObject("Microsoft.XMLHTTP");
          }catch(err){
              Server.xh=false;
          }
        }
        @end @*/
    if(!Server.xh && typeof XMLHttpRequest != 'undefined'){
      Server.xh=new XMLHttpRequest();
    }
  }
}













