// ###    eXtensible Remote Scripting utilities for client(XRS)	###
// ###    programed by Kool.Sk8er.YJ (endy21@naver.com)	###
// ###    Copyright (c) 2006 Millesky.com						###
// ###    All rights reserved.									###

function XRSEnable()
{
	XRS = new _XRS_Object();
}

function XRSExecute(url,method)
{
	var cb, ecb, context;
	var params = new Array;
	var pn = 0;
	var len = XRSExecute.arguments.length;
	for (var i=2; i < len; i++)
		params[pn++] = XRSExecute.arguments[i];

	return XRS.invokeMethod(url, method, params);
}

function XRSGetASPObject(url)
{
	var cb, ecb, context;
	var params = new Array;
	var request = XRS.startRequest(url,'GetServerProxy',params,cb,ecb,context);

	if (request.status == XRS_COMPLETED)
	{
		var server = request.return_value;
		if (typeof(Function) == 'function')
		{
			for (var name in server)
				server[name] = Function('return XRS.invokeMethod(this.location,"' +  name + '",this.' + name + '.arguments);');
		}
		else
		{
			for (var name in server)
				server[name] = eval('function t(p0,p1,p2,p3,p4,p5,p6,p7,p8,p9,pA,pB,pC,pD,pE,pF) { return XRS.invokeMethod(this.location,"' + name + '",this.' + name + '.arguments);} t');
		}
		server.location = url;
		return server;
	}
	alert('XRS ERROR [1200] :\nGetASPObject ¿À·ùÀÔ´Ï´Ù.\n(' + url + ')');
	return null;
}

function XRSCallObject(cb, ecb, context)
{
	this.id = XRS.nextRequestID++;
	this.status = XRS_PENDING;
	this.message = '';
	this.data = '';
	this.return_value = '';
		
	this.callback = cb;
	this.error_callback = ecb;
	this.context = context;

	XRS.requestList[this.id] = this;
}

function _XRS_Object()
{
	HTTP_STATUS_OK = 200;
	WAITING_PERIOD = 100;
	XRS_FAIL = -1;
	XRS_COMPLETED = 0;
	XRS_PENDING = 1;
	XRS_PARTIAL = 2;

	this.httpMethod = "GET";
	this.remoteURL = null;
	this.asyncFunc = null;
	this.syncFlag = false;
	this.httpEquiv = "Content-type:";
	this.content = "text/html";
	this.elements = null;

	this.waitID = 0;
	this.blockMode = false;
	this.nextRequestID = 1;
	this.requestList = new Array;

	/*@cc_on @*/
	/*@if (@_jscript_version >= 5)
		try
		{
			this.XRSProxy = new ActiveXObject("MSXML2.XMLHTTP.3.0");
		}
		catch(e)
		{
			try
			{
				this.XRSProxy = new ActiveXObject("Msxml2.XMLHTTP");
			}
			catch(e)
			{
				try
				{
					this.XRSProxy = new ActiveXObject("Microsoft.XMLHTTP");
				}
				catch(e)
				{
					this.XRSProxy = null;
				}
			}
		}
	@end @*/

	if (this.XRSProxy == null && typeof XMLHttpRequest != "undefined")
		this.XRSProxy = new XMLHttpRequest();

	this.xmlHttp = _XRS_xmlHttp;
	this.startRequest = _XRS_startRequest;
	this.invokeMethod = _XRS_invokeMethod;
	this.setWait = _XRS_setWait;
	this.waitHandler = _XRS_waitHandler;
	this.handleResponse = _XRS_handleResponse;
	this.getRequestID = _XRS_getRequestID;
	this.evaluateRequest = _XRS_evaluateRequest;
	this.buildURL = _XRS_buildURL;
	this.checkArrayType = _XRS_checkArrayType;
	this.parsingArray = _XRS_parsingArray;
}

function _XRS_xmlHttp(requestID)
{
	var request = this.requestList[requestID];

	this.XRSProxy.open(this.httpMethod, this.remoteURL, this.syncFlag);
	try
	{
		this.XRSProxy.setRequestHeader(this.httpEquiv, this.content);
		this.XRSProxy.setRequestHeader("Referer:", this.remoteURL);
	}
	catch(e)
	{}

	try
	{
		if (!this.syncFlag)
		{
			this.XRSProxy.send(this.elements);
			if (this.XRSProxy.status > HTTP_STATUS_OK)
			{
				var errmsg = 'XRS ERROR [1100] :\n¼­¹ö URLÀ» È£ÃâÇÏÁö ¸øÇß½À´Ï´Ù.';
				request.status = XRS_FAIL;
				request.message = errmsg;
			}
			else
			{
				this.handleResponse(this.XRSProxy.responseText);
				this.blockMode = false;
			}
		}
		else
		{
			this.XRSProxy.onreadystatechange = _XRS__onProcessAsync;
			this.XRSProxy.send(this.elements);
		}
	}
	catch(e)
	{
		var errmsg = 'XRS ERROR [1110] :\n¼­¹ö URLÀ» È£ÃâÇÏÁö ¸øÇß½À´Ï´Ù.';
		request.status = XRS_FAIL;
		request.message = errmsg;
	}
}

