function ajax_init_object() {/*{{{*/
	var oHTTP;
	try 
	{
		oHTTP=new ActiveXObject("Msxml2.XMLHTTP");
	}
	catch (e) 
	{
		try 
		{
			oHTTP=new ActiveXObject("Microsoft.XMLHTTP");
		} 
		catch(oc) 	
		{
			oHTTP=null;
		}
	}
	if(!oHTTP && typeof XMLHttpRequest != "undefined")
		oHTTP = new XMLHttpRequest();
	if (!oHTTP)
		alert("Could not create connection object.");
	return oHTTP;
}/*}}}*/
var AjaxInformation = Class.create();
AjaxInformation.prototype = {/*{{{*/
	initialize: function(){
		this.history = 0;
		this.activeCount = 0;
		this.ajaxPool = {};
		this.ajaxRunning = {};
		this.ajaxSaved= null;
		this.ajaxLoginFunctions = {};
		this.cache = {};
		this.lock = false;
	},
	push: function(wingbus){
		var rand = Math.floor(Math.random()*1000);
		var d = new Date();
		d = d.getTime();
		var pid = 'p'+d+rand;
		pid = 'p'+this.history++;
		this.ajaxPool[pid] = wingbus;
		return pid;
	},
	get: function(pid){
		if(this.ajaxPool[pid])
			return this.ajaxPool[pid];
	},
	pop: function(pid){
		if(this.ajaxPool[pid])
		{
			var rturn = this.ajaxPool[pid];
			delete(this.ajaxPool[pid]);
			return rturn;
		}
	},
	save: function(pid){
		this.ajaxSaved = pid;
	},
	removeSaved: function(){
		this.ajaxSaved = null;
	},
	execSaved: function(){
		if(this.ajaxSaved!=null)
			this.ajaxSaved.recall();
	},
	pushLogin: function(strFuncname, strArgs)
	{
		this.ajaxLoginFunctions[strFuncname] = strArgs;
	},
	runLogin: function()
	{
		for(var funcName in this.ajaxLoginFunctions)
			eval(funcName+'('+this.ajaxLoginFunctions[funcName]+');');
	},
	pushCache: function(name, key, oJson)
	{
		if(this.cache[name])
			this.cache[name][key] = oJson;
		else
		{
			this.cache[name] = {};
			this.cache[name][key] = oJson;
		}
	},
	getCache: function(name, key)
	{
		if(typeof(this.cache[name])!='undefined' && typeof(this.cache[name][key]!='undefined'))
			return this.cache[name][key];
		else
			return null;
	},
	clearCache: function(name)
	{
		delete this.cache[name];
	},
	emptyCache: function()
	{
		delete this.cache;
		this.cache = {};
	},
	registRunning: function(wingbus, oAjax)
	{
		if(typeof(this.ajaxRunning[wingbus.methodName])!='undefined')
		{
			var oTarget = this.ajaxRunning[wingbus.methodName];
			this.pop(oTarget.pid);
			oTarget.oAjax.abort();
		}
			this.ajaxRunning[wingbus.methodName] = {};
			this.ajaxRunning[wingbus.methodName].pid= wingbus.pid;
			this.ajaxRunning[wingbus.methodName].oAjax = oAjax;
	},
	removeRunning: function(wingbus)
	{
		if(typeof(this.ajaxRunning[wingbus.methodName])!='undefined')
		{
			delete(this.ajaxRunning[wingbus.methodName]);
		}
	}
}/*}}}*/
var AjaxInfo = new AjaxInformation();

