﻿/*
!!! POST 방식은 XML을 만들 때 
NameIn, ValueIn, SqlDbTypeIn, SizeIn을 다 넘겨야 하는데 현재 코드는 Name="Value" 형식으로 넘기므로
실제 서버 호출시 파라미터가 없다고 에러 남.
서버에서는 XML을 로드해야만 Name="Value" 방식인지 여부를 알수 있으므로 이 방식을 인정하는 방식은 보류함.
*/

var CXmlClientSelectEventArgs = function ()
{
	this.Tag = null;
	this.ErrMsg = "";
	this.Url = "";
	this.DataSet = new Array();
	this.DataTable = new CDataTable();
	this.aParamOut = new Array();
};
var CXmlClientUpdateEventArgs = function ()
{
	this.Tag = null;
	this.ErrMsg = "";
	this.Url = "";
	this.ReturnValue = 0;
	this.aParamOut = new Array();
};

var DbParameter = function (ParameterName, Value)
{
	this.ParameterName = ParameterName;
	this.Value = Value;
};
var DbParameter2 = function (ParameterName, DbType, Size)
{
	this.ParameterName = ParameterName;
	this.DbType = DbType;
	this.Size = Size;
};
var SqlDbType =
{
	Bit: "Bit",
	Char: "Char",
	DateTime: "DateTime",
	Int: "Int",
	Money: "Money",
	NChar: "NChar",
	NVarChar: "NVarChar",
	VarChar: "VarChar",
	Date: "Date",
	Time: "Time"
};
var OracleType =
{
	Char: "Char",
	DateTime: "DateTime",
	NChar: "NChar",
	Number: "Number",
	NVarChar: "NVarChar",
	VarChar: "VarChar"
};

var CXmlClient = function (UrlSelect, UrlUpdate, DbServerType, DbName, IsGet)
{
	this.mSessionId = "";

	this.drNullString = "<<null>>";

	this.mRequest = CXml.GetXMLHttpRequest();

	this.mUrlSelect = UrlSelect;
	this.mUrlUpdate = UrlUpdate;
	this.mDbServerType = DbServerType;
	this.mDbName = DbName;
	this.mIsGet = IsGet;

	this.OnSelectCompleted = null;
	this.OnUpdateCompleted = null;
};

CXmlClient.prototype.ExecSelect = function (SpName, aParamIn, Tag)
{
	var Param = this.GetParamByMethod(SpName, aParamIn);
	if (Param == "")
	{
		return null;
	}

	if (this.mIsGet)
	{
		var Url = this.mUrlSelect + "?" + Param;
		this.mUrl = Url;
		this.DoGet(true, Url, Tag);
	}
	else
	{
		this.DoPost(true, this.mUrlSelect, Param, Tag);
	}
};

CXmlClient.prototype.ExecUpdate = function (SpName, aParamIn, Tag)
{
	var Param = this.GetParamByMethod(SpName, aParamIn);
	if (Param == "")
	{
		return null;
	}

	if (this.mIsGet)
	{
		var Url = this.mUrlUpdate + "?" + Param;
		this.mUrl = Url;
		this.DoGet(false, Url, Tag);
	}
	else
	{
		this.DoPost(false, this.mUrlUpdate, Param, Tag);
	}
};