function _XRS__onProcessAsync()
{
	if (XRS.XRSProxy.readyState == 4)
	{
		XRS.handleResponse(XRS.XRSProxy.responseText);
		XRS.blockMode = false;
	}
}

function _XRS_startRequest(url, method, args, cb, ecb, context)
{
	var request = new XRSCallObject(cb, ecb, context);

	if (this.XRSProxy == null)
	{
		var errmsg = 'XRS ERROR [1000] :\nXRSÅë½ÅÀÌ ÁØºñµÇÁö ¾ÊÀº »óÅÂÀÔ´Ï´Ù.';
		request.status = XRS_FAIL;
		request.message = errmsg; 
	}

	if (request.status != XRS_FAIL)
	{
		url = this.buildURL(request.id, url, method, args);
		url_context = window.location.href;

		if (typeof(cb) == 'function')
		{
			this.syncFlag = true;
			this.setWait(url, request.id);
		}
		else
		{
			this.syncFlag = false;
			this.blockMode = true;
			this.remoteURL = url;
			this.xmlHttp(request.id);
		}
	}
	return request;
}

function _XRS_invokeMethod(url, method, args)
{
	var cb, ecb, context;
	var params = new Array;
	var pn = 0;
	var i = 0;
	for (var i=0; i < args.length; i++)
	{
		if (typeof(args[i]) == 'function')
		{
			pn = -1;
			if (typeof(cb) == 'undefined')
				cb = args[i];
			else
				ecb = args[i];
		}
		else if (pn != -1)
		{
			params[pn++] = args[i];
		}
		else
			context = args[i];
	}

	return XRS.startRequest(url, method, params, cb, ecb, context);
}

function _XRS_setWait(url, requestID)
{
	this.waitID = window.setTimeout("XRS.waitHandler('" + url + "', '" + requestID + "')",WAITING_PERIOD,"javascript");
}

function _XRS_waitHandler(url, requestID)
{
	if (this.XRSProxy.readyState == 0 ||this.XRSProxy.readyState == 4)
	{
		this.blockMode = true;
		this.remoteURL = url;
		this.xmlHttp(requestID);
	}
	else
        this.setWait(url, requestID);
}

function _XRS_handleResponse(responseData)
{
	var request = this.requestList[this.getRequestID(responseData)];
    if (typeof(request) == 'undefined')
		return;

	request.data = responseData;
	request.status = XRS_COMPLETED;
	this.evaluateRequest(request);
	if (request.status == XRS_FAIL)
	{
		if (typeof(request.error_callback) == 'function')
			request.error_callback(request);
	}
	else
	{
		if (typeof(request.callback) == 'function')
			request.callback(request);
	}
	this.requestList[request.id] = null;
}

function _XRS_getRequestID(data)
{
	var start_index = 0;
	var end_index = 0;
	var start_key = '<' + 'RID';
	var end_key = '<' + '/RID>';

	if ((start_index = data.indexOf(start_key)) != -1)
	{
		var data_start_index = data.indexOf('>',start_index) + 1;
		end_index = data.indexOf(end_key,data_start_index);
		if (end_index == -1) 
			end_index = data.length;
		return unescape(data.substring(data_start_index,end_index));
	}
	else
		return -1;
}

function _XRS_evaluateRequest(request)
{
	var data = request.data;
	var start_index = 0;
	var end_index = 0;
	var start_key = '<' + 'RETURN_VALUE';
	var end_key = '<' + '/RETURN_VALUE>';

	if ((start_index = data.indexOf(start_key)) != -1)
	{
		var data_start_index = data.indexOf('>',start_index) + 1;
		end_index = data.indexOf(end_key,data_start_index);
		if (end_index == -1) 
			end_index = data.length;
		var metatag = data.substring(start_index,data_start_index);
		if (metatag.indexOf('TYPE=SIMPLE') != -1)
		{
			var lsDecode;
			lsDecode = decode(data.substring(data_start_index,end_index));
			if (this.checkArrayType(lsDecode))
				request.return_value = this.parsingArray(lsDecode);
			else
				request.return_value = lsDecode;
		}
		else if (metatag.indexOf('TYPE=EVAL_OBJECT') != -1)
		{
			request.return_value = data.substring(data_start_index,end_index);
			request.return_value = eval(decode(request.return_value));
		}
		else if (metatag.indexOf('TYPE=ERROR') != -1)
		{
			request.status = XRS_FAIL;
			request.message = decode(data.substring(data_start_index,end_index));		
		}
	}
	else
	{
		request.status = XRS_FAIL;
		request.message = 'XRS ERROR [3000] :\n ¿äÃ»ÇÑ ¼­¹ö ÆäÀÌÁö´Â XRS¸¦ Áö¿øÇÏÁö ¾Ê½À´Ï´Ù.';			
	}
}

