
var s_EXE_CORE = 0;
var s_EXE_BLOCK = 1;
var s_EXE_FORM = 2;
var s_EXE_DECL_VAR = 3;
var s_EXE_FUNC = 4;
var s_EXE_COND = 5;
var s_EXE_IF = 6;
var s_EXE_WHILE = 7;
var s_EXE_ASSIGN = 8;
var s_EXE_EXPR = 9;
var s_EXE_CONTROL = 10;
var s_EXE_BREAK = 11;
var s_EXE_CONTINUE = 12;
var s_EXE_RETURN = 13;
var s_EXE_END = 14;
var s_EXE_END_FUNC = 15;
var s_EXE_END_IF = 16;
var s_EXE_END_WHILE = 17;

/**
 * CExeCore 클래스 
 */
function CExeCore ()
{
	this.m_nNextExeId = StdCore._INIT_WVALUE;
	
	this.m_objOwnerBlock = null;
	this.m_objNextExecute = null;
}

CExeCore.prototype.ExeCore = function (nNextExeId)
{
	this.m_nNextExeId = nNextExeId; 
}

CExeCore.prototype.setOwnerBlock = function (pOwnerBlock)
{
	this.m_objOwnerBlock = pOwnerBlock;
}

CExeCore.prototype.getOwnerBlock = function ()
{
	return this.m_objOwnerBlock;
}

CExeCore.prototype.queryExecute = function (nExeId)
{
	var objFormExe = this.getFormExe();
	var objExecute = null;
	if (null == objFormExe || null == (objExecute = objFormExe.getExecute(nExeId)))
	{
		return null;
	}
	
	return objExecute;
}

CExeCore.prototype.getFormExe = function()
{
	if (null == this.m_objOwnerBlock)
	{
		return this;
	}
	
	return this.m_objOwnerBlock.getFormExe();
}

CExeCore.prototype.getNextExecute = function ()
{
	if (null == this.m_objNextExecute && StdCore._INIT_WVALUE != this.m_nNextExeId)
	{
		this.m_objNextExecute = this.queryExecute(this.m_nNextExeId);
	}
	
	return this.m_objNextExecute;
}

CExeCore.prototype.queryExprExe = function (nExprExeId)
{
	var pExprExe = null;
	if (null == this.m_objOwnerBlock || null == (pExprExe = this.m_objOwnerBlock.getExprExe(nExprExeId)))
	{
		return null;
	}
	
	return pExprExe;
}
	
CExeCore.prototype.queryExprItem = function (nExprItemId)
{
	var objExprItem = null;
	if (null == this.m_objOwnerBlock || null == (objExprItem = this.m_objOwnerBlock.getExprItem(nExprItemId)))
	{
		return null;
	}

	objExprItem.setFormExe(this.getFormExe());
	objExprItem.initialize(this);
	
	return objExprItem;
}

CExeCore.prototype.querySymbol = function (nExeId, nSymbolId)
{
	var objBlockExe = null;
	if (-1 == nExeId)
	{
		objBlockExe = this.getFormExe();
	}
	else
	{
		objBlockExe = this.queryExecute(nExeId);
	}

	try
	{
		if (null != objBlockExe && objBlockExe instanceof CBlockExe)
		{
			return objBlockExe.getSymbol(nSymbolId);
		}
	}
	catch (e)
	{
		//throw PQScriptException.create(this, PQExceptionMessage.s_PQScript_FailExecuteScript, e);
	}
	
	return null;
}

CExeCore.prototype.releaseTempSymbol = function (objSymbol)
{
	var objFormExe = this.getFormExe();
	if (null != objFormExe)
	{
		objFormExe.releaseTempSymbol(objSymbol);
	}
}


/**
 * CBlockExe 클래스
 */
function CBlockExe ()
{
	this.m_strType = "CBlockExe";
	this.m_objExprExeTable;
	this.m_objExprItemTable;
}

CBlockExe.prototype = new CExeCore();
CBlockExe.prototype.constructor = CBlockExe;

CBlockExe.prototype.BlockExe = function (nNextExeId,  objExprExeTable, objExprItemTable)
{
	this.m_objExprExeTable = objExprExeTable;
	this.m_objExprItemTable = objExprItemTable;
	
	this.ExeCore(nNextExeId);
}

CBlockExe.prototype.getExeKind = function ()
{
	return s_EXE_BLOCK;
}

CBlockExe.prototype.getExprExe = function (nExeId)
{
	return this._lookupTable(this.m_objExprExeTable, nExeId);
}

CBlockExe.prototype.getExprItem = function (nExprItemId)
{
	return this._lookupTable(this.m_objExprItemTable, nExprItemId);
}

CBlockExe.prototype._lookupTable = function (arTable, nId)
{
	if (null != arTable && 0 <= nId)
	{
		if (null != arTable[nId])
		{
			return arTable[nId];
		}
	}

	return null;
}

CBlockExe.prototype.getSymbol = function (nSymbolId)
{
	return this._lookupTable(this.getSymbolTable(), nSymbolId);
}

CBlockExe.prototype.getSymbolTable = function ()
{
	return null;
}


/**
 * CDeclVarExe 클래스 
 */
function CDeclVarExe ()
{
	this.m_strType = "CDeclVarExe";
	this.m_objSymbolTable = null;
}

CDeclVarExe.prototype = new CBlockExe();
CDeclVarExe.prototype.constructor = CDeclVarExe;

CDeclVarExe.prototype.DeclVarExe = function (nNextExeId,  objExprExeTable, objExprItemTable, objSymbolTable)
{
	this.m_objSymbolTable = objSymbolTable;
	
	this.BlockExe(nNextExeId,  objExprExeTable, objExprItemTable);
}

CDeclVarExe.prototype.getExeKind = function ()
{
	return s_EXE_DECL_VAR;
}

CDeclVarExe.prototype.initialize = function (pObjectX)
{
	return true;
}

CDeclVarExe.prototype.getSymbolTable = function()
{
	return this.m_objSymbolTable;
}

CDeclVarExe.prototype.initVariable = function()
{
	var arSymbolTable = this.getSymbolTable();
	if (null != arSymbolTable)
	{
		var nSize = arSymbolTable.length;
		for (var i = 0; i < nSize; i++)
		{
			var objSymbol = arSymbolTable[i];
			if (null != objSymbol)
			{
				objSymbol.clear();
			}
		}
	}

	return true;
}


/**
 * CFuncExe 클래스 
 */
function CFuncExe (nNextExeId, objExprExeTable, objExprItemTable, objSymbolTable)
{
	this.m_strType = "CFuncExe";
	this.m_nExeId = StdCore._INIT_WVALUE;
	
	this.DeclVarExe(nNextExeId, objExprExeTable, objExprItemTable, objSymbolTable);
}

CFuncExe.prototype = new CDeclVarExe();
CFuncExe.prototype.constructor = CFuncExe;

CFuncExe.prototype.getExeKind = function ()
{
	return s_EXE_FUNC;
}

CFuncExe.prototype.setExeId = function (nExeId)
{
	this.m_nExeId = nExeId;
}

CFuncExe.prototype.execute = function ()
{
	//super.execute ();

	var pExecute = this.getNextExecute ();
	if (null != pExecute)
	{
		do
		{
			pExecute.setOwnerBlock (this);
			if (ScriptDefine._exeEndFunc == pExecute.getExeKind ())
			{
				break;
			}
			pExecute = pExecute.execute ();
		}
		while (null != pExecute);
	}
	
	this.initVariable ();
	
	return null;
}

CFuncExe.prototype.attachArgList = function (arArgs)
{
	var nArgCount = 0;
	if (null == arArgs || null == arArgs[0] || 0 == (nArgCount = arArgs[0].toInt()))
	{
		return true;
	}

	var objSymbolTable = this.getSymbolTable();
	
	if (nArgCount > objSymbolTable.length)
	{
		nArgCount = objSymbolTable.length;
	}

	for (var i = 0; i < nArgCount; i+=1)
	{
		var objSymbol = objSymbolTable[i];
		if (null != objSymbol)
		{
			var objVar = arArgs[i + 1];
			objSymbol.setValueType(objVar.getType(), objVar.getValue());
		}
	}

	return true;
}


/**
 * CEndFuncExe 클래스 
 */