CXmlClient.prototype.GetSelectResult = function (XDoc, aParamOutIs)
{
	var NODE_ELEMENT = 1;

	var Body = XDoc.documentElement;

	this.FillParamOutByAttribute(XDoc, aParamOutIs);

	var aNodeColumns = Body.getElementsByTagName("columns");
	var aNodeRows = Body.getElementsByTagName("rows");

	var adt = new Array();
	for (var nData = 0; nData < aNodeColumns.length; nData++)
	{
		var Columns = aNodeColumns[nData];
		var Rows = aNodeRows[nData];

		var dt = new CDataTable();

		//필드 이름
		var cl = -1;
		for (var i = 0; i < Columns.childNodes.length; i++)
		{
			var ElemCol = Columns.childNodes[i];
			if (ElemCol.nodeType != NODE_ELEMENT)
				continue;

			var ColName = ElemCol.attributes.getNamedItem("Name").value;

			//필드 이름을 지정하지 않으면 오라클의 경우 필드값이 필드이름이 되는 경우 있음.
			if (!isNaN(ColName))
			{
				ColName = "col" + ColName;
			}
			dt.Columns[++cl] = ColName;
		}
		dt.ColumnCount = dt.Columns.length;

		//레코드 값
		var rw = -1;
		for (var i = 0, i2 = Rows.childNodes.length; i < i2; i++)
		{
			var ElemRow = Rows.childNodes[i];
			if (ElemRow.nodeType != NODE_ELEMENT)
				continue;

			var CurAttrs = ElemRow.attributes;
			dt.Rows[++rw] = new Object();
			for (var j = 0, j2 = CurAttrs.length; j < j2; j++)
			{
				var Value = CurAttrs[j].value;
				if (Value == this.drNullString)
					Value = null;

				dt.Rows[rw][dt.Columns[j]] = Value;
			}
		}
		dt.RowCount = dt.Rows.length;

		adt.push(dt);
	} //nData

	return adt;
};

CXmlClient.prototype.FillParamOutByAttribute = function (XDoc, aParamOutIs)
{
	var Body = XDoc.documentElement;
	if (Body == null)
	{
		var ErrMsg = "documentElement가 없습니다.";
		throw (ErrMsg);
	}

	var CurAttrs = Body.attributes;

	var ReturnValue = 0;
	var ErrMsg = "";

	for (var i = 0, i2 = CurAttrs.length; i < i2; i++)
	{
		var Name = CurAttrs[i].nodeName;

		var Value = CurAttrs[i].value;
		if (Value == this.drNullString)
			Value = null;

		switch (Name)
		{
			case "ReturnValue":
				ReturnValue = parseInt(Value, 10);
				break;
			case "ErrMsg":
				ErrMsg = Value;
				break;
			default:
				aParamOutIs[Name] = Value;
				break;
		}
	}

	if (ErrMsg)
	{
		throw (ErrMsg);
	}

	return ReturnValue;
};

CXmlClient.prototype.GetParamByMethod = function (SpName, aParamIn)
{
	if (aParamIn && (!aParamIn[0]))
	{
		var ErrMsg = "aParamIn이 Array 형식이 아닙니다.";
		throw (ErrMsg);
	}

	var ParamList = "";
	var XWriter = new CXmlWriter();

	if (this.mIsGet)
	{
		ParamList += "SessionId=" + this.mSessionId;
		ParamList += "&NullString=" + this.drNullString;
		ParamList += "&DbServerType=" + this.mDbServerType;
		ParamList += "&DbName=" + this.mDbName;
		ParamList += "&SpName=" + SpName;
	}
	else
	{
		XWriter.WriteStartElement("body");
		XWriter.WriteAttributeString("SessionId", this.mSessionId);
		XWriter.WriteAttributeString("NullString", this.drNullString);
		XWriter.WriteAttributeString("DbServerType", this.mDbServerType);
		XWriter.WriteAttributeString("DbName", this.mDbName);
		XWriter.WriteAttributeString("SpName", SpName);
	}


	if (aParamIn)
	{
		for (var i = 0, i2 = aParamIn.length; i < i2; i++)
		{
			var oParamCur = aParamIn[i];
			if (typeof (oParamCur) != "object")
			{
				var ErrMsg = "aParamIn의 " + (i + 1) + "번째 값이 object 형식이 아닙니다.";
				throw (ErrMsg);
			}

			var Value = oParamCur.Value;
			if (Value == null)
			{
				Value = this.drNullString;
			}
			else if (CValid.IsDateType(Value))
			{
				var dt = CDateTime.GetDateTimeInfo(Value);
				Value = dt.yyyy + "-" + dt.mm + "-" + dt.dd + " " + dt.hh + ":" + dt.nn + ":" + dt.ss;
			}
			else if (typeof (Value) == "boolean")
			{
				Value = (Value == true) ? "1" : "0";
			}

			if (this.mIsGet)
			{
				ParamList += "&" + oParamCur.ParameterName + "=" + escape(Value);
			}
			else
			{
				//@ 제거
				var ParamName = oParamCur.ParameterName;
				if (ParamName.substr(0, 1) == "@")
					ParamName = ParamName.substr(1);

				XWriter.WriteAttributeString("Key", ParamName);
			}
		}
	}

	if (this.mIsGet)
	{
		//"&ValueIn0=     "와 같이 마지막이 스페이스로 끝나면 자동으로 삭제되므로 &를 붙임.
		ParamList += "&";

		return ParamList;
	}
	else
	{
		XWriter.WriteEndElement();
		XWriter.Close();
		return XWriter.ToString();
	}
};

