create = function(){
	P = function(){
		return this.initialize.apply(this, arguments);
	};
	P.prototype.constructor = P;
	return P;
};

XmlHttp = {
	'getXmlHttpObj': function(){
		var XMLHttpObject = false;
		try{
			XMLHttpObject = new XMLHttpRequest();
		}catch(e){
			try{
				XMLHttpObject = new ActiveXObject("Msxml2.XMLHTTP");
			}catch(e){
				try{
					XMLHttpObject = new ActiveXObject("Microsoft.XMLHTTP");
				}catch(e){}
			}
		}
		return XMLHttpObject;
	},
	'option':{
		'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8',
		'encoding': 'Windows-31J'
	}
};


/*
	XmlHttp.Request(method,url,param,state[,header[,timeout]]);
	method	:"GET"もしくは"POST"
	url		:Request先のURL
	param	:連想配列に格納したurlへ渡すパラメーター
			 例:{param1:value1,param2:value2,param3:value3}
	state	:状態毎に実行するメソッド。連想配列形式で格納
			 {onSuccess:成功時のメソッド,
			  onFailure:失敗時のメソッド,
			  onTimeout:タイムアウト時に実行するメソッド,
			  onLoading:読み込み中に実行するメソッド,
			  on+Status:ステータスコード(404,500など)によって処理を分ける場合用いる。
			  			(on404:404のとき,on500:500のとき)
			 }
	header	:連想配列形式のリクエストヘッダー
	timeout	:タイムアウトまでのミリ秒
*/
XmlHttp.Request = create();
XmlHttp.Request.prototype = {
	'initialize': function(){
		return this.xmlHttpRequest(arguments);
	},
	'xmlHttpObj': null,
	'state': null,
	'TimeoutObject': null,
	'xmlHttpRequest': function(){
		var arg = arguments[0];
		var _self = this;
		_self.xmlHttpObj = XmlHttp.getXmlHttpObj();
		if(!_self.xmlHttpObj)
			return false;
		if(arg.length>3 && arg[3]!=null)
			_self.setStatus(_self,arg[3]);
		var option = XmlHttp.option;
		if(arg.length>4){
			for(var i in arg[4])
				option[i] = arg[4][i];
		}
		if(arg.length>5)
			_self.TimeoutObject =
				window.setTimeout(function(){return _self.xmlHttpAbort.apply(_self,[_self]);},arg[5]);
		arg[2] = arg[2]==null?"":_self.paramString(arg[2]);
		if(arg[0]=="GET"){
			arg[1] = arg[1] + "?"+ arg[2];
			arg[2] = "";
		}
		else if(arg[0]!="POST")
			return false;
		_self.xmlHttpObj.open(arg[0],arg[1],true);
		if(arg.length>3 && arg[3]!=null)
			_self.setFunction(_self);
		for(var i in option)
			_self.xmlHttpObj.setRequestHeader(i,option[i]);
		_self.xmlHttpObj.send(arg[2]);
		return true;
	},
	'setFunction': function(_self){
		_self.xmlHttpObj.onreadystatechange = function(){ return _self.getStatus.apply(_self,[_self])};
	},
	'setStatus': function(_self,state){
		_self.state = state;
	},
	'getStatus': function(_self){
		if(_self.xmlHttpObj.readyState!=4){
			if(_self.flgLoading == null || !_self.flgLoading){
				_self.result(_self,"onLoading");
				_self.flgLoading=true;
			}
			return;
		}
		if(_self.TimeoutObject!=null)
			clearTimeout(_self.TimeoutObject);
		var getState = _self.xmlHttpObj.status;
		if(_self.result(_self,"on"+getState))
			return;
		if(getState == 200){
			_self.result(_self, "onSuccess");
			return;
		}
		if(_self.result(_self,"onFailure"));
			return;
		throw 'failure.';
	},
	'result': function(_self, status){
		if(_self.state == null)
			return false;
		if(typeof _self.state[status]=="undefined"||_self.state[status]==null)
			return false;
		_self.state[status].apply(_self,[_self.xmlHttpObj]);
		return true;
	},
	'xmlHttpAbort': function(_self){
		_self.xmlHttpObj.abort();
		if(typeof _self.state['onTimeout']=="undefined"||_self.state['onTimeout']==null)
			return;
		_self.state['onTimeout']();
		clearTimeout(_self.TimeoutObject);
		return;
	},
	'paramString': function (param){
		var str = "";
		for(var i in param){
			str += encodeURI(i) + "=" + encodeURI(param[i]) + "&";
		}
		return str.substr(0,str.length-1);
	}
}