function CEndFuncExe (nNextExeId)
{
	this.m_strType = "CEndFuncExe";
	
	this.ExeCore(nNextExeId);
}

CEndFuncExe.prototype = new CExeCore();
CEndFuncExe.prototype.constructor = CEndFuncExe;

CEndFuncExe.prototype.getExeKind = function () 
{ 
	return s_EXE_END_FUNC;
}


/**
 * CFormExe 클래스 
 */
var CFormExe_FUNC_SERVER = 0;
var CFormExe_GLOBAL_SERVER = 1;
var CFormExe_FORM_SERVER = 2;
var CFormExe_PARENT_FORM_SERVER = 3;

function CFormExe (objExeTable, htSymbolTable, objTempTable)
{
	this.m_strType = "CFormExe";
	this.m_objExeTable = objExeTable;
	this.m_htSymbolTable = htSymbolTable;
	this.m_objTempTable = objTempTable;
	this.m_hmFunctionMap;
	
	this.m_objCallStack = new Array();
	this.m_objTempSymbolStack = new Array();
	
	this.m_bUseEBLSource = false;
	this.m_bExecute = false;
}

CFormExe.prototype = new CBlockExe ();
CFormExe.prototype.constructor = CFormExe;

CFormExe.prototype.getExeKind = function ()
{
	return s_EXE_FORM;
}

CFormExe.prototype.getSymbolTable = function ()
{
	return this.m_htSymbolTable;
}

CFormExe.prototype.makeFunctionMap = function ()
{
	this.m_hmFunctionMap = new Hashtable ();

	for (var nKey in this.m_htSymbolTable)
	{
		var objSymbol = this.m_htSymbolTable[nKey];
		if (null == objSymbol || ScriptDefine._FUNCTION != objSymbol.getSymbolKind())
		{
			continue;
		}

		objSymbol.setValueType(CVariantX._vtInt, 0);

		var strFuncName = objSymbol.getFunctionName();

		this.m_hmFunctionMap[strFuncName] = objSymbol;
	}
}

CFormExe.prototype.initServerSymbol = function (objDoc)
{
	if (null == this.m_htSymbolTable[2])
	{
		return false;
	}

	var objFuncSymbol = this.m_htSymbolTable[0];		// s_FUNC_SERVER
	var objFuncServer = null;
	if (null == objFuncSymbol || null == (objFuncServer = new CFuncServer()))
	{
		//throw PQScriptException.create(this, PQExceptionMessage.s_PQScript_FailSetFormGlobalMemberData, PQExceptionReason.s_PQScript_FailCreateSymbol);
	}

	objFuncServer.setDocument(objDoc);
	objFuncSymbol.setValueExeServer(objFuncServer);

	var objGlobalSymbol = this.m_htSymbolTable[1];		// s_GLOBAL_SERVER
	var objGScriptServer = null;
//	if (null != objGlobalSymbol && null != (objGScriptServer = CScriptApp.getGlobalScript()))
//	{
//		objGlobalSymbol.setValue(objGScriptServer);
//	}

	if (null != objDoc)
	{
		var objFormSymbol = this.m_htSymbolTable[2];	// s_FORM_SERVER
		if (null == objFormSymbol)
		{
			return false;
		}

		var objFormServer = new CFormServer(objDoc);
		objFormSymbol.setValueExeServer(objFormServer);
	}

	return true;
}

CFormExe.prototype.callMsgHandler = function(strMessge, arArgs, objRetVal)
{
	var objFuncSymbol = null;
	var objFuncExe = null;
	try
	{
		var nPos = strMessge.indexOf("@");
		if (0 == nPos)
		{
			strMessge = strMessge.substring(1);
		}

		if (this.m_bExecute && 0 != nPos)
		{
			return true;
		}	

		// 1. Lookup Function Symbol
		objFuncSymbol = this.m_hmFunctionMap[strMessge];
		if (null == objFuncSymbol)
		{
			return false;
		}

		objFuncSymbol.initValue();
		objFuncSymbol.initialize(this);

		this.m_bExecute = true;

		// 2. Get Function Execute
		if (null == (objFuncExe = objFuncSymbol.getFuncExe()))
		{
			return false;
		}

		objFuncExe.setExeId(objFuncSymbol.getFuncExeID());
		objFuncExe.setOwnerBlock(this);

		// 3 Registry Call Stack
		this.regCallStack(objFuncExe);

		// 4. Set Owner BlockExe & Clear Variables
		objFuncExe.initialize(this);

		// 5. Set Parameters
		objFuncExe.attachArgList(arArgs);

		// 6. Execute
		objFuncExe.execute();

		// 7. UnRegistry Call Stack
		this.unRegCallStack(objFuncExe);

		// 8. Set Return Value
		if (null != objRetVal)
		{
			objRetVal.setValue(objFuncSymbol);
		}
	}
	catch (e)
	{
		if (e.message)
		{
			alert("Script Engine (" + e.name + ") :" + e.message);
		}
		else
		{
			alert(e);
		}
	}
	finally
	{
		this.m_bExecute = false;
	}

	return true;
}

CFormExe.prototype.getExecute = function (wExeID)
{
	var objExecute = null;
	if (null != this.m_objExeTable && 0 <= wExeID && wExeID < this.m_objExeTable.length)
	{
		objExecute = this.m_objExeTable[wExeID]
	}

	return objExecute;
}

CFormExe.prototype.getTempString = function (nTempID)
{
	var strTempString = "";

	if (null != this.m_objExeTable && 0 <= nTempID && nTempID < this.m_objTempTable.length)
	{
		strTempString = this.m_objTempTable[nTempID];
	}

	return strTempString;
}

CFormExe.prototype.regCallStack = function (objFuncExe)
{
	if (null == objFuncExe || null == this.m_objCallStack)
	{
		return false;
	}

	if (1700 <= this.m_objCallStack.length)
	{
		return false;
	}

	this.m_objCallStack.push(new CCallStackInfo(objFuncExe));

	return true;
}

CFormExe.prototype.unRegCallStack = function (objFuncExe)
{
	if (null == objFuncExe || null == this.m_objCallStack)
	{
		return false;
	}

	this.m_objCallStack.pop();

	return true;
}

CFormExe.prototype.releaseTempSymbol = function (objSymbol)
{
	if (null != this.m_objTempSymbolStack && null != objSymbol && ScriptDefine._TEMP_SYMBOL == objSymbol.getSymbolKind())
	{
		objSymbol.clear();
		this.m_objTempSymbolStack.push(objSymbol);
	}

	return;
}

CFormExe.prototype.getTempSymbol = function ()
{
	if (null == this.m_objTempSymbolStack)
	{
		return null;
	}

	if (0 == this.m_objTempSymbolStack.length)
	{
		for (var i = 0; i < 5; i+=1)
		{
			var objTempSymbol = new CTempSymbol();
			if (null == objTempSymbol)
			{
				return null;
			}

			this.m_objTempSymbolStack.push(objTempSymbol);
		}
	}

	var objSymbol = this.m_objTempSymbolStack.pop();
	objSymbol.clear();

	return objSymbol;
}

CFormExe.prototype.useEBLSource = function ()
{
	return this.m_bUseEBLSource;
}

CFormExe.prototype.setUseEBLSource = function (bUseEBLSource)
{
	this.m_bUseEBLSource = bUseEBLSource;
}


/**
 * CAssignExe 클래스 
 */
function CAssignExe (nNextExeId, nLOpndKey, nROpndKey)
{
	this.m_strType = "CAssignExe";
	
	this.m_nLOpndKey = nLOpndKey;
	this.m_nROpndKey = nROpndKey;
	this.m_objLOpnd = null;
	this.m_objROpnd = null;
	
	this.ExeCore(nNextExeId);
}

CAssignExe.prototype = new CExeCore();
CAssignExe.prototype.constructor = CAssignExe;

CAssignExe.prototype.getExeKind = function ()
{
	return s_EXE_ASSIGN;
}

CAssignExe.prototype.execute = function ()
{
	if (null == this.m_objROpnd && false == this.initialize (this))
	{
		return this.getNextExecute ();
	}

	// 1. R-Operand의 계산 결과 값을 구한다..
	var pResult = this.m_objROpnd.getResult ();

	// 2. 결과값을.. L-Operand에 대입한다..
	if (null != this.m_objLOpnd && null != pResult)
	{
		this.m_objLOpnd.setValue (pResult);
	}

	this.releaseTempSymbol (pResult);
	
	return this.getNextExecute ();
}

