/*
mino Class Request

coded by : hanulis (hanulis@docircle.com)
date : 2006. 12. 8

about : AJAX Request function
usege : (object) mino.Request(url,params,method,callback[,param1,param2,...])

		param1, param2, ... 등등은 Request후 callback function에 넘겨줄 인자들을 받는다./
		callback function에서는 req(xml original), json, params(array)를 넘겨받는다.

*/

var request_id=1;

var mino_dir_root="";

if(!mino_dir_root) {
	var __scripts=document.getElementsByTagName("script");
	for(var i=0;i<__scripts.length;i++) {
	
		if(__scripts[i].src.match(/mino_request2\.js/)) {
			mino_dir_root=__scripts[i].src.replace(/mino_request2\.js(.*?)$/,"");
			break;
		}
	}
}

var mino_request_xdr_script=new Array();
var mino_request_xdr_transVar=new Array();

function mino_reqeust_xdr_callback(res,id) {
	try {
		var s=document.getElementById("__mino_request_xdr_"+id);
		if(s) s.parentNode.removeChild(s);
	
	} catch(e) {
	
	}
	
	var req={};
	
	if(res) {
		res=Base64.decode(res);
        req.responseText=res;	
		
		if(res.match(/<\?xml/i)) {
            	
            if (window.ActiveXObject){
              var doc=new ActiveXObject('Microsoft.XMLDOM');
              doc.async='false';
              doc.loadXML(res);
              
            } else {
              var parser=new DOMParser();
              var doc=parser.parseFromString(res,'text/xml');
            }
            req.responseXML=doc;

		}
	}
	
	
	if(mino_request_xdr_script[id]) {
		for(var i in mino_request_xdr_script[id]) {

			if(mino_request_xdr_transVar[id]) {
				mino_request_xdr_script[id][i](req,mino_request_xdr_transVar[id]);
			} else {
				mino_request_xdr_script[id][i](req);
			}
		}	
	}
	
	mino_request_xdr_transVar[id]=null;
	delete(mino_request_xdr_transVar[id]);
	
	mino_request_xdr_script[id]=null;
	delete(mino_request_xdr_script[id]);
}

mino_request = {}

mino_request = function() {
	request_id++;
	this.params=new Array();
	this.responseFunc=new Array();
	this.method="POST";
	this.url="";
	this.transVars=new Array();
	this.trycount=1;
	this.timeout=300000;
	this.async=1;
	//this.params = (params == null) ? null : params;
}