var Ajax = Class.create();
Ajax.prototype = {
	initialize: function(calltype){/*{{{*/
		this.method = 'post';
		this.params = {};
		this.args = new Array();
		this.methodName = null;
		this.returnFunction = null;
		this.baseUrl = '/global/ajax.wbs';
		this.returnType = 'json';
		this.showLoading = true;
		this.loadingMsg = null;
		this.lock = true;
		this.autoHandle = true;
		this.save = true; //save for when need login to exec me
		this.save4login = false; //save for when logged in to refresh page 
		this.form = null;
		this.showRecall = false;
		if(calltype)
			this.callType = calltype;
		else	
			this.callType = 'normal';
		this.cache = false;
	},/*}}}*/
	setArg: function(argName, argVal){/*{{{*/
		this.args.push(argName+'='+encodeURIComponent(argVal)); 
		this.params[argName] = argVal;
	},/*}}}*/
	getArgs: function(){/*{{{*/
		return this.args.join('&');
	},/*}}}*/
	getParams: function(){/*{{{*/
		var retStr = '';
		for(var i in this.params)
			retStr+='_'+this.params[i];
		return retStr;
	},/*}}}*/
	recall: function(){/*{{{*/
		this.call(this.methodName, this.returnFunction);
	},/*}}}*/
	call: function(methodName, returnFunction){/*{{{*/
		//check cache
		if(this.cache)
		{
			var cache = AjaxInfo.getCache(returnFunction.name, this.getParams());
			if(cache!=null)
			{
				returnFunction(cache);
				return;
			}
		}

		this.methodName = methodName;
		this.returnFunction = returnFunction;
		var pid = AjaxInfo.push(this);
		this.pid = pid;
		AjaxInfo.activeCount++;
		var uri = this.baseUrl+'?method='+methodName+'&returnType='+this.returnType+'&pid='+pid;
		if (this.callType=='https')
			uri = 'https://www.wingbus.com' + uri;

		//save for login after
		if(this.save) AjaxInfo.save(this);

		if(this.showLoading && null!=this.loadingMsg)
			ajax_show_loading(this.loadingMsg, this);

		if(this.callType=='normal' || this.callType=='https')
		{
			try {
				var oAjax = ajax_init_object();
				oAjax.open(this.method, uri, true);
				if (this.callType=='https' && typeof oAjax.withCredentials !== "undefined") {
					oAjax.setRequestHeader("X-PINGOTHER", "pingpong");
					oAjax.withCredentials = true;
				}
				else {
					oAjax.setRequestHeader("Method", "POST " + uri + " HTTP/1.1");
				}
				oAjax.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
				var _this = this;
				oAjax.onreadystatechange = function(){
					if (oAjax.readyState != 4)
						return;
					
					//status changed so remove running info
					AjaxInfo.removeRunning(_this);
					
					//check status
					try{
						if(oAjax.status && oAjax.status==200 && oAjax.responseText!='')
						{
							var wingbus_again = AjaxInfo.get(pid);
							ajax_oncomplete_handle(oAjax.responseText, pid);
							oAjax.onreadystatechange = function(){};
							delete oAjax;
						}
						else
						{
							//call again
							var wingbus_again = AjaxInfo.pop(pid);
							if(wingbus_again && oAjax.status!=0)
							{
								wingbus_again.call(wingbus_again.methodName, wingbus_again.returnFunction);
							}
						}
					}catch(e){}
				}
				var postdata = this.getArgs();
				
				//regist running before send
				AjaxInfo.registRunning(this, oAjax);

				oAjax.send(postdata);
				delete postdata;
				delete oAjax;
			}
			catch (e) {
				var oFjax = $('ajaxframe');
				if(!oFjax)
				{
					alert('폼 전송 프레임이 준비되지 않았습니다.');
					return false;
				}
				var oForm = this.form;
				oForm.target = 'ajaxframe';//+ajaxf_frmcnt;
				oForm.action = 'https://www.wingbus.com/global/ajaxf.wbs?method='+methodName+'&returnType='+this.returnType+'&pid='+pid;
				oForm.method = 'POST';
				oForm.submit();	
			}
		}
		else
		{
			var oFjax = $('ajaxframe');
			if(!oFjax)
			{
				alert('폼 전송 프레임이 준비되지 않았습니다.');
				return false;
			}
			var oForm = this.form;
			oForm.target = 'ajaxframe';//+ajaxf_frmcnt;
			oForm.action = '/global/ajaxf.wbs?method='+methodName+'&returnType='+this.returnType+'&pid='+pid;
			oForm.method = 'POST';
			oForm.submit();	
		}
	}/*}}}*/
}

function debug_msg(strStat, strHead, strMsg)/*{{{*/
{
	var oDate = new Date();
	var oTable = $('tblDebug');
	if(!oTable) return;
	var oRow = oTable.insertRow(1);

	var oCell = oRow.insertCell(0);
	oCell.innerHTML = oDate.getHours()+':'+oDate.getMinutes()+' '+oDate.getSeconds()+'.'+oDate.getMilliseconds();
	oCell = oRow.insertCell(-1);
	oCell.innerHTML = strStat;
	oCell = oRow.insertCell(-1);
	oCell.innerHTML = strHead;//'<div style="height:20px;overflow:hidden">'+strHead+'</div>';
	oCell = oRow.insertCell(-1);
	oCell.innerHTML = strMsg!='' ? '<textarea style="width:100%;height:100px;">'+strMsg+'</textarea>' : '';
}/*}}}*/