CAssignExe.prototype.initialize = function (objObjectX)
{
	if (null == this.m_objLOpnd && StdCore._INIT_WVALUE != this.m_nLOpndKey)
	{
		this.m_objLOpnd = this.queryExprItem(this.m_nLOpndKey);
	}
	
	if (null == this.m_objROpnd && StdCore._INIT_WVALUE != this.m_nROpndKey)
	{
		if (null != (this.m_objROpnd = this.queryExprExe(this.m_nROpndKey)))
		{
			this.m_objROpnd.setOwnerBlock(this.getOwnerBlock());
			this.m_objROpnd.initialize(this);
		}
	}
	
	return (null != this.m_objROpnd) ? true : false;
}


/**
 * CExprExe 클래스
 */
function CExprExe (nNextExeId, arExprItemId)
{
	this.m_strType = "CExprExe";
	
	this.m_arExprItemId = arExprItemId;
	this.m_arExprItem = null;
	
	this.ExeCore(nNextExeId);
}

CExprExe.prototype = new CExeCore();
CExprExe.prototype.constructor = CExprExe;

CExprExe.prototype.getExeKind = function ()
{
	return s_EXE_EXPR;
}

CExprExe.prototype.initialize = function (objObjectX)
{
	if (0 == this.m_arExprItemId.length)
	{
		return false;
	}
	
	if (null == this.m_arExprItem)
	{
		this.m_arExprItem = new Array();

		for (var i = 0; i < this.m_arExprItemId.length; i++)
		{
			var nExprItemId = Utils.parseInt(this.m_arExprItemId[i]);
			var objExprItem = this.queryExprItem(nExprItemId);
			if (null != objExprItem)
			{
				this.m_arExprItem.push(objExprItem);
			}
		}
	}
	
	return (0 < this.m_arExprItem.length) ? true : false;
}

CExprExe.prototype.getFirstItem = function ()
{
	if (null == this.m_arExprItem || 0 == this.m_arExprItem.length)
	{
		return null;
	}

	return this.m_arExprItem[0];
}

CExprExe.prototype.getResult = function ()
{
	if (null == this.m_arExprItem || 0 == this.m_arExprItem.length) 
		return null;

	var pResult = null;
	var pBuffItem = this.m_arExprItem[0];
	if (null == pBuffItem || null == (pResult = pBuffItem.getValue ()))
	{
		return null; 
	}

	var pStack = new Array();
	for (var i = 1 ; i < this.m_arExprItem.length; i+=1)
	{
		var pNextItem = this.m_arExprItem[i];

		if (pNextItem instanceof COpItem) // 연산자를 만나면 계산을 한다..
		{
			var pLOpnd = pResult;
			var pROpnd = pResult;
			if (pNextItem.isUnary ())
			{
				pROpnd = null;  // Operand 가 하나인 경우...
			}
			else
			{							  
				pLOpnd = pStack.pop(); // Operand 가 두개인 경우...
			}
			
			if (null == (pResult = pNextItem.evaluate (pLOpnd, pROpnd)))
			{
				// 빌더에서 비교 결과가 null 일 경우, 그냥 다음으로 계속 진행한다.
				System.err.println("ScriptException : Empty Operand");
			}
		}
		else
		{
			pStack.push (pResult);
			if (null == (pResult = pNextItem.getValue ()))
			{
				return null;
			}
		}
	}

	return pResult;
}


/**
 * CConditionExe 클래스
 */
function CConditionExe ()
{
	this.m_strType = "CConditionExe";
	this.m_nConditionKey = StdCore._INIT_WVALUE;
	this.m_nBranchKey = StdCore._INIT_WVALUE;

	this.m_objConditionExe = null;
	this.m_objBranchExe = null;
}

CConditionExe.prototype = new CDeclVarExe ();
CConditionExe.prototype.constructor = CConditionExe;

CConditionExe.prototype.ConditionExe = function (nNextExeId,  objExprExeTable, objExprItemTable, objSymbolTable, 
												nConditionKey, nBranchKey)
{
	this.m_nConditionKey = nConditionKey;
	this.m_nBranchKey = nBranchKey;
	
	this.DeclVarExe(nNextExeId,  objExprExeTable, objExprItemTable, objSymbolTable);
}

CConditionExe.prototype.getExeKind = function () 
{ 
	return s_EXE_COND;
}

CConditionExe.prototype.getConditionKey = function ()
{
	return this.m_nConditionKey;
}

CConditionExe.prototype.getConditionExe = function ()
{
	return this.m_objConditionExe;
}

CConditionExe.prototype.getBranchKey = function ()
{
	return this.m_nBranchKey;
}
	
CConditionExe.prototype.getBranchExe = function ()
{
	return this.m_objBranchExe;
}

CConditionExe.prototype.initialize = function (pObjectX)
{
	if (null == this.m_objConditionExe && StdCore._INIT_WVALUE != this.m_nConditionKey)
	{
		var objBlockExe = this.getOwnerBlock();
		this.setOwnerBlock(this);

		this.m_objConditionExe = this.queryExprExe(this.m_nConditionKey);

		this.setOwnerBlock(objBlockExe);

		if (null != this.m_objConditionExe)
		{
			this.m_objConditionExe.setOwnerBlock(this);
			this.m_objConditionExe.initialize(this);
		}
	}
	
	return (null != this.m_objConditionExe) ? true : false;
}


/**
 * CIfExe 클래스
 */
function CIfExe (nNextExeId, objExprExeTable, objExprItemTable, objSymbolTable, nConditionKey, nBranchKey)
{
	this.m_strType = "CIfExe";
	
	this.ConditionExe(nNextExeId, objExprExeTable, objExprItemTable, objSymbolTable, nConditionKey, nBranchKey);
}

CIfExe.prototype = new CConditionExe ();
CIfExe.prototype.constructor = CIfExe;

CIfExe.prototype.getExeKind = function () 
{ 
	return s_EXE_IF;
}

CIfExe.prototype.execute = function ()
{
	if (StdCore._INIT_WVALUE != this.getConditionKey())
	{
		if (null == this.getConditionExe() && false == this.initialize(this))
		{
			return null;
		}

		var bCondition = false;
		var objResult = this.getConditionExe().getResult();
		if (null != objResult)
		{
			bCondition = objResult.toBoolean();
		}
		
		this.releaseTempSymbol(objResult);

		if (false == bCondition)
		{
			var objBranchExe = this.getBranchExe();
			if (null == objBranchExe && StdCore._INIT_WVALUE != this.getBranchKey())
			{
				if (null != (objBranchExe = this.queryExecute(this.m_nBranchKey)))
				{
					objBranchExe.setOwnerBlock(this.getOwnerBlock());
				}
			}

			this.initVariable();
			
			if (objBranchExe == null)
			{
				return objBranchExe;
			}
			
			if (s_EXE_END_IF == objBranchExe.getExeKind())
			{
				return objBranchExe.getNextExecute();
			}
			
			return objBranchExe;
		}
	}

	this.initialize(this);
	
	var objExecute = this.getNextExecute();
	if (null != objExecute)
	{
		do
		{
			objExecute.setOwnerBlock(this);
			
			if (s_EXE_END_IF == objExecute.getExeKind())
			{
				this.initVariable();
				return objExecute.getNextExecute();
			}
			else if (s_EXE_BREAK == objExecute.getExeKind())
			{
				var objLookupExe = objExecute.getNextExecute();
				if (null != objLookupExe && s_EXE_END_WHILE == objLookupExe.getExeKind())
				{
					this.initVariable();
					return objExecute;
				}
			}
			else if (s_EXE_CONTINUE == objExecute.getExeKind())
			{
				var objLookupExe = objExecute.getNextExecute();
				if (null == objLookupExe)
				{
					this.initVariable();
					return objExecute;
				}
			}
			else if (s_EXE_RETURN == objExecute.getExeKind())
			{
				this.initVariable();
				return objExecute;
			}

			objExecute = objExecute.execute();
		}
		while (null != objExecute);
	}

	this.initVariable();
	
	return null;
}