function _XRS__escapePlus(value)
{
	for (var i = 0, newValue = ''; i < value.length; i++)
		newValue += (value.charAt(i) == '+' ? '%2B' : value.charAt(i));
	return newValue;
}

function _XRS_buildURL(rid, url, method, args)
{
	if (url == '') url = window.location.pathname;
	if (typeof(method) == 'string')
	{
		url += '?_rcache=' + RestrictCache() + '&_id=' + rid;
		url += '&_method=' + encode(method);
		url += '&_mtype=execute';
		var params = '&pcount=0';
		if (typeof(args) != 'undefined' && args.length)
		{
			params = '&pcount=' + args.length 
			for (var i = 0; i < args.length; i++) 
			{
				var arg = "" + args[i];
				params += '&p' + i + '=' + _XRS__escapePlus(encode(arg));
			}
		}
		url += params;
	}
	return url;
}

function _XRS_checkArrayType(psData)
{
	if (psData.indexOf('<' + 'ARRAY') != -1 && psData.indexOf('<' + '/ARRAY>') != -1)
		return true;
	else
		return false;
}

function _XRS_parsingArray(psData)
{
	var laUNRow = new Array();
	var liSIdx, liEIdx;
	var liDSIdx;
	var lsSKey = '<' + 'ARRAY DIMENSION=';
	var lsEKey = '<' + '/ARRAY>';

	if ((liSIdx = psData.indexOf(lsSKey)) != -1)
	{
		var re = /<ROW>/g;
		var re2 = /<COL>/g;
		var liDSIdx = psData.indexOf('>', liSIdx) + 1;
		var lsArrayTag = psData.substring(liSIdx, liDSIdx);
		var lsDimension = lsArrayTag.substring(lsSKey.length, liDSIdx -1);

		psData = psData.replace(lsArrayTag, '').replace(lsEKey, '');
		psData = psData.replace(re, '').replace(re2, '');
		psData = eraseTag(psData);
		laUNRow = psData.split('<' + '/ROW>');
		for (var i = 0 ; i < laUNRow.length; i++)
		{
			laUNRow[i] = eraseTag(laUNRow[i]);
			if (lsDimension == '1')
				laUNRow[i] = laUNRow[i];
			if (lsDimension == '2')
			{
				laUNRow[i] = laUNRow[i].split('<' + '/COL>');
				for (var j = 0 ; j < laUNRow[i].length; j++)
					laUNRow[i][j] = laUNRow[i][j];
			}
		}
	}
	return laUNRow;
}

function eraseTag(psData)
{
	while(psData.substring(psData.length-6, psData.length) == '<' + '/COL>' || psData.substring(psData.length-6, psData.length) == '<' + '/ROW>')
		psData = psData.substring(0, psData.length-6);
	return psData;
}

function RestrictCache()
{
	var laVal = "0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z".split(",");
	var lsVal = "";

	lsVal = "";
	for (var i=0; i<25; i++)
		lsVal+=laVal[Math.floor(Math.random()*laVal.length)];
	
	return lsVal;
}

function encode(str)
{
	return base64encode(encodeURL(str));
}

function decode(str)
{
	return decodeURL(base64decode(str));
}

function encodeURL(str)
{
	var s0, i, s, u;
	s0 = "";
	for (i = 0; i < str.length; i++)
	{
		s = str.charAt(i);
		u = str.charCodeAt(i);
		if (s == " ")
		{
			s0 += "+";
		}
		else
		{
			if ( u == 0x2a || u == 0x2d || u == 0x2e || u == 0x5f || ((u >= 0x30) && (u <= 0x39)) || ((u >= 0x41) && (u <= 0x5a)) || ((u >= 0x61) && (u <= 0x7a)))
			{
				s0 = s0 + s;
			}
			else
			{
				if ((u >= 0x0) && (u <= 0x7f))
				{
					s = "0"+u.toString(16);
					s0 += "%"+ s.substr(s.length-2);
				}
				else if (u > 0x1fffff)
				{
					s0 += "%" + (oxf0 + ((u & 0x1c0000) >> 18)).toString(16);
					s0 += "%" + (0x80 + ((u & 0x3f000) >> 12)).toString(16);
					s0 += "%" + (0x80 + ((u & 0xfc0) >> 6)).toString(16);
					s0 += "%" + (0x80 + (u & 0x3f)).toString(16);
				}
				else if (u > 0x7ff)
				{
					s0 += "%" + (0xe0 + ((u & 0xf000) >> 12)).toString(16);
					s0 += "%" + (0x80 + ((u & 0xfc0) >> 6)).toString(16);
					s0 += "%" + (0x80 + (u & 0x3f)).toString(16);
				}
				else 
				{
					s0 += "%" + (0xc0 + ((u & 0x7c0) >> 6)).toString(16);
					s0 += "%" + (0x80 + (u & 0x3f)).toString(16);
				}
			}
		}
	}
	return s0;
}
	