CXmlClient.prototype.DoGet = function (IsSelect, Url, Tag)
{
	if ((this.mRequest.readyState == 4) || (this.mRequest.readyState == 0))
	{
		this.mRequest.open("GET", Url, true);

		this.HandleEvent(IsSelect, Tag);

		this.mRequest.send(null);
	}
};
CXmlClient.prototype.DoPost = function (IsSelect, Url, ParamXml, Tag)
{
	if ((this.mRequest.readyState == 4) || (this.mRequest.readyState == 0))
	{
		this.mRequest.open("POST", Url, true);

		this.mRequest.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
		this.mRequest.setRequestHeader("Content-length", ParamXml.length);
		this.mRequest.setRequestHeader("Connection", "close");

		this.HandleEvent(IsSelect, Tag);

		this.mRequest.send(ParamXml);
	}
};
CXmlClient.prototype.HandleEvent = function (IsSelect, Tag)
{
	var xc = this;

	if (IsSelect)
	{
		xc.mRequest.onreadystatechange = function ()
		{
			//ie 6에서 안되어 주석
			//if (this.readyState == 4)
			if (xc.mRequest.readyState == 4)
			{
				xc.ResponseProceedSelect(Tag);
			}
		}
	}
	else
	{
		xc.mRequest.onreadystatechange = function ()
		{
			//ie 6에서 안되어 주석
			//if (this.readyState == 4)
			if (xc.mRequest.readyState == 4)
			{
				xc.ResponseProceedUpdate(Tag);
			}
		}
	}
};

CXmlClient.prototype.ResponseProceedSelect = function (Tag)
{
	if (this.OnSelectCompleted != null)
	{
		var XDoc = this.mRequest.responseXML;
		var aParamOutIs = new Object();

		var evt = new CXmlClientSelectEventArgs();
		if (this.mIsGet)
			evt.Url = this.mUrl;
		evt.Tag = Tag;

		try
		{
			var adt = this.GetSelectResult(XDoc, aParamOutIs);
			evt.DataSet = adt;
			evt.DataTable = adt[0];

			evt.aParamOut = aParamOutIs;
		}
		catch (ex)
		{
			evt.ErrMsg = ex;
		}

		this.OnSelectCompleted(evt);
	}
};
CXmlClient.prototype.ResponseProceedUpdate = function (Tag)
{
	if (this.OnUpdateCompleted != null)
	{
		var XDoc = this.mRequest.responseXML;

		var aParamOutIs = new Object();

		var evt = new CXmlClientUpdateEventArgs();
		if (this.mIsGet)
			evt.Url = this.mUrl;
		evt.Tag = Tag;

		try
		{
			var ReturnValue = this.FillParamOutByAttribute(XDoc, aParamOutIs);
			evt.ReturnValue = ReturnValue;
			evt.aParamOut = aParamOutIs;
		}
		catch (ex)
		{
			evt.ErrMsg = ex;
		}

		this.OnUpdateCompleted(evt);
	}
};