/**
 * CEndIfExe 클래스 
 */
function CEndIfExe (nNextExeId)
{
	this.m_strType = "CEndIfExe";
	
	this.ExeCore(nNextExeId);
}

CEndIfExe.prototype = new CExeCore();
CEndIfExe.prototype.constructor = CEndIfExe;

CEndIfExe.prototype.getExeKind = function () 
{ 
	return s_EXE_END_IF;
}


/**
 * CWhileExe 클래스
 */
function CWhileExe (nNextExeId, objExprExeTable, objExprItemTable, objSymbolTable, nConditionKey, nBranchKey)
{
	this.m_strType = "CWhileExe";
	
	this.ConditionExe(nNextExeId, objExprExeTable, objExprItemTable, objSymbolTable, nConditionKey, nBranchKey);
}

CWhileExe.prototype = new CConditionExe ();
CWhileExe.prototype.constructor = CWhileExe;

CWhileExe.prototype.getExeKind = function () 
{ 
	return s_EXE_WHILE;
}

CWhileExe.prototype.execute = function ()
{
	if (null == this.getConditionExe() && false == this.initialize(this))
	{
		return null;
	}
	
	var bCondition = false;
	var objResult = this.getConditionExe().getResult();
	if (null != objResult)
	{
		bCondition = objResult.toBoolean();
	}
	
	this.releaseTempSymbol(objResult);

	if (false == bCondition)
	{
		var objBranchExe = this.getBranchExe();
		if (null == objBranchExe && StdCore._INIT_WVALUE != this.getBranchKey())
		{
			if (null != (objBranchExe = this.queryExecute(this.m_nBranchKey)))
			{
				objBranchExe.setOwnerBlock(this.getOwnerBlock());
			}
		}

		this.initVariable();
		
		if (objBranchExe == null)
		{
			return objBranchExe;
		}
		
		if (s_EXE_END_WHILE == objBranchExe.getExeKind())
		{
			return objBranchExe.getNextExecute();
		}
		
		return objBranchExe;
	}

	this.initialize(this);
	
	var objExecute = this.getNextExecute();
	if (null == objExecute)
	{
		return null;
	}

	do
	{
		objExecute.setOwnerBlock(this);
		
		if (s_EXE_END_WHILE == objExecute.getExeKind())
		{
			this.initVariable();
			return objExecute.getNextExecute();
		}
		else if (s_EXE_CONTINUE == objExecute.getExeKind())
		{
			this.initVariable();
			return this;
		}
		else if (s_EXE_RETURN == objExecute.getExeKind())
		{
			this.initVariable();
			return objExecute;
		}

		objExecute = objExecute.execute();
	}
	while (null != objExecute);

	this.initVariable();
	
	return this;
}


/**
 * CEndWhileExe 클래스 
 */
function CEndWhileExe (nNextExeId)
{
	this.m_strType = "CEndWhileExe";
	
	this.ExeCore(nNextExeId);
}

CEndWhileExe.prototype = new CExeCore();
CEndWhileExe.prototype.constructor = CEndWhileExe;

CEndWhileExe.prototype.getExeKind = function () 
{ 
	return s_EXE_END_WHILE;
}

	
/**
 * CBreakExe
 */
function CBreakExe (nNextExeId)
{
	this.m_strType = "CBreakExe";
	this.ExeCore(nNextExeId);
}

CBreakExe.prototype = new CExeCore();
CBreakExe.prototype.constructor = CBreakExe;

CBreakExe.prototype.getExeKind = function ()
{
	return s_EXE_BREAK;
}

CBreakExe.prototype.execute = function ()
{
	return this.getNextExecute();
}

/**
 * CReturnExe
 */
function CReturnExe (nNextExeId)
{
	this.m_strType = "CReturnExe";
	this.ExeCore(nNextExeId);
}

CReturnExe.prototype = new CExeCore();
CReturnExe.prototype.constructor = CReturnExe;

CReturnExe.prototype.getExeKind = function ()
{
	return s_EXE_RETURN;
}

CReturnExe.prototype.execute = function ()
{
	return this.getNextExecute();
}


/**
 * CContinueExe
 */
function CContinueExe (nNextExeId)
{
	this.m_strType = "CContinueExe";
	this.ExeCore(nNextExeId);
}

CContinueExe.prototype = new CExeCore();
CContinueExe.prototype.constructor = CContinueExe;

CContinueExe.prototype.getExeKind	= function () 
{
	return s_EXE_CONTINUE; 
}

CContinueExe.prototype.execute = function ()
{
	return this.getNextExecute();
}


/////////////////////////////////////////////////////////
// Server 클래스 시작


function CExeServer ()
{
}

CExeServer.prototype.getProperty = function (wObjID, wPropID, pRetVal)
{
	if (StdCore._INIT_WVALUE == wPropID || null == pRetVal)
		return StdCore.E_NOT_DEF_PROPERTY;

	var nResult = StdCore.S_OK;
	
	try
	{
		nResult = this.getPropertyL(wPropID, null, pRetVal);
	}
	catch(e)
	{
		nResult = StdCore.E_NOT_DEF_PROPERTY;
	}
	
	return nResult;
}
	
CExeServer.prototype.setProperty = function (wObjID, wPropID, pvaArgs, pValue)
{
	if (StdCore._INIT_WVALUE == wPropID || null == pValue)
		return StdCore.E_NOT_DEF_PROPERTY;

	var nResult = StdCore.S_OK;
	
	try
	{
		nResult = this.setPropertyL(wPropID, pvaArgs, pValue);
	}
	catch (e)
	{
		nResult = StdCore.E_NOT_DEF_PROPERTY;
	}
	
	return nResult;
}

CExeServer.prototype.action = function (wObjID, wPropID, pvaArgs, pRetVal)
{
	if (StdCore._INIT_WVALUE == wPropID || null == pRetVal)
	{
		return StdCore.E_NOT_DEF_PROPERTY;
	}

	var nResult = StdCore.S_OK;
	try
	{
		nResult = this.actionL(wPropID, pvaArgs, pRetVal);
	}
	catch (e)
	{
		nResult = StdCore.E_NOT_DEF_PROPERTY;
		throw e;
	}

	return nResult;
}

CExeServer.prototype.getPropertyL = function (nPropID, arArgs, objRetVal)
{
	switch (nPropID)
	{
		case 0: case 203: return this.get_Value(arArgs, objRetVal);		// 값
		default : return StdCore.E_NOT_DEF_PROPERTY;
	}
}

/**
 * CFormServer 클래스
 */
function CFormServer (objDoc)
{
	this.m_objDoc = objDoc;
}

CFormServer.prototype = new CExeServer ()
CFormServer.prototype.constructor = CFormServer;

CFormServer.prototype.isValidServer = function ()
{
	return (null != this.m_objDoc) ? true : false;
}

CFormServer.prototype.getDocument = function ()
{
	return this.m_objDoc;
}

CFormServer.prototype.setProperty = function (nObjID, nPropID, arArgs, objValue)
{
	var nRet = 0;
	
	if (null != this.m_objDoc)
	{
		nRet = this.m_objDoc.setProperty(nObjID, nPropID, arArgs, objValue);
	}
	
	return nRet;
}

CFormServer.prototype.getProperty = function (nObjID, nPropID, objRetVal)
{
	return (null != this.m_objDoc) ? this.m_objDoc.getProperty(nObjID, nPropID, objRetVal) : 0;
}

CFormServer.prototype.action = function (nObjID, nPropID, arArgs, objRetVal)
{
	return (null != this.m_objDoc) ? this.m_objDoc.action(nObjID, nPropID, arArgs, objRetVal) : 0;
}

CFormServer.prototype.getPropertyS = function (strObjName, nPropID, objRetVal)
{
	return (null != this.m_objDoc) ? this.m_objDoc.getPropertyS(strObjName, nPropID, objRetVal) : 0;
}

CFormServer.prototype.setPropertyS = function (strObjName, nPropID, arArgs, pValue)
{
	return (null != this.m_objDoc) ? this.m_objDoc.setPropertyS(strObjName, nPropID, arArgs, pValue) : 0;
}

CFormServer.prototype.actionS = function (strObjName, nPropID, arArgs, objRetVal)
{
	return (null != this.m_objDoc) ? this.m_objDoc.actionS(strObjName, nPropID, arArgs, objRetVal) : 0;
}