function decodeURL(str)
{
	var s0, i, j, s, ss, u, n, f;
	s0 = "";
	for (i = 0; i < str.length; i++)
	{
		s = str.charAt(i);
		if (s == "+")
		{
			s0 += " ";
		}
		else
		{
			if (s != "%")
			{
				s0 += s;
			}
			else
			{
				u = 0;
				f = 1;
				while (true)
				{
					ss = "";
					for (j = 0; j < 2; j++ )
					{
						sss = str.charAt(++i);
						if (((sss >= "0") && (sss <= "9")) || ((sss >= "a") && (sss <= "f"))  || ((sss >= "A") && (sss <= "F")))
						{
							ss += sss;
						}
						else
						{
							--i;
							break;
						}
					}
					n = parseInt(ss, 16);
					if (n <= 0x7f) {u = n; f = 1;}
					if ((n >= 0xc0) && (n <= 0xdf)) {u = n & 0x1f; f = 2;}
					if ((n >= 0xe0) && (n <= 0xef))	{u = n & 0x0f; f = 3;}
					if ((n >= 0xf0) && (n <= 0xf7))	{u = n & 0x07; f = 4;}
					if ((n >= 0x80) && (n <= 0xbf))	{u = (u << 6) + (n & 0x3f);	--f;}
					if (f <= 1) {break;}
					if (str.charAt(i + 1) == "%") {i++;} else {	break;}
				}
				s0 += String.fromCharCode(u);
			}
		}
	}
	return s0;
}

function base64encode(str)
{
	var out, i, len;
	var c1, c2, c3;
	var base64EncodeChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";

	len = str.length;
	i = 0;
	out = "";
	while(i < len)
	{
		c1 = str.charCodeAt(i++) & 0xff;
		if(i == len)
		{
			out += base64EncodeChars.charAt(c1 >> 2);
			out += base64EncodeChars.charAt((c1 & 0x3) << 4);
			out += "==";
			break;
		}
		c2 = str.charCodeAt(i++);
		if(i == len)
		{
			out += base64EncodeChars.charAt(c1 >> 2);
			out += base64EncodeChars.charAt(((c1 & 0x3)<< 4) | ((c2 & 0xF0) >> 4));
			out += base64EncodeChars.charAt((c2 & 0xF) << 2);
			out += "=";
			break;
		}
		c3 = str.charCodeAt(i++);
		out += base64EncodeChars.charAt(c1 >> 2);
		out += base64EncodeChars.charAt(((c1 & 0x3)<< 4) | ((c2 & 0xF0) >> 4));
		out += base64EncodeChars.charAt(((c2 & 0xF) << 2) | ((c3 & 0xC0) >>6));
		out += base64EncodeChars.charAt(c3 & 0x3F);
	}
	return out;
}

function base64decode(str)
{
	var c1, c2, c3, c4;
	var i, len, out;
	var base64DecodeChars = new Array(
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63,
		52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1,
		-1,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14,
		15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1,
		-1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
		41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1);

	len = str.length;
	i = 0;
	out = "";
	while(i < len)
	{
		/* c1 */
		do {c1 = base64DecodeChars[str.charCodeAt(i++) & 0xff];} while(i < len && c1 == -1);
		if(c1 == -1)
			break;

		/* c2 */
		do {c2 = base64DecodeChars[str.charCodeAt(i++) & 0xff];} while(i < len && c2 == -1);
		if(c2 == -1)
			break;

		out += String.fromCharCode((c1 << 2) | ((c2 & 0x30) >> 4));

		/* c3 */
		do {
			c3 = str.charCodeAt(i++) & 0xff;
			if(c3 == 61)
				return out;
			c3 = base64DecodeChars[c3];
		} while(i < len && c3 == -1);
		if(c3 == -1)
			break;

		out += String.fromCharCode(((c2 & 0XF) << 4) | ((c3 & 0x3C) >> 2));

		/* c4 */
		do {
			c4 = str.charCodeAt(i++) & 0xff;
			if(c4 == 61)
				return out;
			c4 = base64DecodeChars[c4];
		} while(i < len && c4 == -1);
		if(c4 == -1)
			break;
		out += String.fromCharCode(((c3 & 0x03) << 6) | c4);
    }
    return out;
}