/*
<?xml version="1.0" encoding="utf-8"?>
<return ReturnValue="0" RowCountIs="9" TestIs="test" SessionId="" />

<?xml version="1.0" encoding="utf-8" ?> 
<body SessionId="" ReturnValue="0" V_CURSOR="<<null>>">
	<columns>
		<column Name="section_type" AllowDbNull="1" DataType="System.String" /> 
		<column Name="exam_part" AllowDbNull="1" DataType="System.String" /> 
		<column Name="exam_type" AllowDbNull="1" DataType="System.String" /> 
		<column Name="title" AllowDbNull="1" DataType="System.String" /> 
		<column Name="description" AllowDbNull="1" DataType="System.String" /> 
		<column Name="content" AllowDbNull="1" DataType="System.String" /> 
		<column Name="question" AllowDbNull="1" DataType="System.String" /> 
		<column Name="example_1" AllowDbNull="1" DataType="System.String" /> 
		<column Name="example_2" AllowDbNull="1" DataType="System.String" /> 
		<column Name="example_3" AllowDbNull="1" DataType="System.String" /> 
		<column Name="example_4" AllowDbNull="1" DataType="System.String" /> 
		<column Name="extra" AllowDbNull="1" DataType="System.String" /> 
		<column Name="answer" AllowDbNull="1" DataType="System.String" /> 
		<column Name="example_direction" AllowDbNull="1" DataType="System.String" /> 
		<column Name="mp3_name" AllowDbNull="1" DataType="System.String" /> 
		<column Name="mp3_text" AllowDbNull="1" DataType="System.String" /> 
	</columns>
	<rows>
		<row SECTION_TYPE="1" EXAM_PART="1" EXAM_TYPE="Normal" TITLE="<<null>>" DESCRIPTION="<b>Part1 : Question 1-5</b><BR>Directions: In Part I, you will hear five short conversations between a man and a woman. Choose the best response for the man or woman. There will be four possible answers for each question. Please note that you will not be able to read the answer choices in this part. You will hear the conversation only once, so please listen carefully." CONTENT="Woman:<br>Man:<br>Woman:<br>Man:<br>Woman: _______________________________" QUESTION="<<null>>" EXAMPLE_1="a)" EXAMPLE_2="b)" EXAMPLE_3="c)" EXAMPLE_4="d)" EXTRA="<<null>>" ANSWER="1" EXAMPLE_DIRECTION="V" MP3_NAME="1" MP3_TEXT="mp3 text" /> 
	</rows>
</body>

<?xml version="1.0" encoding="UTF-8" ?> 
<body SessionId="" ReturnValue="0">
	<columns>
		<column Name="CountAll" AllowDbNull="1" DataType="System.Int32" /> 
		<column Name="RowNumber" AllowDbNull="1" DataType="System.Int64" /> 
		<column Name="RowNumberFull" AllowDbNull="1" DataType="System.Int64" /> 
		<column Name="Seq" AllowDbNull="1" DataType="System.Int32" /> 
		<column Name="GroupSeq" AllowDbNull="1" DataType="System.Int32" /> 
		<column Name="Title" AllowDbNull="1" DataType="System.String" /> 
		<column Name="Depth" AllowDbNull="1" DataType="System.Int32" /> 
	</columns>
	<rows>
		<row CountAll="11" RowNumber="1" RowNumberFull="1" Seq="1" GroupSeq="1" Title="카메라" Depth="0" /> 
		<row CountAll="11" RowNumber="2" RowNumberFull="2" Seq="4" GroupSeq="1" Title="E-P1" Depth="1" /> 
		<row CountAll="11" RowNumber="3" RowNumberFull="3" Seq="2" GroupSeq="2" Title="렌즈" Depth="0" /> 
		<row CountAll="11" RowNumber="4" RowNumberFull="4" Seq="5" GroupSeq="2" Title="17mm" Depth="1" /> 
		<row CountAll="11" RowNumber="5" RowNumberFull="5" Seq="6" GroupSeq="2" Title="14-42mm" Depth="1" /> 
		<row CountAll="11" RowNumber="6" RowNumberFull="6" Seq="7" GroupSeq="2" Title="어댑터" Depth="1" /> 
		<row CountAll="11" RowNumber="7" RowNumberFull="7" Seq="3" GroupSeq="3" Title="악세사리" Depth="0" /> 
		<row CountAll="11" RowNumber="8" RowNumberFull="8" Seq="8" GroupSeq="3" Title="전자플래시" Depth="1" /> 
		<row CountAll="11" RowNumber="9" RowNumberFull="9" Seq="9" GroupSeq="3" Title="광학파인더" Depth="1" /> 
		<row CountAll="11" RowNumber="10" RowNumberFull="10" Seq="10" GroupSeq="3" Title="보호필터" Depth="1" /> 
		<row CountAll="11" RowNumber="11" RowNumberFull="11" Seq="11" GroupSeq="3" Title="스트랩 / 자킷" Depth="1" /> 
	</rows>
</body>
*/