/**
 * CFuncServer 클래스
 */
function CFuncServer ()
{
	this.m_objDoc = null;
}

CFuncServer.prototype.setDocument = function (objDoc)
{
	this.m_objDoc = objDoc;
}

CFuncServer.prototype.isValidServer = function ()
{
	return true;
}

CFuncServer.prototype.actionL = function (nPropID, arArgs, objRetVal)
{
	switch (nPropID)
	{
		case 2: case 103: return this.raw_ShowMessage (arArgs, objRetVal); // 메시지
		case 5: case 106: return this.raw_CurrentDate (arArgs, objRetVal); // 현재날짜
		case 6: case 107: return this.raw_CurrentTime (arArgs, objRetVal); // 현재시간
		case 30: case 134: return this.raw_SystemInformation (arArgs, objRetVal); // 시스템정보
		case 58: case 159: return this.raw_GetServerDateTime (arArgs, objRetVal); // 서버현재날짜시간
		case 71: case 181: return this.raw_PopupBlock (arArgs, objRetVal); // 팝업차단
		case 72: case 182: return this.raw_PopupBlockExist (arArgs, objRetVal); // 팝업차단여부
		case 74: case 786: return this.raw_WebBoardReply (arArgs, objRetVal);	// 게시판답글값
		case 84: case 183: return this.raw_ClipBoardCopy (arArgs, objRetVal); //클립보드복사
		
		default: return this.getProperty(nPropID, arArgs, objRetVal);
	}
}

CFuncServer.prototype.getProperty = function (nPropID, arArgs, objRetVal)
{
	switch (nPropID)
	{
//	case 16: case 117: return this.get_Global(arArgs, objRetVal); // 전역정보
	case 66: case 1410: return this.get_WebSessionInfo (arArgs, objRetVal);	// 웹세션정보"
	case 81: case 793: return this.get_WebCookieInfo (arArgs, objRetVal);	// 웹쿠키정보
	default : return StdCore.E_NOT_DEF_PROPERTY;
	}
}
CFuncServer.prototype.setProperty = function (nPropID, arArgs, objRetVal)
{
	switch (nPropID)
	{
		default : return StdCore.E_NOT_DEF_PROPERTY;
	}
}

/**
 * 팝업차단 (키, 기간)
 */
CFuncServer.prototype.raw_PopupBlock = function (arArgs, objRetVal)
{
	if (null == arArgs || 2 > arArgs.length)
		return StdCore.E_NOT_MATCH_PARAM_CNT;

	// 웹에서만 사용
	var strKey	= arArgs[1].toStringX();
	var strExpire = arArgs[2].toStringX();
	
	var strAddInfo = strKey + "$" + strExpire + ";";
	
	g_strPopupBlockInfo += strAddInfo;
	
	CookieLib.setCookie("*" + strKey, "1", Utils.parseInt(strExpire));
	
	var parentWindow = window.top.opener;
	if (null != parentWindow)
	{
		parentWindow.GlobalField.initPopupBlockInfo();
	}
	
	return StdCore.S_OK;
}

/**
 * 팝업차단여부 (키)
 */
CFuncServer.prototype.raw_PopupBlockExist = function (arArgs, objRetVal)
{
	if (null == arArgs || 1 > arArgs.length)
		return StdCore.E_NOT_MATCH_PARAM_CNT;

	objRetVal.setValueType(CVariantX._vtInt, false);
	
	// 웹에서만 사용
	var strKey	= arArgs[1].toStringX ();
	
	var arBlockInfo = g_strPopupBlockInfo.split(";");
	
	for (var i = 0; i < arBlockInfo.length; i+=1)
	{
		var strBlock = arBlockInfo[i];
		
		var arInfo = strBlock.split("$");
		if (arInfo[0] == strKey)
		{
			objRetVal.setValueType(CVariantX._vtInt, true);
		}
	}
	
	return StdCore.S_OK;
}

/**
 * "현재날짜()" 스크립트.
 */
CFuncServer.prototype.raw_CurrentDate = function (arArgs, objRetVal)
{
	if (null == arArgs || 1 > arArgs.length)
	{
		return StdCore.E_NOT_MATCH_PARAM_CNT;
	}

	objRetVal.setValueType(CVariantX._vtString, "");
	var nArgCnt = arArgs[0].toInt();

	var objCalendar = new Date();
	var nYear = objCalendar.getYear();
	var nMonth = objCalendar.getMonth();
	var nDate = objCalendar.getDate();

	switch (arArgs[1].toInt())
	{
	case 1029: // #날짜
	{
		var strDelimiter = (1 < nArgCnt) ? arArgs[2].toStringX() : "";
		
		var strValue = nYear + "";
		
		if (nMonth < 10)
		{
			strValue += "0";
		}
		strValue += nMonth;
		
		if (nDate < 10)
		{
			strValue += "0";
		}
		strValue += nDate;
		
		objRetVal.setValueType(CVariantX._vtString, strValue);
		break;
	}
	case 1030: // #년
	{
		objRetVal.setValueType(CVariantX._vtString, nYear + "");
		break;
	}
	case 1031: // #월
	{
		objRetVal.setValueType(CVariantX._vtString, nMonth + "");
		break;
	}
	case 1032: // #일
	{
		objRetVal.setValueType(CVariantX._vtString, nDate + "");
		break;
	}
	case 1033: // #요일
	{
		var arDaysOfWeek = ["일요일", "월요일", "화요일", "수요일", "목요일", "금요일", "토요일"];
		var strResult = arDaysOfWeek[objCalendar.getDay()];
		objRetVal.setValueType(CVariantX._vtString, strResult);
		break;
	}
	default:
		break;
	}

	return StdCore.S_OK;
}

CFuncServer.prototype.raw_CurrentTime = function (arArgs, objRetVal)
{
	if (null == arArgs || 1 > arArgs.length)
	{
		return StdCore.E_NOT_MATCH_PARAM_CNT;
	}

	objRetVal.setValueType(CVariantX._vtString, "");
	var nArgCnt = arArgs[0].toInt();

	var objCalendar = new Date();
	var nHour = objCalendar.getHours();
	var nMinute = objCalendar.getMinutes();
	var nSecond = objCalendar.getSeconds();
	
	switch (arArgs[1].toInt())
	{
	case 1034: // #시간
	{
		var strDelimiter = (1 < nArgCnt) ? arArgs[2].toStringX() : "";
		
		var strValue = "";
		if (nHour < 10)
		{
			strValue += "0";
		}
		strValue += nHour;
		
		if (nMinute < 10)
		{
			strValue += "0";
		}
		strValue += nMinute;
		
		if (nSecond < 10)
		{
			strValue += "0";
		}
		strValue += nSecond;
		
		objRetVal.setValueType(CVariantX._vtString, strValue);
		break;
	}
	case 1035: // #시
	{
		objRetVal.setValueType(CVariantX._vtString, "" + nHour);
		break;
	}
	case 1036: // #분
	{
		objRetVal.setValueType(CVariantX._vtString, "" + Minute);
		break;
	}
	case 1037: // #초
	{
		objRetVal.setValueType(CVariantX._vtString, "" + nSecond);
		break;
	}
	case 1038: // #밀리초
	{
		objRetVal.setValueType(CVariantX._vtString, "" + objCalendar.getMilliseconds());
		break;
	}
	default:
		break;
	}

	return StdCore.S_OK;
}

/**
 * 웹쿠키정보('읽기' or '쓰기', 키값, (저장값), (보존일수)
 */
CFuncServer.prototype.get_WebCookieInfo = function (arArgs, objRetVal)
{
	if (null == arArgs || 3 > arArgs.length)
	{
		return StdCore.E_NOT_MATCH_PARAM_CNT;
	}
	
	var nArgCnt = arArgs[0].toInt();
	var nType = arArgs[1].toInt()
	var strKey = arArgs[2].toStringX();
	
	if(ScriptDefine._READ == nType)
	{
		if (false == Utils.isEmpty(strKey))
		{
			var strValue = CookieLib.getCookie(strKey);
			objRetVal.setValueType(CVariantX._vtString, strValue);
		}
	}
	else if (ScriptDefine._WRITE == nType)
	{
		if (nArgCnt < 3)
		{
			return StdCore.E_NOT_MATCH_PARAM_CNT;
		}
		
		var strValue = arArgs[3].toStringX();
		var nExpireDay = (4 == nArgCnt) ? arArgs[4].toInt() : 1;
		
		CookieLib.setCookie(strKey, strValue, nExpireDay);
	}
	
	return StdCore.S_OK;
}

