/* ------------------------------------------- Ajax Part --------------------------------------------- */
function cs_xmlHttp(){
	this.config				// Parameter Object
	/* ------ Loading ------ */
	this.loading = true;	// [enable | disable] Loading
	this.loading_msg = "";	// Loading Message
	this.loading_img = "<img src='/images/loading2.gif' style=\"vertical-align:middle;\" />";	// Loading Image
	this.loading_box = "";
	/* ------- Cache ------ */
	this.cache = false;		// [enable | disable] Cache
	this.cache_res = [];	// Cache Result
	this.cache_key = "";	
	
	this.multi = false;		// false = Abort Previous Request
	this.xmlObj = null;
	this.xmlObj = (window.XMLHttpRequest)? new XMLHttpRequest() : new ActiveXObject("Microsoft.XMLHTTP");
	
	// this.get(<config>); | this.post(<config>); -> config คือ object ที่ส่งมา รูปแบบการใช้งาน เช่น obj_req.get({url:"test.asp", trg_id:"result"});
	// {url:"test.asp", trg_id:"result"} -> เขียน object แบบย่อ โดยมี Property ตามด้านล่าง(ตัวเล็กทั้งหมด)
	// url=[url ที่ต้องการ Request ไป], parameters=[ชื่อตัวแปร[|=|]ค่าตัวแปร เช่น id[|=|]9[|&|]name[|=|]somsak], trg_id=[id ของ Element ที่ต้องการให้แสดงผล], 
	// statement=[function หรือ statement ที่ต้องการให้รันหลังจาก Response complete กรณีต้องรอผลลัพธ์จาก Request ตัวแรก, กรณีมีมากกว่า 1 statement ให้ใส่ ; คั่น]
	// is_elm_name=[true | false กรณี ที่เป็นต้องการ set element หลายๆ ตัวให้ใส่ trg_id เป็น name แทน id],
	// delay=[ค่าหน่วงเวลาก่อนการรัน statement (เป็นวินาที)]
	// *** parameters มีสัญลักษณ์พิเศษคือ [|=|] คือ เครื่องหมายเท่ากับ และ [|&|] คือ เครื่องหมายคั่นตัวแปร
	this.get = function (config){
		// Initial config
		this.config = config;
		// Set default values on config
		this.def("parameters", ""); 
		this.def("statement", "");
		this.def("delay", 0);
		this.def("is_elm_name", false);
		
		if(typeof(this.config.trg_id)!="undefined" && this.config.trg_id!=''){
			// Encode Parameters
			this.config.parameters = this.encode_para(this.config.parameters);
			if(this.config.parameters!=""){ this.config.parameters = "?" + this.config.parameters; }
			
			// Cache
			this.cache_key = "ch_"+encodeURIComponent(this.config.url)+'_'+encodeURIComponent(this.config.parameters);
			if(this.cache && this.config.parameters.length <= 1000 && this.cache_res[this.cache_key]){
				if(this.cache_res.length > 50){ this.cache_res = []; }	// Limit only 50 cache
				this.set_data(this.config.trg_id, this.cache_res[this.cache_key], this.config.is_elm_name);
				return true;
			}
			// Loading
			if(this.loading == true){
				if (this.loading_box != ""){
					this.set_data(this.config.trg_id, this.loading_box, this.config.is_elm_name);
				}
				else{
					this.set_data(this.config.trg_id, this.loading_msg + " " +this.loading_img, this.config.is_elm_name);
				}
			}
			// Abort Previous Request
			if(!this.multi){ this.abort(); }
			
			var self = this;
			this.xmlObj.onreadystatechange = function(){
				var obj_xml = self.xmlObj || this.xmlObj;
				if (obj_xml.readyState==4 || obj_xml.readyState=="complete"){
					// Set Result
					self.set_data(self.config.trg_id, obj_xml.responseText, self.config.is_elm_name);
					// Add Result to Cache
					if(self.cache && self.cache_key.length <= 1000){ self.cache_res[self.cache_key] = obj_xml.responseText; }
					if(typeof(self.config.statement)!='undefined'){ 
						if(self.config.delay && obj_xml.responseText!=""){		
							var i;
							var arr_stm = self.config.statement.split(";");
							self.config.statement = "";
							for(i=0; i<arr_stm.length; i++){
								if(arr_stm[i].replace(/(^\s+)|(\s+$)/gi, "")!=""){ self.config.statement += "eval("+arr_stm[i]+"); " ; }
							}
							var timer = setTimeout(self.config.statement, (self.config.delay*1000));
						}else{
							eval(self.config.statement); 
						}
					}
				} 
			};
			
			this.xmlObj.open('GET', this.config.url+this.config.parameters, true);
			this.xmlObj.send(null);
		}
	};
	
	// this.post(<config>); -> config คือ object ที่ส่งมา รูปแบบการใช้งาน เช่น obj_req.get({url:"test.asp", trg_id:"result"});
	// {url:"test.asp", trg_id:"result"} -> เขียน object แบบย่อ โดยมี Property ตามด้านล่าง(ตัวเล็กทั้งหมด)
	// url=[url ที่ต้องการ Request ไป], parameters=[ชื่อตัวแปร[|=|]ค่าตัวแปร เช่น id[|=|]9[|&|]name[|=|]somsak], trg_id=[id ของ Element ที่ต้องการให้แสดงผล], 
	// statement=[function หรือ statement ที่ต้องการให้รันหลังจาก Response complete กรณีต้องรอผลลัพธ์จาก Request ตัวแรก, กรณีมีมากกว่า 1 statement ให้ใส่ ; คั่น]
	// is_elm_name=[true | false กรณี ที่เป็นต้องการ set element หลายๆ ตัวให้ใส่ trg_id เป็น name แทน id],
	// delay=[ค่าหน่วงเวลาก่อนการรัน statement (เป็นวินาที)]
	// *** parameters มีสัญลักษณ์พิเศษคือ [|=|] คือ เครื่องหมายเท่ากับ และ [|&|] คือ เครื่องหมายคั่นตัวแปร
	this.post = function (config){
		// Initial config
		this.config = config;
		// Set default values on config
		this.def("parameters", ""); 
		this.def("statement", "");
		this.def("delay", 0);
		this.def("is_elm_name", false);
		
		if(typeof(this.config.trg_id)!="undefined" && this.config.trg_id!=''){
			// Encode Parameters
			this.config.parameters = this.encode_para(this.config.parameters);
		
			// Cache
			this.cache_key = "ch_"+encodeURIComponent(this.config.url)+'_'+encodeURIComponent(this.config.parameters);
			if(this.cache && this.config.parameters.length <= 1000 && this.cache_res[this.cache_key]){
				if(this.cache_res.length > 50){ this.cache_res = []; }	// Limit only 50 cache
				this.set_data(this.config.trg_id, this.cache_res[this.cache_key], this.config.is_elm_name);
				return true;
			}
			// Loading
			if(this.loading == true){
				if (this.loading_box != ""){
					this.set_data(this.config.trg_id, this.loading_box, this.config.is_elm_name);
				}
				else{
					this.set_data(this.config.trg_id, this.loading_msg + " " +this.loading_img, this.config.is_elm_name);
				}
			}
			// Stop Previous Request
			if(!this.multi){ this.abort(); }
			
			var self = this;
			this.xmlObj.onreadystatechange = function(){
				var obj_xml = self.xmlObj || this.xmlObj;
				if (obj_xml.readyState==4 || obj_xml.readyState=="complete"){
					// Set Result
					self.set_data(self.config.trg_id, obj_xml.responseText, self.config.is_elm_name);
					// Add Result to Cache
					if(self.cache && self.cache_key.length <= 1000){ self.cache_res[self.cache_key] = obj_xml.responseText; }
					if(typeof(self.config.statement)!='undefined'){
						if(self.config.delay && obj_xml.responseText!=""){		
							var i;
							var arr_stm = self.config.statement.split(";");
							self.config.statement = "";
							for(i=0; i<arr_stm.length; i++){
								if(arr_stm[i].replace(/(^\s+)|(\s+$)/gi, "")!=""){ self.config.statement += "eval("+arr_stm[i]+"); " ; }
							}
							var timer = setTimeout(self.config.statement, (self.config.delay*1000));
						}else{
							eval(self.config.statement); 
						}	
					}
				} 
			};	

			this.xmlObj.open('POST', this.config.url, true);
			this.xmlObj.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
			this.xmlObj.setRequestHeader("Content-length", this.config.parameters.length);
			this.xmlObj.setRequestHeader("Connection", "close");
			this.xmlObj.send(this.config.parameters);
		}
	};
	
	this.set_data = function (elm_name, value, is_elm_name){
		if(is_elm_name){
			var obj = document.getElementsByName(elm_name);
			var i;
			for(i in obj){
				obj[i].innerHTML = value;
			}
		}else{
			var obj = document.getElementById(elm_name);
			obj.innerHTML = value;
		}
	};
	
	this.encode_para = function (parameters){
		if(parameters==""){ return ""; }
		var arr_para = parameters.split("[|&|]");
		for(i in arr_para){
			arr_para[i] = arr_para[i].split("[|=|]")[0] + "=" + encodeURIComponent(arr_para[i].split("[|=|]")[1]);
		}
		return arr_para.join("&");
	};
	
	this.abort = function (){
		this.xmlObj.abort();
		this.xmlObj = (window.XMLHttpRequest)? new XMLHttpRequest() : new ActiveXObject("Microsoft.XMLHTTP");
	};
	
	this.def = function (prop, def){
		if(typeof(this.config[prop])=="undefined"){ this.config[prop] = def; }
	};
}