function ajax_oncomplete_handle(resultString, pid)/*{{{*/
{
	AjaxInfo.activeCount--;
//	if(AjaxInfo.activeCount<=0)
		ajax_hide_loading();

	var wingbus = AjaxInfo.pop(pid);
	
	try{ //execute only when data is correct
	var oResult = eval('('+resultString+')');
	if(oResult.result!='OK')
	{
		if(oResult.result =='LOGIN')
		{
			open_login();
			if(wingbus.save)
				AjaxInfo.ajaxSaved = wingbus;
			return;
		}
		else
		{
			//delete saved
			AjaxInfo.removeSaved();
			if(wingbus.autoHandle)
			{
				ajax_show_error(oResult.errMsg);
				return;
			}
		}
	}
	}catch(e){};

	//save cache
	if(wingbus.cache)
		AjaxInfo.pushCache(wingbus.returnFunction.name, wingbus.getParams(), oResult);
	
	//result to function
	wingbus.returnFunction(oResult);
	delete wingbus;
	delete oResult;
}/*}}}*/

function ajax_show_hide_loading(pid)//(o, pid)/*{{{*/
{
	if(AjaxInfo.activeCount==0)
		ajax_hide_loading();
	var wingbus = AjaxInfo.get(pid);
	if(wingbus)
	{
		if(AjaxInfo.activeCount>0 && wingbus.showLoading)
			ajax_show_loading(wingbus.loadingMsg);
	}
}/*}}}*/
function ajax_create_loading()/*{{{*/
{
	var divLoading = $('divLoading');
	if(!divLoading) return null;
	var oBody = wbs_get_body();

	divLoading.style.top = (oBody.top + oBody.height/2 - 100)+'px';
	var width = (oBody.width>972) ? 972 : oBody.width;
	divLoading.style.left = (oBody.left + width/2 - 140)+'px';
	
//	ajax_show_cover();
	return divLoading;
}/*}}}*/
function ajax_show_cover()/*{{{*/
{
	var divCover = $('divCover');
	if(!divCover)
	{
		divCover = document.createElement('div');
		document.body.appendChild(divCover);
		divCover.setAttribute('id', 'divCover');
		divCover = $('divCover');
	}
	divCover.style.height = (document.body.scrollHeight+'px');
	divCover.style.display = 'block';
}/*}}}*/
function ajax_show_loading(msg, wingbus)/*{{{*/
{
	var divLoading = ajax_create_loading();
	if(!divLoading) return;
	if(msg)
	{
		$('liLoadingMsg').update(msg);
		$('liLoadingMsg').show();
		if(window.intRecall) clearTimeout(window.intRecall);
		if(wingbus && wingbus.showRecall)
		{
			$('btnAjaxRecall').onclick = function(){
				wingbus.recall();
				return false;
			};
			window.intRecall = setTimeout(function(){$('divAjaxRecall').show();}, 30000);
		}
		$('divAjaxRecall').hide();
	}
	else
	{
		$('liLoadingMsg').update('');
		$('liLoadingMsg').hide();
		$('divAjaxRecall').hide();
		if(window.intRecall) clearTimeout(window.intRecall);
	}
	divLoading.show();
}/*}}}*/
function ajax_hide_loading()/*{{{*/
{
	var divLoading = $('divLoading');
	var divCover = $('divCover');
	if(divLoading)
		$('divLoading').hide();
	if(divCover)
		$('divCover').hide();
}/*}}}*/
function ajax_onlogin_handle()/*{{{*/
{
	var savedAjax = AjaxInfo.saved;
	if(savedAjax==null) return;
}/*}}}*/
function ajax_show_error(msg)/*{{{*/
{
	alert(msg);
}/*}}}*/





function ajax_get_nodedata(oNode, tagName, idx)/*{{{*/
{
	if(!idx) idx=0;
	try
	{
		if(oNode.getElementsByTagName(tagName).item(idx).firstChild)
			return oNode.getElementsByTagName(tagName).item(idx).firstChild.data;
	}
	catch(e)
	{
		show_magic_alert(tagName+','+idx);
		return null;
	}
}/*}}}*/

function ajaxf_receive_call(handler, strXML, returnType)/*{{{*/
{
	var re = /wextarea/gim;
	strXML = strXML.replace(re, 'textarea');

	var myDocument;
	if(returnType=='xml')
	{
		if (document.implementation.createDocument){
			// Mozilla 에서 DOMParser 를 이용한다.
			var parser = new DOMParser();
			myDocument = parser.parseFromString(strXML, "text/xml");
		} else if (window.ActiveXObject){
			// IE 에서 XMLDOM 객체를 이용한다.
			myDocument = new ActiveXObject("Microsoft.XMLDOM")
			myDocument.async="false";
			myDocument.loadXML(strXML);
		}
		var result = ajax_get_nodedata(myDocument, 'result');
	}
	else
	{
		myDocument = eval('('+strXML+')');
		var result = myDocument.result;
	}

	if(result!='OK')
	{
		if(result=='LOGIN')
		{
			open_login();
		}
		else
		{
			var msg = ajax_get_nodedata(myDocument, 'msg');
			if(msg!='')
				show_magic_alert(msg);
		}	
	}
	else
	{
		handler(myDocument);
	}
}/*}}}*/