/**
 * 웹세션정보
 * Map 에는 Object 형으로 값이 들어가지만, 빌더에서 값을 String 으로 넘기므로 캐스트함
 */
CFuncServer.prototype.get_WebSessionInfo = function (arArgs, objRetVal)
{
	if (null == arArgs || 2 > arArgs.length)
	{
		return StdCore.E_NOT_MATCH_PARAM_CNT;
	}
	objRetVal.setValueType(CVariantX._vtString, "");

	if (2 < arArgs.length)
	{
		var strKey = arArgs[2].toStringX();
		if(ScriptDefine._READ == arArgs[1].toInt())
		{
			var strValue = this.getSessionService(strKey);
			
			if (null != strValue)
			{
				objRetVal.setValueType(CVariantX._vtString, strValue);
			}
			else
			{
				objRetVal.setValueType(CVariantX._vtString, "");
			}
		}
		else if (ScriptDefine._WRITE == arArgs[1].toInt())
		{
			var nArgCnt = arArgs[0].toInt();

			var strValue = (2 < nArgCnt) ? arArgs[3].toStringX() : "";
			
			this.setSessionService(strKey, strValue);
		}
	}
	else
	{
		var strKey = arArgs[1].toStringX();
		
		var strValue = this.getSessionService(strKey);
		
		if (null != strValue)
		{
			objRetVal.setValueType(CVariantX._vtString, strValue);
		}
		else
		{
			objRetVal.setValueType(CVariantX._vtString, "");
		}
	}
	return StdCore.S_OK;
}

CFuncServer.prototype.getSessionService = function (strKey)
{
	return PQPortalService.executeSessionService(0, strKey, "");
}

CFuncServer.prototype.setSessionService = function (strKey, strValue)
{
	PQPortalService.executeSessionService(1, strKey, strValue);
}


CFuncServer.prototype.raw_ShowMessage = function (arArgs, objRetVal)
{
	if (null == arArgs || 1 > arArgs.length)
		return StdCore.E_NOT_MATCH_PARAM_CNT;
	
	objRetVal.setValueType(CVariantX._vtInt, 0);
	var nArgCnt = arArgs[0].toInt();

	var strTitle = (3 < nArgCnt) ? arArgs[4].toStringX() + " : " : "";
	var nButtonType = (1 < nArgCnt) ? arArgs[2].toInt() : 0;
	var nIconType = (2 < nArgCnt) ? arArgs[3].toInt() : 1019;
	
	var strMessage = "";
	if (CVariantX._vtInt == arArgs[1].getType())
	{
		strMessage = arArgs[1].toInt() + "";
		strMessage = Utils.trim(strMessage);
	}
	if (0 == strMessage.length)
	{
		strMessage = arArgs[1].toStringX();
	}
	
	var bResult = null;
	var nResult = null;
	
	//버튼유형을 선택하지 않은 경우 일반경고창 발생
	if(0 == nButtonType)
	{
		alert(strMessage);
		nResult = 0;
	}
	else
	{
		bResult = confirm (strMessage);
		//확인을 선택한 경우
		if(bResult)
		{
			nResult = 0;
		}
		//취소를 선택한 경우
		else
		{
			nResult = 1;
		}
	}
	
	switch (nResult)
	{
	case 0:
		objRetVal.setValueType(CVariantX._vtInt, 1013);
		break; // #확인
	case 1:
		objRetVal.setValueType(CVariantX._vtInt, 1021);
		break; // #취소
	case 2:
		objRetVal.setValueType(CVariantX._vtInt, 1023);
		break; // #예
	case 3:
		objRetVal.setValueType(CVariantX._vtInt, 1024);
		break; // #아니오
	case 4:
		objRetVal.setValueType(CVariantX._vtInt, 1022);
		break; // #재시도
	case 5:
		objRetVal.setValueType(CVariantX._vtInt, 1025);
		break; // #중지
	case 6:
		objRetVal.setValueType(CVariantX._vtInt, 1026);
		break; // #무시
	default:
		break;
	}
	
	return StdCore.S_OK;
}

/**
 * 서버현재날짜시간()
 */
CFuncServer.prototype.raw_GetServerDateTime = function (arArgs, objRetVal)
{
	if (null == arArgs || 1 > arArgs.length)
		return StdCore.E_NOT_MATCH_PARAM_CNT;

	var strType = arArgs[1].toStringX();
	objRetVal.setValueType(CVariantX._vtString, "");

	if (false == this.isValidServer())
	{
		return StdCore.S_OK;
	}

	try
	{
		var strField = "[SYSDATE_2]";
		var strTableName = g_objQueryLib.getOwnerWithDBName("TOP_COMM") + ".TOP_DEP";	//접속되었다면 TOP_COMM에 존재하는 테이블 (oracle때문에..)
		var strQuery = "SELECT " + strField + " FROM " + strTableName;
		
		strQuery = g_objQueryLib.getDBMSQuery(strQuery);

		var arResult = g_objDataService.executeOpenRowX(strQuery, 15, 0, "TOP_COMM");

		if (null == arResult || 0 == arResult.length)
		{
			return StdCore.S_OK;
		}

		var strDateTime = arResult[0];

		if (1 == g_nDBKind)	// 오라클일 경우
		{
			// 쿼리 결과값에 밀리세컨드 값이 포함되어 있지 않으므로 임의로 채운다.
			strDateTime += ".000";
		}
		
		var strResult = this._changeDateFormat(strDateTime, strType);

		objRetVal.setValueType(CVariantX._vtString, strResult);
	}
	catch (e)
	{
		return StdCore.E_INVALID_DATETIME;
	}

	return StdCore.S_OK;
}

/**
 * 문자열 시간 데이터를 변환한다.
 * 원본 문자형 : "yyyy-MM-dd HH:mm:ss.SSS"
 */
CFuncServer.prototype._changeDateFormat = function (strValue, strFormat)
{
	var arSplit = strValue.split(" ");
	
	if (2 == arSplit.length)
	{
		var aryMd = arSplit[0].split("-");
		var arHms = arSplit[1].split(":");
		
		var strSecond = arHms[2].substring(0, 2);
		
		var objDate = new Date(aryMd[0], aryMd[1], aryMd[2], arHms[0], arHms[1], strSecond);
		
		strFormat = Utils.replaceAll(strFormat, "yyyy", aryMd[0]);
		strFormat = Utils.replaceAll(strFormat, "MM", aryMd[1]);
		strFormat = Utils.replaceAll(strFormat, "dd", aryMd[2]);
		
		strFormat = Utils.replaceAll(strFormat, "HH", arHms[0]);
		strFormat = Utils.replaceAll(strFormat, "mm", arHms[1]);
		strFormat = Utils.replaceAll(strFormat, "ss", strSecond);
	}
	
	return strFormat;
}

/**
 * 답글게시판 사용시 단계값 받는 함수
 */
CFuncServer.prototype.raw_WebBoardReply = function (arArgs, objRetVal)
{
	if (null == arArgs || 2 > arArgs.length)
	{
		return StdCore.E_NOT_MATCH_PARAM_CNT;
	}

	var strReferenceAtom = arArgs[1].toStringX();
	var strDepthAtom = arArgs[2].toStringX();
	
	var objReferenceAtom = Model.getAtom(strReferenceAtom);
	var objDepthAtom = Model.getAtom(strDepthAtom);
	
	var strNextValue = "A";
	if (null != objReferenceAtom && null != objDepthAtom)
	{
		var strBoardTable = objReferenceAtom.getTableName();
		var strReferenceField = objReferenceAtom.getFieldName();
		var strDepthField = objDepthAtom.getFieldName();

		var strReferenceNum = objReferenceAtom.getValue();
		var strDepth	= objDepthAtom.getValue();

		if (0 < strDepth.length)
		{
			var nReferenceNum = Utils.parseInt(strReferenceNum);

			var strMaxDepth	=  this._getMaxDepthValue (nReferenceNum, strDepth, strDepthField, strReferenceField, strBoardTable);
			if ("" == strMaxDepth)
			{
				strNextValue = strDepth + "A";	
			}
			else if (strMaxDepth == strDepth)
			{
				strNextValue = strMaxDepth + "A";
			}
			else
			{
				strNextValue = this._getNextDepth (strMaxDepth);
			}
		}
	}
	
	objRetVal.setValueType(CVariantX._vtString, strNextValue);	
	return StdCore.S_OK;
}