mino_request.prototype = {
	addParam:function(name,val) {
		this.params[name]=val;
	},
	
	makeParam:function() {
		var str="";
		for(var i in this.params) {
			if(typeof(this.params[i]) !="function") {
				str+=i+"="+this.params[i]+"&";
			}
		}

		return str;
	},
	
	addResponse:function(fnc) {
		this.responseFunc.push(fnc);
	},
	
	addVar:function(v) {
		this.transVars.push(v);
	},
	
	getXMLHttpRequest: function() {

		var XMLHttpFactories = [
			function () {return new XMLHttpRequest()},
			function () {return new ActiveXObject("Msxml2.XMLHTTP")},
			function () {return new ActiveXObject("Msxml3.XMLHTTP")},
			function () {return new ActiveXObject("Microsoft.XMLHTTP")}
		];

		var xmlhttp = false;
		for (var i=0;i<XMLHttpFactories.length;i++) {
			try {
				xmlhttp = XMLHttpFactories[i]();
			}
			catch (e) {
				continue;
			}
			break;
		}
		
		return xmlhttp;
	},

	encode:function() {
		var result="";
		
		result="params="+Base64.encode(this.makeParam());
		result+="&callback=mino_reqeust_xdr_callback&__request_url="+this.url;
		
		return result;
	},

	send: function() {
		if(this.url.match(/http:\/\//i)) {
			var target_host=this.url.match(/http:\/\/(.*?)\//i)[1];
			if(target_host!=location.host) {
//				this.addParam("__request_url",this.url);
//				this.url=mino_dir_root+"/action/remote_request.php";

				if(this.responseFunc) {
					mino_request_xdr_script[request_id]=this.responseFunc;
				}
				
				if(this.transVars) {
					mino_request_xdr_transVar[request_id]=this.transVars;				
				}
				
				var s=document.createElement("SCRIPT");
				s.id="__mino_request_xdr_"+request_id;
				s.src=mino_dir_root+"/action/remote_request.php?__xmethod="+this.method+"&_xhid="+request_id+"&"+this.encode();
				document.body.appendChild(s);
				
				return;
			}			
		}

		this.req = this.getXMLHttpRequest();

		if(!this.req) alert("failed to request xmlHTTP.");

		var httpMethod = this.method ? this.method : 'GET';
		if (httpMethod != 'GET' && httpMethod != 'POST') httpMethod = 'POST';
		var httpParams = this.makeParam();
		var httpUrl = this.url;
		if (httpMethod == 'GET' && httpParams != null) httpUrl = httpUrl + "?" + httpParams;
		
		//sync or async
		if(this.async==1) this.req.open(httpMethod, httpUrl, true);
		else {
			this.req.open(httpMethod, httpUrl, false);
		}

		this.req.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');

		var request = this;

		this.requestTimer = setTimeout(function() {if(request.trycount==5) {request.req.abort();} else {request.resend();}}, this.timeout);

		if(this.async==1) {
			this.req.onreadystatechange = function() {
				request.onStateChange.call(request);
			}
		}

		this.req.send(httpMethod == 'POST' ? httpParams : null);

		if(this.async!=1) {
			clearTimeout(this.requestTimer);
			if(this.responseFunc) this.callback(this.req,this.responseFunc,this.transVars);
		}
	},

	resend: function() {
		this.trycount++;
		this.send();
	},

	onStateChange: function() {
	
		if(this.req.readyState == 4 && this.req.status==404) {
			var al=new mino.alert();
			al.message="404 not found. ('"+this.url+"')";
			al.open();
			
			return;
		} else if(this.responseFunc) this.callback(this.req,this.responseFunc,this.transVars);
		else {
			if(this.req.readyState == 4) clearTimeout(this.requestTimer);
		}
		return;
	},

	callback: function (req,notifyto,transvars){
		if(req.readyState == 4){
			clearTimeout(this.requestTimer);
			 if(req.status == 200){

				var t=req.responseText;

				if(t.match(/Parse error/)) {
					alert("PHP error\n\n"+t);
					return;
				}

				var t=req.responseXML;
				try
				{
					var err=t.selectSingleNode("//ERRORMESSAGE").firstChild.nodeValue;
					if(err != "success") {
						var al=new mino.alert();
						al.message=err;
						al.open();						
						return;
					}
				}
				catch (e){}

				if(notifyto) {
					for(var i in notifyto) {
						if(transvars) {
							notifyto[i](req,transvars);
						} else {
							notifyto[i](req);
						}
					}
				}
			} else {
				if(req.status=="0" || req.status=="12029" || req.status=="12030" || req.status=="12152") {
					try{
						this.trycount=1;
						this.req.abort();
						this.resend();
 					} catch (e) {
						return false;
					}
				} else {
					var al=new mino.alert();
					al.message='HTTP ERROR:'+req.status+'<br><br>callback Failed.';
					al.open();
				}
			}
		}
	} 
}


var Base64={_keyStr:"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",encode:function(input){var output="";var chr1,chr2,chr3,enc1,enc2,enc3,enc4;var i=0;input=Base64._utf8_encode(input);while(i<input.length){chr1=input.charCodeAt(i++);chr2=input.charCodeAt(i++);chr3=input.charCodeAt(i++);enc1=chr1>>2;enc2=((chr1&3)<<4)|(chr2>>4);enc3=((chr2&15)<<2)|(chr3>>6);enc4=chr3&63;if(isNaN(chr2)){enc3=enc4=64;}else if(isNaN(chr3)){enc4=64;}
output=output+
this._keyStr.charAt(enc1)+this._keyStr.charAt(enc2)+
this._keyStr.charAt(enc3)+this._keyStr.charAt(enc4);}
return output;},decode:function(input){var output="";var chr1,chr2,chr3;var enc1,enc2,enc3,enc4;var i=0;input=input.replace(/[^A-Za-z0-9\+\/\=]/g,"");while(i<input.length){enc1=this._keyStr.indexOf(input.charAt(i++));enc2=this._keyStr.indexOf(input.charAt(i++));enc3=this._keyStr.indexOf(input.charAt(i++));enc4=this._keyStr.indexOf(input.charAt(i++));chr1=(enc1<<2)|(enc2>>4);chr2=((enc2&15)<<4)|(enc3>>2);chr3=((enc3&3)<<6)|enc4;output=output+String.fromCharCode(chr1);if(enc3!=64){output=output+String.fromCharCode(chr2);}
if(enc4!=64){output=output+String.fromCharCode(chr3);}}
output=Base64._utf8_decode(output);return output;},_utf8_encode:function(string){string=string.replace(/\r\n/g,"\n");var utftext="";for(var n=0;n<string.length;n++){var c=string.charCodeAt(n);if(c<128){utftext+=String.fromCharCode(c);}
else if((c>127)&&(c<2048)){utftext+=String.fromCharCode((c>>6)|192);utftext+=String.fromCharCode((c&63)|128);}
else{utftext+=String.fromCharCode((c>>12)|224);utftext+=String.fromCharCode(((c>>6)&63)|128);utftext+=String.fromCharCode((c&63)|128);}}
return utftext;},_utf8_decode:function(utftext){var string="";var i=0;var c=c1=c2=0;while(i<utftext.length){c=utftext.charCodeAt(i);if(c<128){string+=String.fromCharCode(c);i++;}
else if((c>191)&&(c<224)){c2=utftext.charCodeAt(i+1);string+=String.fromCharCode(((c&31)<<6)|(c2&63));i+=2;}
else{c2=utftext.charCodeAt(i+1);c3=utftext.charCodeAt(i+2);string+=String.fromCharCode(((c&15)<<12)|((c2&63)<<6)|(c3&63));i+=3;}}
return string;}}