/// 문자열 값을 가져온다.
CFuncServer.prototype._getNextDepth = function (strValue)
{
	var strOutput = "";
	
	if (null != strValue && 0 < strValue.length)
	{
		var strValue1 = strValue.substring (0, strValue.length - 1);
		//var cLastChar   = strValue.charAt(strValue.length - 1);
		var nLastChar = strValue.charCodeAt(strValue.length - 1);
		var cNextChar = String.fromCharCode(nLastChar + 1);
		
		strOutput = strValue1 + cNextChar;
	}

	return strOutput;
}

/// 같은 그룹을 가지고 있을때 다음번 문자열 값을 구성한다.
CFuncServer.prototype._getMaxDepthValue = function (nReferenceNum, strDepth, strDepthField, strReferenceField, strBoardTable)
{
	var strField	= "MAX (" + strDepthField + ")";
	var strWhere = strReferenceField + " = " + nReferenceNum + " AND " + strDepthField+ " LIKE '" + strDepth + "_'";
	
	var strQuery = "SELECT " + strField + " FROM " + strBoardTable + " WHERE " + strWhere;
	strQuery = g_objQueryLib.getDBMSQuery(strQuery);
		
	var strMaxDepth;
	try
	{
		var strModuleKey = PQQuery.getModuleKey(1);
		
		strMaxDepth = g_objDataService.executeOpenScalarX(strQuery, 15, 1, strModuleKey);
	}
	catch (e)
	{
		strMaxDepth = "";
	}
	
	if (null != strMaxDepth)
	{
		strMaxDepth = Utils.trim(strMaxDepth);
	}
	
	return strMaxDepth;
}

// 서버에 요청을 보내서 클라리언트 ip정보 등을 얻어온다.
CFuncServer.prototype.raw_SystemInformation = function (arArgs, objRetVal)
{
	if (null == arArgs || 1 > arArgs.length)
		return StdCore.E_NOT_MATCH_PARAM_CNT;

	var strResult = g_objPQPortalService.executeClientInfoService();
	
	if (null == strResult)
	{
		return StdCore.E_FAIL;
	}
	
	var xnResult = XmlLib.loadXMLFromString(strResult);
	var xnInfo = XmlLib.selectSingleNode(xnResult, "//ClientInfo");
	
	var nKind = arArgs[1].toInt();
	switch (nKind)
	{
	case 1324 :   //#IP
	{
		var strIP = XmlLib.getAttribute(xnInfo, "IP");
		
		var varIP = new CVariantX (CVariantX._vtString, strIP);
		
		var varIPArray = new CVarArrayX ();
		varIPArray.add(varIP);
		
		objRetVal.setValueType(CVariantX._vtArray, varIPArray);
	} break;
	case 1325 :   //#NAME
	{
		var strName = XmlLib.getAttribute(xnInfo, "IP");
		
		objRetVal.setValueType(CVariantX._vtString, strName);
	} break;
	case 1342 : // #MAC
		return StdCore.E_NOT_SUPPORT_FUNCTION;
	default : break;
	}

	return StdCore.S_OK;
}
/**
 * 클립보드로 복사한다
 * 사용법 : 클립보드복사(아톰명)를 실행한다.
 */
CFuncServer.prototype.raw_ClipBoardCopy = function (arArgs, objRetVal)
{
	//아톰명에 해당하는 데이터를 클립보드로 복사
	window.clipboardData.setData('Text',arArgs[1].getValue());
	return StdCore.S_OK;
}

/**
 * CFieldServer
 */
function CFieldServer (strFieldName)
{
	this.m_objDoc = null;
	this.m_strFieldName = strFieldName;
}

CFieldServer.prototype.initialize = function (pObjectX)
{
	if (pObjectX instanceof CFormServer)
	{
		this.m_objDoc = pObjectX.getDocument ();
	}

	return (null != this.m_objDoc) ? true : false;
}

CFieldServer.prototype.makeArgumentList = function (arArgs)
{
	var nCount = (arArgs != null) ? arArgs[0].toInt () : 0;

	var arNewArgs = new Array(nCount + 2);		//2 : 0번째Arg, 필드명
	
	// 0 번째는 인자 갯수가 들어간다..
	arNewArgs[0] = new CVariantX (CVariantX._vtInt, nCount + 1);
	// 첫번째는 필드명이 들어간다
	arNewArgs[1] = new CVariantX (CVariantX._vtString, this.m_strFieldName);

	for (var i = 0; i < nCount; i++)
	{
		arNewArgs[i + 2] = arArgs[i + 1];
	}

	return arNewArgs;
}

CFieldServer.prototype.action = function (nObjID, nPropID,  arArgs, objRetVal)
{
	var pDTSvr = this.m_objDoc.findQueryResult (this.m_strFieldName);
	if (null == pDTSvr)
		return StdCore.E_FAIL;

	var arNewArgs = this.makeArgumentList (arArgs);
	return pDTSvr.action (nObjID, nPropID, arNewArgs, objRetVal);
}
	
CFieldServer.prototype.getProperty = function (nObjID, nPropID, objRetVal)
{
	var pDTSvr = this.m_objDoc.findQueryResult (this.m_strFieldName);
	if (null == pDTSvr)
		return StdCore.E_FAIL;

	if (nPropID == -1)
	{
		var arNewArgs = this.makeArgumentList (null);
		var objTempVal = new CVariantX ();
		var nResult = pDTSvr.action (nObjID, 0, arNewArgs, objTempVal);
		if (nResult != StdCore.S_OK)
			return nResult;
	
		objRetVal.setValue (objTempVal);
		return StdCore.S_OK;
	}

	return this.getPropertyL (nPropID, null, objRetVal);
}

/**
 * CDataTableServer 클래스
 */
function CDataTableServer (bOneBase)
{
	this.m_bOneBase = bOneBase;
	
	this.m_objDataTable = null;
}

CDataTableServer.prototype = new CExeServer ()
CDataTableServer.prototype.constructor = CDataTableServer;

CDataTableServer.prototype.CDataTableServer = function (objDataTable)
{
	this.m_objDataTable = objDataTable;
}

CDataTableServer.prototype.attach = function (dtBuffer)
{
	if (null == dtBuffer)
	{
		return true;
	}
	
	this.m_objDataTable = dtBuffer;

	return true;
}

CDataTableServer.prototype.containsColumnName = function (strColumnName)
{
	var nColLen = this.m_objDataTable.m_arColName.length;
	
	for (var i = 0; i < nColLen; i+=1)
	{
		if (this.m_objDataTable.m_arColName[i] == strColumnName)
		{
			return true;
		}
	}

	return false;
}

CDataTableServer.prototype.getRealIndex = function (nIndex)
{
	if (this.m_bOneBase == true && 0 < nIndex)
		nIndex -= 1

	return nIndex;
}

CDataTableServer.prototype.isValidServer = function ()
{
	return (null != this.m_objDataTable);
}

CDataTableServer.prototype.getPropertyL = function (wNameID, pvaArgs, pRetVal)
{
	switch (wNameID)
	{
	case 0 : case 203 :return this.get_Value(pvaArgs, pRetVal);		// 값
	case 1 : case 202 :return this.get_Property(202, pvaArgs, pRetVal);	// 크기
	case 5 : case 220 :return this.get_Property(220, pvaArgs, pRetVal);	// 열크기
	case 6 : case 204 :return this.get_Property(204, pvaArgs, pRetVal);	// 타입
	default : return StdCore.E_NOT_DEF_PROPERTY;
	}
}

CDataTableServer.prototype.setPropertyL = function (wNameID, pvaArgs, pRetVal)
{
	switch (wNameID)
	{
	default : return StdCore.E_NOT_DEF_PROPERTY;
	}
}

CDataTableServer.prototype.actionL = function (wPropID, pvaArgs, pRetVal)
{
	switch (wPropID)
	{
	case 2: case 216: return raw_ArrayFunc (216, pvaArgs, pRetVal);	// 추가
	case 3: case 217: return raw_ArrayFunc (217, pvaArgs, pRetVal);	// 삭제
	case 4: case 218: return raw_ArrayFunc (218, pvaArgs, pRetVal);	// 모두삭제
	default : return this.getPropertyL (wPropID, pvaArgs, pRetVal);
	}
}

CDataTableServer.prototype.get_Property = function (nNameID, arArgs, objRetVal)
{
	objRetVal.setValueType(CVariantX._vtInt, 0);
	
	switch (nNameID)
	{
	case 204 : objRetVal.setValueType(CVariantX._vtInt, 1083); break; // 타입 (#배열)
	case 202 : // 크기
	{
		var nValue = (null != this.m_objDataTable) ? this.m_objDataTable.getRowCount() : 0;
		objRetVal.setValueType(CVariantX._vtInt, nValue);
		break;
	}
	case 220 : // 열크기
	{
		var nCount = 0;
		if (null != this.m_objDataTable && 0 < this.m_objDataTable.getRowCount())
		{
			nCount = this.m_objDataTable.getColCount();
		}
		objRetVal.setValueType(CVariantX._vtInt, nCount);
		break;
	}
	default :
		return StdCore.E_NOT_DEF_PROPERTY;
	}

	return StdCore.S_OK;
}

CDataTableServer.prototype.get_Value = function (arArgs, objRetVal)
{
	if (null == arArgs || 1 > arArgs.length)
		return StdCore.E_NOT_MATCH_PARAM_CNT;

	objRetVal.setValueType(CVariantX._vtString, "");
	var nArgCnt = arArgs[0].toInt ();
	
	if (1 == nArgCnt)
	{
		var nType1 = arArgs[1].getType();
		
		if (nType1 == CVariantX._vtInt) //객배.값[0]
		{
			var nRow = arArgs[1].toInt();
			nRow = this.getRealIndex(nRow);
	
//			var objRowTable = getRowTable(nRow);
//	
//			var pServer = new CDataRowServer(m_objDoc, objRowTable, isOneBase());
//			objRetVal.setValue(pServer);
		}
		else if (nType1 != CVariantX._vtInt) //열의 값을 돌려준다. 객배.값["NAME"]
		{
			var strColName = arArgs[1].toStringX();
	
			if (1 == this.m_objDataTable.getRowCount())
			{
				//new JBinDataTableHelper(m_objDataTable).setReturnValue(objRetVal, 0, strColName);
			}
			else
			{
//				var pColData = JBinDataTableHelper.getTableByColumnName (m_objDataTable, strColName);
//	
//				if (null != pColData)
//				{
//					var pServer = new CDataColServer(m_objDoc, pColData, true, isOneBase());
//					objRetVal.setValue (pServer);
//				}
			}
		}
	}
	else if (2 == nArgCnt)
	{
		var nType1 = arArgs[1].getType();
		var nType2 = arArgs[2].getType();
		
		if (nType1 == CVariantX._vtInt && nType2 == CVariantX._vtInt) //객배.값[0, 0]
		{
			var nRow = this.getRealIndex(arArgs[1].toInt());
			var nCol = this.getRealIndex(arArgs[2].toInt());
			
			this.m_objDataTable.setReturnValue(objRetVal, nRow, nCol);
		}
		else if (nType1 == CVariantX._vtInt && nType2 != CVariantX._vtInt) //객배.값[0, "NAME"]
		{
			var nRow = arArgs[1].toInt ();
			nRow = this.getRealIndex(nRow);
	
			var strColName = arArgs[2].toStringX();
	
			this.m_objDataTable.setReturnValueColName(objRetVal, nRow, strColName);
		}
		else if (nType1 != CVariantX._vtInt && nType2 == CVariantX._vtInt) //객배.값["NAME", 0]
		{
			var nRow = arArgs[2].toInt ();
			nRow = this.getRealIndex(nRow);
	
			var strColName = arArgs[1].toStringX();
	
			this.m_objDataTable.setReturnValueColName(objRetVal, nRow, strColName);
		}
	}

	return StdCore.S_OK;
}

CDataTableServer.prototype.raw_ArrayFunc = function (wNameID, pvaArgs, pRetVal)
{
	if (false == this.isValidServer())
		return StdCore.S_OK;

	switch (wNameID)
		{
	default:
		return StdCore.E_NOT_DEF_PROPERTY;
	}

	return StdCore.S_OK;
}


/**
 * CDataRowServer 클래스
 */
function CDataRowServer (bOneBase)
{
	this.m_nRowIndex = nRowIndex;
	
	this.CDataTableServer(bOneBase);
}

CDataRowServer.prototype = new CDataTableServer ()
CDataRowServer.prototype.constructor = CDataRowServer;


function CDataColServer (bOneBase)
{
	this.m_nColIndex = nRowIndex;
	
	this.CDataTableServer(bOneBase);
}

CDataColServer.prototype = new CDataTableServer ()
CDataColServer.prototype.constructor = CDataColServer;


function CDBServer (nDBIndex)
{
	this.m_nDBIndex = nDBIndex;
}

/**
 * 저장 프로시저를 실행한다.
 */
CDBServer.prototype.executeProcedure = function (arArgs, objRetVal)
{
	var objDBIOParam = this.makeProcedureParam(arArgs);
	
	g_objDoc.getExeScript().executeProcedure(objDBIOParam);
	
	this._handleProcedureParam(arArgs, objDBIOParam);
	
//	var objRSetServer = new CRSetServer(m_objDoc);
//	objRSetServer.setResult(objServiceParameter.getScriptParameter().getDBIOParam().getResult());
//	objRSetServer.setColumnName(objServiceParameter.getScriptParameter().getDBIOParam().getColumnName());
//	objRetVal.setValue(objRSetServer);
}

/**
 * 디비.저장프로시저()에 쓰이는 인자를 만든다.
 */
CDBServer.prototype.makeProcedureParam = function (arArgs)
{
	var objDBIOParam = new DBIOParam(this.m_nDBIndex);
	
	var nArgCnt = arArgs[0].toInt();		
	var strQuery = arArgs[1].toStringX();
	objDBIOParam.setQuery(strQuery);
	
	if (1 < nArgCnt && arArgs[2].isVarArray())
	{
		var arOriginalParams = arArgs[2].toArray();
		var nSize = arOriginalParams.getSize();
		var arParam = new Array(nSize);
				
		for (var i = 0; i != nSize; i++)
		{
			var objParam = arOriginalParams.getAt(i);
			var arParamInfos = objParam.toArray();
			var arValues = new Array (arParamInfos.getSize());
			for (var j = 0, nInfoCount = arParamInfos.getSize(); j != nInfoCount; j++)
			{
				var objInfo = arParamInfos.getAt(j);
				var objValue = objInfo.getValue();
				if (null == objValue)
				{
					objValue = "";
				}
				
				arValues[j] = objValue;
			}
			arParam[i] = arValues;
		}
		
		objDBIOParam.setParam(arParam);
	}
	
	return objDBIOParam;
}

/**
 * 디비.저장프로시저() 매개변수를 처리한다.
 */
CDBServer.prototype._handleProcedureParam = function (arArgs, objDBIOParam)
{
	var arParams = objDBIOParam.getParam();
	
	var nArgCount = arArgs.length;
	if (1 < nArgCount)
	{
		var objVarArray = new CVarArrayX ();

		var nRowLen = arParams.length;
		for (var i = 0 ; i < nRowLen ; i+=1)
		{
			var objRetValue = this._makeRowData(arParams[i]);
			
			objVarArray.add(objRetValue);
		}
		
		arArgs[2].setValueType(CVariantX._vtArray, objVarArray);
	}
}

CDBServer.prototype._makeRowData = function (arRealResult)
{
	var objRetValue = new CVariantX();
	objRetValue.makeVarArray();

	var nLen = arRealResult.length;
	for (var i = 0 ; i < nLen ; i+=1)
	{
		objRetValue.toArray().setAtGrow(i, arRealResult[i]);
	}
	
	return objRetValue;
}

