/**
 * 팝업  Javascript 클래스 목록
 * 	- PopupAtom
 *	- PopupHeader
 */

/**
팝업 Result XML 형식

<BindPopup>
	<DataRow DisplayType="">
		<Column>
		</Column>
		...
	</DataRow>
	...
</BindPopup>
*/
function PopupAtom (strVarName, // 1
				nScriptIndex, // 2
				nSQLIndex, // 3
				nPopKind, // 4
				arDataInfoList, // 5
				bReSearchAll, // 6
				strPopupTitle, // 7
				nWidth, // 8
				nHeight, // 9
				bBorder, // 10
				strBackgroundColor, // 11
				strFontFamily, // 12
				nFontSize, // 13
				strFontColor, // 14
				strFontBold, // 15
				strFontItalic, // 16
				strFontUnderline, // 17
				strFontStrikeout, // 18
				bShowTreeExtend, // 19
				bShowTreeRoot, // 20
				bShowTreeLine, // 21
				bCheckForeignKey, // 22
				nOffsetTabOrder) // 23
{
	this.m_strVarName = strVarName;			// 팝업 아톱 변수명
	this.m_nScriptIndex = nScriptIndex;		// 팝업아톰 스크립트 인덱스
	this.m_nSQLIndex = nSQLIndex;
	this.m_nPopKind = nPopKind;					// 팝업 종류 0:DB,1:자체정의
	this.m_arDataInfoList = arDataInfoList;		// 데이터 정보
	this.m_bReSearchAll = bReSearchAll;
	this.m_strPopupTitle = strPopupTitle;			// 팝업 제목
	this.m_nTop = 0;								// 팝업 창 X Pos
	this.m_nLeft = 0;								// 팝업 창 Y Pos
	this.m_nWidth = nWidth;							// 팝업 창 너비
	this.m_nHeight = nHeight;						// 팝업 창 높이
	this.m_bBorder = bBorder;						// 보더 표시 여부
	this.m_strBackgroundColor = strBackgroundColor;	// 팝업창 배경색상
	this.m_strFontFamily = strFontFamily;			// 폰트
	this.m_nFontSize = nFontSize;					// 폰트크기
	this.m_strFontColor = strFontColor;				// 폰트 색상
	this.m_strFontBold = strFontBold;				// 폰트 굵게
	this.m_strFontItalic = strFontItalic;			// 폰트 기울임
	this.m_strFontUnderline = strFontUnderline;		// 폰트 밑줄
	this.m_strFontStrikeout = strFontStrikeout;		// 폰트 취소선
	this.m_bShowTreeExtend = bShowTreeExtend;	// 트리 확장표시 여부
	this.m_bShowTreeRoot = bShowTreeRoot;		// 트리 최상위 표시 여부
	this.m_bShowTreeLine = bShowTreeLine;		// 트리 구분선 표시 여부
	this.m_bCheckForeignKey = bCheckForeignKey;	// 유효성 검사 수행 여부
	this.m_nOffsetTabOrder = nOffsetTabOrder;	// 팝업후 커서위치
	
	this.m_objPopupHeader = null;
	this.m_nSelectIndex = -1;
	this.m_xnResultDoc = null;					// 서버에서 전달받은 결과 XML
	this.m_strScrollName = null;				// 스크롤에 묶여 있을 경우 스크롤 아톰 변수명
	this.m_heEventAtom = null;					// 팝업 이벤트가 발생한 아톰 HTML
	this.m_objInputAtom = null; 
	this.m_bSearchPopUp = false;
	this.m_bOperation = true; 					// 묶인 아톰들에서 연산식이 일어나야 하는지 여부
	this.m_nPopupCursorSize = 200;		// 팝업 커서 동작시 가져오는 데이터 갯수, 변경가능
	this.m_nPopupCursorPos = 0;			// 팝업 커서 동작 데이터 가져오는 위치
	
	//WebPortalServie 관련 Cursor동작 정보 추가 
	this.m_strCursorActon = "";
	this.m_strCursorDbindex = "";
	this.m_strCursorDbkind = "";
	this.m_strCursorConnection = "";
}

PopupAtom.prototype.setCursorAction = function (strCursorActon)
{
	if (null != strCursorActon)
	{
		this.m_strCursorActon = strCursorActon;
	}
}

PopupAtom.prototype.setCursorDbindex = function (strCursorDbindex)
{
	if (null != strCursorDbindex)
	{
		this.m_strCursorDbindex = strCursorDbindex;
	}
}

PopupAtom.prototype.setCursorDbkind = function (strCursorDbkind)
{
	if (null != strCursorDbkind)
	{
		this.m_strCursorDbkind = strCursorDbkind;
	}
}

PopupAtom.prototype.setCursorConnection = function (strCursorConnection)
{
	if (null != strCursorConnection)
	{
		this.m_strCursorConnection = strCursorConnection;
	}
}	

PopupAtom.prototype.getCursorAction = function ()
{
	return this.m_strCursorActon;
}

PopupAtom.prototype.getCursorDbindex = function ()
{
	return this.m_strCursorDbindex;
}

PopupAtom.prototype.getCursorDbkind = function ()
{
	return this.m_strCursorDbkind;
}

PopupAtom.prototype.getCursorConnection = function ()
{
	return this.m_strCursorConnection;
}	
PopupAtom.prototype.init = function ()
{
	this._initHeader();
	
	if (PopupAtom.MEMORYDATA == this.m_nPopKind)
	{
		this._initMemoryData();
	}
}

/**
 *	@return 팝업에 묶인 아톰변수명을 배열로 리턴
 */
PopupAtom.prototype.getBindedAtomVarNames = function ()
{
	var arVarName = new Array();
	
	if (PopupAtom.DBDATA == this.m_nPopKind)
	{
		for (var i = 0; i < this.m_arDataInfoList.length; i += 1)
		{
			var objDataInfo = this.m_arDataInfoList[i];
			arVarName.push(objDataInfo.getRefVarName())
		}
	}
	
	return arVarName;
}

PopupAtom.prototype.getScrollName = function ()
{
	return this.m_strScrollName;
}

PopupAtom.prototype.getVarName = function ()
{
	return this.m_strVarName;
}

/**
 * 아톰리스트에 추가
 */
PopupAtom.prototype.putAtom = function ()
{
	PopupAtom._atoms[this.m_strVarName] = this;
}

PopupAtom.prototype.setIsSearchPopUp = function (bSearch)
{
	this.m_bSearchPopUp = bSearch;
}

PopupAtom.prototype.getResultDoc = function ()
{
	return this.m_xnResultDoc;
}

PopupAtom.prototype.setResultDoc = function (xnResultDoc)
{
	this.m_xnResultDoc = xnResultDoc;
}

PopupAtom.prototype.getPopHeader = function ()
{
	return this.m_objPopupHeader;
}

PopupAtom.prototype.setVarName = function (strVarName)
{
	this.m_strVarName = strVarName;
}

/*
 * 자체정의 팝업인가?
 */
PopupAtom.prototype.isMemoryPopup = function ()
{
	return (PopupAtom.MEMORYDATA == this.m_nPopKind) ? true : false;
}

PopupAtom.prototype.setIsOperation = function (bOperation)
{
	this.m_bOperation = bOperation;
}
	
PopupAtom.prototype.isOperation = function ()
{
	return this.m_bOperation;
}

/**
 * 수행조건 일때 팝업 동작을 수행합니다.
 *
 * @param strScrollName
 * @param heEventAtom
 */
PopupAtom.prototype.executeSearchRowPopup = function (strScrollName, heEventAtom, objEvent)
{
	this._setSearchConditionAtomInfo(strScrollName, heEventAtom, objEvent);
	return this._openPopup();
}

/**
 * 입력란 일때 팝업 동작을 수행합니다.
 *
 * @param strScrollName
 * @param heEventAtom
 */
PopupAtom.prototype.executeInputDataPopup = function (strScrollName, objInputAtom, objEvent)
{
	this._setInputAtomInfo(strScrollName, objInputAtom, objEvent);
	return this._openPopup();
}

PopupAtom.prototype.executeConnectionModel = function (bButtonExec)
{
	var objConModelInfo = this.m_objPopupHeader.getConnctionModelInfo(this.m_nSelectIndex);
	if (null == objConModelInfo)
	{
		return;
	}
	
	if (!objConModelInfo.isConnectionModel())
	{
		return;
	}
	
	if (objConModelInfo.isButtonExec() && !bButtonExec)
	{
		return;
	}
	
	var strRefVarName = objConModelInfo.getConnectionRefKey();
	var strConnectionModelName = objConModelInfo.getConnectionModelName();
	
	PQConnectionModel.open(strConnectionModelName, strRefVarName);
}

/*
 * 자체정의 팝업을 실행한다. 
 * 해당 컬럼명의 값 중에서 비교값과 일치하는 자체정의 목록이 존재하면 나머지 아톰에 자체정의의 값을 넣어주고, 
 * 없으면 아무 동작도 하지 않는다.
 * @param strVarName 자체정의 컬럼 중에서 비교할 아톰변수명.
 * @param strValue 자체정의에서 찾을 비교값.
 * @param objInputAtom 팝업동작이 일어난 아톰변수(입력란)
 * @param strScrollName 스크롤이름 (스크롤에 묶였을 경우)
 */
PopupAtom.prototype.executeMemoryPopup = function (strVarName, strValue, objInputAtom, strScrollName)
{
	if (null == this.m_objPopupHeader || null == this.m_xnResultDoc ||
		null == strVarName || 0 == strVarName.length ||
		null == strValue || 0 == strValue.length ||
		null == objInputAtom
		)
	{
		return;
	}
	
	this.m_objInputAtom = objInputAtom; //입력란 아톰 저장
	this.m_strScrollName = strScrollName; //스크롤 이름 저장
	
	var nColumnLen = this.m_objPopupHeader.getColumnLength();
	for (var columnIndex = 0; columnIndex < nColumnLen; columnIndex=columnIndex+1)
	{
		var strRefVarName = this.m_objPopupHeader.getColumnRefVarName(columnIndex);
		if (strRefVarName == strVarName)
		{
			var xnDataRowList = XmlLib.selectNodeList(this.m_xnResultDoc, "/BindPopup/DataRow");
			if (null == xnDataRowList)
			{
				return;
			}
			
			var nRowLen = xnDataRowList.length;
			for (var rowIndex = 0; rowIndex != nRowLen; rowIndex=rowIndex+1)
			{
				var xnDataRow = xnDataRowList[rowIndex];
				if (null != xnDataRow)
				{				
					var xnColumnList = xnDataRow.childNodes;
					if (null != xnColumnList)
					{
						var xnColumn = xnColumnList[columnIndex];
						if (null != xnColumn)
						{
							var strMemoryValue = XmlLib.getTextValue(xnColumn);
							strValue = Utils.replace(strValue, ",",""); //숫자에 통화기호 (',')가 들어갈경우 제외
							if (strMemoryValue == strValue)
							{
								this._assignPopupResultData(xnDataRow);
								return;
							}
						}
					}
				}
			}
		}
	}
}

/////////////////////////////
// public method
//

/**
 * 팝업창에서 선택한 결과를 팝업에 묶인 아톰에 반영합니다.
 *
 * @param xnDoc	: 팝업창에 검색된 결과 xml
 * @param nSelectedIndex : 선택한 index
 */
PopupAtom.prototype.assignPopupResult = function (xnDoc, nSelectIndex)
{
	this.m_nSelectIndex = nSelectIndex;
	
	var xnResultDoc = xnDoc;
	if (null == xnResultDoc)
	{
		return;
	}
	
	var xnDataRowList = XmlLib.selectNodeList(xnResultDoc, "/BindPopup/DataRow");
	if (null == xnDataRowList)
	{
		return;
	}
	
	var xnDataRow = xnDataRowList[nSelectIndex];
	if (null != xnDataRow)
	{
		this._assignPopupResultXml(xnDataRow);
	}
}

PopupAtom.prototype._assignPopupResultXml = function (xnDataRow)
{
	if (null == xnDataRow)
	{
		return;
	}
	
	if (this.m_bSearchPopUp)
	{
		this._assignSearchPopupResultData(xnDataRow);
	}
	else if (ContainsGridExAtom() && null != GridExAtom.getAtom(this.m_strScrollName))
	{
		// 그리드에 값 저장
		var objGridExAtom = GridExAtom.getAtom(this.m_strScrollName)
		this._assignGridPopupResult (objGridExAtom, xnDataRow);
	}
	else
	{
		if ("DataRow" == xnDataRow.nodeName)
		{
			var strSelectedRowIndex = XmlLib.getTextValue(xnDataRow.selectSingleNode("SelectedIndex"));
			this.m_nSelectIndex = parseInt (strSelectedRowIndex);
		}
		
		this._assignPopupResultData(xnDataRow);
		
		if (PopupAtom.MEMORYDATA == this.m_nPopKind)
		{
			this.executeConnectionModel(false);
		}
	}
}

PopupAtom.prototype.isCheckPopupForeignKey = function ()
{
	return this.m_bCheckForeignKey;
}

PopupAtom.prototype.getOffsetTabOrder = function ()
{
	return this.m_nOffsetTabOrder;
}
	
PopupAtom.prototype.makePopupRequest = function (xnAtomRequest)
{
	this._makePopupRequest(xnAtomRequest);
}

PopupAtom.prototype.setScrollName = function (strScrollName)
{
	this.m_strScrollName = strScrollName;
}


/////////////////////////////
// private method
//

/**
 * 팝업 헤더 정보를 구성합니다.
 */
PopupAtom.prototype._initHeader = function ()
{
	var objPopupHeader = new PopupHeader();
	objPopupHeader.init(this.m_nPopKind, this.m_arDataInfoList);
	
	this.m_objPopupHeader = objPopupHeader;
}

/**
 * 자체정의 데이터을 팝업 Result XML 형식으로 구성합니다.
 */
PopupAtom.prototype._initMemoryData = function ()
{
	this.m_xnResultDoc = null;
	
	if (null == this.m_arDataInfoList)
	{
		return;
	}
	
	var xnResultDoc = XmlLib.createXML("BindPopup");
	var xnResult = xnResultDoc.documentElement;
	
	var xnHeaderInfo = XmlLib.createChild(xnResult, "HeaderInfo");
	this._makePopupHeaderRequest(xnHeaderInfo);
	
	var nLen = this.m_arDataInfoList.length;
	for (var i = 0; i < nLen; i=i+1)
	{
		var objDataInfo = this.m_arDataInfoList[i];
		if (null == objDataInfo)
		{
			continue;
		}
		
		var xnDataRow = XmlLib.createChild(xnResult, "DataRow");
		
		this._initMemoryDataRow(xnResultDoc, xnDataRow, objDataInfo);
	}
	
	this.m_xnResultDoc = xnResultDoc;
}

/**
 * 자체정의 데이터의 행 정보를 구성합니다.
 *
 * @param xnResultDoc
 * @param xnDataRow
 * @param objDataInfo
 */
PopupAtom.prototype._initMemoryDataRow = function (xnResultDoc, xnDataRow, objDataInfo)
{
	var arPopupItemList = objDataInfo.getPopupItemList();
	if (null == arPopupItemList)
	{
		return;
	}
	
	var nItemLen = arPopupItemList.length;
	for (var i = 0; i < nItemLen; i=i+1)
	{
		var strPopupItem = arPopupItemList[i];
		
		var xnColumn = XmlLib.createChild(xnDataRow, "Col");
		
		this._initMemoryDataColumn(xnColumn, strPopupItem);
	}
}

/**
 * 자체정의 데이터의 열 정보를 구성합니다.
 *
 * @param xnColumn
 * @param strPopupItem
 */
PopupAtom.prototype._initMemoryDataColumn = function (xnColumn, strPopupItem)
{
	//xnColumn.setAttribute("DisplayType", "0");
	XmlLib.setTextValue(xnColumn, strPopupItem);
}

/**
 * 자체정의 데이터 팝업에 대한 연결검색 정보를 설정합니다.
 *
 * @param xnColumn
 * @param strConnectionRefKey
 */
/*var initMemoryDataColumn_ConnectionInfo = function (xnColumn, strConnectionRefKey)
{
	if (null != strConnectionRefKey && 0 < strConnectionRefKey.length)
	{
		xnColumn.setAttribute("ConnectionRefKey", strConnectionRefKey);
	}
}*/


/**
 * 서버에서 검색해온 DB 데이터 결과를 구성합니다.
 *
 * @xnResultDoc
 */
PopupAtom.prototype._initDBData = function (xnResultDoc)
{
	if (null == xnResultDoc)
	{
		return;
	}
	
	var xnResult = HandleResult.getAtomResultNode(xnResultDoc);
	var xnPopupResult = XmlLib.selectSingleNode(xnResult, "./BindPopup");
	if (null == xnPopupResult)
	{
		return;
	}
	
	return XmlLib.loadXMLFromString(XmlLib.serializeToString(xnPopupResult));
}

/**
* 입력란에서 팝업 이벤트가 발생할때 아톰 정보를 설정한다.
* @param strScrollName
* @param objInputAtom 팝업이 발생한 입력란 아톰
* @param objEvent
*/
PopupAtom.prototype._setInputAtomInfo = function (strScrollName, objInputAtom, objEvent)
{
	this.m_strScrollName = strScrollName;
	this.m_objInputAtom = objInputAtom;
	
	this.m_nTop = objEvent.screenY;
	this.m_nLeft = objEvent.screenX;
}


/**
* 수행조건에서 팝업이벤트가 발생할때 아톰정보를 설정
* @strScrollName
* @heEventAtom 발생한 이벤트의 html element
* @objEvent
*/
PopupAtom.prototype._setSearchConditionAtomInfo = function (strScrollName, heEventAtom, objEvent)
{
	this.m_strScrollName = strScrollName;
	this.m_heEventAtom = heEventAtom;
	
	this.m_nTop = objEvent.screenY;
	this.m_nLeft = objEvent.screenX;
	
	this.m_nFontSize = 10;
	this.m_strFontColor = "#000000";
}

/**
 * 서버에 서비스를 요청할 때 필요한 문서 정보를 설정합니다.
 */
PopupAtom.prototype.setModelInfo = function ()
{
	//SetServiceName("PopupAction");
	GlobalField.setServiceName("SearchAction");
	GlobalField.setServiceEventName("Popup");
	GlobalField.setEventVarName(this.m_strVarName);
}

/**
 * 서비스 요청 정보를 구성합니다.
 * @retuen xnRequestDoc
 */
PopupAtom.prototype.makeRequest = function ()
{
	var xnRequest = MakeRequest.createRequestNode();
	
	MakeRequest.makeServiceRequest(xnRequest);
	
	MakeRequest.makeAtomRequest(xnRequest);		// 스크롤, 검색창, 트리의 변수 값을 치환하기 위해	
	
	var xnAtomRequest = MakeRequest.getAtomRequestNode(xnRequest);
	this._makePopupRequest(xnAtomRequest);
	
	return xnRequest.ownerDocument;
}

/**
 * 팝업 동작에 대한 서비스 요청 정보를 구성합니다.
 * @param xnAtomRequest
 */
PopupAtom.prototype._makePopupRequest = function (xnAtomRequest)
{
	var xnPopupRequest = XmlLib.createChild(xnAtomRequest, "BindPopup");
	xnPopupRequest.setAttribute("VarName", this.m_strVarName);
	xnPopupRequest.setAttribute("SQLIndex", this.m_nSQLIndex);
	xnPopupRequest.setAttribute("PopKind", this.m_nPopKind);
	
	
	
	var xnServiceInfo = XmlLib.createChild(xnPopupRequest, "ServiceInfo");
	this._makePopupServiceRequest(xnServiceInfo);
	
	//WebPortalServie 관련 Cursor동작 정보 추가 
	xnServiceInfo.setAttribute("CursorAction", this.m_strCursorActon);
	xnServiceInfo.setAttribute("CursorDbindex", this.m_strCursorDbindex);
	xnServiceInfo.setAttribute("CursorDbkind", this.m_strCursorDbkind);
	xnServiceInfo.setAttribute("CursorConnection", this.m_strCursorConnection);
	
	var xnHeaderInfo = XmlLib.createChild(xnPopupRequest, "HeaderInfo");
	this._makePopupHeaderRequest(xnHeaderInfo);
}

/**
 * 팝업 동작에 대한 서비스 요청 정보를 구성합니다.
 *  - 서버 검색시 필요한 정보
 *
 * @param xnServiceInfo
 */
PopupAtom.prototype._makePopupServiceRequest = function (xnServiceInfo)
{
	var strOrderField = "";//this.m_objPopupHeader.getOrderField(strVarName);
	var strOrderKey = "";//objBindedAtom.getValue();

	if (false == this._isBindedElementExist())
	{
		return;
	}
	
	if (null != this.m_objInputAtom)
	{
		this._setNormalPopService(xnServiceInfo);
	}
	else
	{
		this._setSearchPopService(xnServiceInfo);
	}	
}

/**
 * 일반 팝업에 정렬필드와 검색키에 관한 정보를 구성하여 요청의 
 * xnServiceInfo에 설정한다. 
 * @param xnServiceInfo (팝업 요청의 서비스 정보 XML)
 */
PopupAtom.prototype._setNormalPopService = function (xnServiceInfo)
{
	objBindedAtom = this._getBindedAtom(this.m_objInputAtom.getVarName(), this.m_strScrollName, this.m_objInputAtom);
	
	if (null == objBindedAtom)
	{
		return;
	}
	
	var strVarName = objBindedAtom.getVarName();
	if (0 == strVarName.indexOf("__GRIDEX_"))
	{
		var arStr = strVarName.split("_");
		strVarName = arStr[arStr.length - 1];
	}

	var strOrderField = this.m_objPopupHeader.getOrderField(strVarName);
	var strOrderKey = objBindedAtom.getValue();
	
	this._setPopServiceAttribute(xnServiceInfo, strOrderField, strOrderKey);
}

/**
 * 수행조건 팝업에 정렬필드와 검색키에 관한 정보를 구성하여 요청의 
 * xnServiceInfo에 설정한다. 
 * @param xnServiceInfo (팝업 요청의 서비스 정보 XML)
 */
PopupAtom.prototype._setSearchPopService = function (xnServiceInfo)
{
	var strRowID = this.m_heEventAtom.id;
	var nEditIndex = strRowID.substring(strRowID.lastIndexOf('_') + 1);

	if (null == nEditIndex)
	{
		return;
	}

	var strOrderField = this.m_objPopupHeader.getOrderFieldOnEditIndex(nEditIndex);
	var strOrderKey = this.m_heEventAtom.value;
	
	this._setPopServiceAttribute(xnServiceInfo, strOrderField, strOrderKey);
}

/**
 * 팝의 요청의 xnServiceInfo(서비스 정보 요소)에 정렬 필드와, 검색 키(?)의속성을 설정한다.  
 * @param xnServiceInfo(서비스 정보보 요소)
 * @param strOrderField (정렬 필드 속성)
 * @param strOrderKey
 */
PopupAtom.prototype._setPopServiceAttribute = function (xnServiceInfo, strOrderField, strOrderKey)
{
	xnServiceInfo.setAttribute("OrderBy", strOrderField);
	xnServiceInfo.setAttribute("OrderKey", strOrderKey);
	xnServiceInfo.setAttribute("ReSearchAll", this.m_bReSearchAll ? "Y" : "N");
	
	xnServiceInfo.setAttribute("CursorSize", this.m_nPopupCursorSize);
	xnServiceInfo.setAttribute("CursorPos", this.m_nPopupCursorPos);
}

/**
 * 팝업이 팝업 아톰 요소를 가지고 있는가??
 * , 팝업에 묶인 아톰 또는 html(수행조건의 경우)이 없다면, false를 반환한다. 
 * @return boolean(있다, 없다)
 */
PopupAtom.prototype._isBindedElementExist = function ()
{
	if (null != this.m_objInputAtom || null != this.m_heEventAtom)
	{
		return true;
	}
	return false;
}

/**
 * 팝업 동작에 대한 서비스 요청 정보를 구성합니다.
 *  - 검색 결과 구성시 필요한 정보
 *
 * @param xnHeaderInfo
 */
PopupAtom.prototype._makePopupHeaderRequest = function (xnHeaderInfo)
{
	var objPopupHeader = this.m_objPopupHeader;
	if (null == objPopupHeader)
	{
		return;
	}
	
	if (null != this.m_strScrollName)
	{
		xnHeaderInfo.setAttribute("ScrollName", this.m_strScrollName);
	}
	
	var nLen = objPopupHeader.getColumnLength();
	for (var i = 0; i < nLen; i=i+1)
	{
		var xnColumn = XmlLib.createChild(xnHeaderInfo, "Column");
	
		var nDisplayType = objPopupHeader.getColumnDisplayType(i);
		xnColumn.setAttribute("DisplayType", nDisplayType);
		
		var strRefVarName = objPopupHeader.getColumnRefVarName(i);
		xnColumn.setAttribute("RefVarName", strRefVarName);
		
		var strFieldName = objPopupHeader.getColumnFieldName(i);
		xnColumn.setAttribute("FieldName", strFieldName);
	}
}

PopupAtom.prototype._openTreePopup = function ()
{
	var objPopupInfo = this._makePopupInfo(); //팝업창을 위한 정보를 생성한다.
	this._makeTreePopupInfo(objPopupInfo);
	
	var strWindowPath = IsWPQModel() ? "./ups/sys/html/support/TreePopupAtomWindow_WPQ.html" : "/ups/sys/html/support/TreePopupAtomWindow.html";
	var xnDataRow = this._createPopupWindow(strWindowPath, objPopupInfo);
	
	this._assignPopupResultData(xnDataRow);
}

/**
 * 팝업 창을 만들고 팝업 Result XML을 팝업 창에 뿌려줍니다.
 */
PopupAtom.prototype._openPopup = function ()
{

	if (this._isTreePopup())
	{
		this._openTreePopup();
	}
	else
	{
		var xnResultDoc = null;
		
		if (PopupAtom.DBDATA == this.m_nPopKind)
		{
			this.setModelInfo();
			
			var xnRequestDoc = this.makeRequest();
			
			xnResultDoc = this.executeDBPopupService(xnRequestDoc);
		}
		else if (PopupAtom.MEMORYDATA == this.m_nPopKind)
		{
			var strValue = this.m_objInputAtom.getValue();
			
			// 임시로 아톰 입력값과 일치하는 항목으로만 구성된 xml을 생성한다.
			xnResultDoc = this._makeTempMemoryPopupData(strValue, this.m_objInputAtom.getVarName());
		}
		
		if (null == xnResultDoc || null == xnResultDoc.documentElement || 
			null == xnResultDoc.documentElement.childNodes || 1 == xnResultDoc.documentElement.childNodes.length)
		{
			alert("요청한 작업에 해당하는 데이터가 없습니다.");
			return false;
		}
		
		// 결과 항목이 하나이면 선택할 필요가 없으므로, 팝업을 띄우지 않고 그 값을 설정 
		if (2 == xnResultDoc.documentElement.childNodes.length)
		{
			this.assignPopupResult(xnResultDoc, 0);
			return true;
		}
		
		var xnXSL = PopupAtom.getXSL();
		if (null == xnXSL)
		{
			return false;
		}
		var objPopupInfo = this._makePopupInfo(xnResultDoc, xnXSL); //팝업창을 위한 정보를 생성한다.
		
		var strWindowPath = IsWPQModel() ? "./ups/sys/html/support/PopupAtomWindow_WPQ.html" : "/ups/sys/html/support/PopupAtomWindow.html";
		var objResult = this._createPopupWindow(strWindowPath, objPopupInfo);//일반 팝업창은 누른행의 인덱스를 반환한다.
		
		if (null != objResult && 2 == objResult.length && 
				(PopupAtom.DBDATA == this.m_nPopKind || PopupAtom.MEMORYDATA == this.m_nPopKind))
		{
			switch(objResult[0])
			{
			case "OK":
				// 결과로 xml 리턴
				this._assignPopupResultXml(objResult[1]);
				return true;
			case "CANCEL":
				return false;
			case "REMOVE":
				this.removeData(objResult[1]);
				return false;
			}
		}
		
		return false;
	}
}

PopupAtom.prototype.executeDBPopupService = function (xnRequestDoc)
{	
	var xnResultDoc = PQService.executeService(xnRequestDoc);
	
	this.m_xnResultDoc = this._initDBData(xnResultDoc);
	
	return this.m_xnResultDoc;
}

/**
 * 일반 팝업창을 만듭니다.
 * @param strPopupURL 팝업창 html URL
 * @param arPopupInfo 팝업창 전달 매개변수
 * @return 일반팝업 : 선택한 row 인덱스, 트리팝업: 없음..
 *
 */
PopupAtom.prototype._createPopupWindow = function (strPopupURL, objPopupInfo)
{
	return Utils.showModalDialog(
		strPopupURL,
		objPopupInfo,
		this.m_nLeft, this.m_nTop, this.m_nWidth, this.m_nHeight);
}
/**
* 트리 아톰을 만들기 위한 정보를 생성함
* @param arPopupInfo 트리 팝업창 매개변수
*/
PopupAtom.prototype._makeTreePopupInfo = function (objPopupInfo)
{
	objPopupInfo.Model = g_objModel;
	
	//트리 아톰을 생성하기 위한 정보를 만들어서 팝업창에 넘겨줌
	var arTreeColumnList = new Array();
	
	var nLen = this.m_objPopupHeader.getColumnLength();
	for (var i = 0; i < nLen; i=i+1)
	{
		var strDisplayInfo = this.m_objPopupHeader.getColumnDisplayInfo(i);
		var strFieldName = this.m_objPopupHeader.getColumnFieldName(i);
		var strFieldType = this.m_objPopupHeader.getColumnFieldType(i);
		var nDisplayType = this.m_objPopupHeader.getColumnDisplayType(i);
		var nAlignType = "0"; //항목 정렬 
		var bDefaultKey = false;
		if (null != strDisplayInfo && 0 < strDisplayInfo.length)
		{
			bDefaultKey = true;
		}
		
		var objTreeColumn = new TreeColumn(strFieldName, "", "", strFieldName, false, strDisplayInfo,
							bDefaultKey, true, strFieldType, nDisplayType, false, false, 0, nAlignType);
		
		arTreeColumnList.push(objTreeColumn);
	}
	
	var objTreeHeader = new TreeHeader(TreeAtom.INDEP_TREE, "", arTreeColumnList);
	var nFieldIndex = 0;
	var strOrderField = "";
	var strOrderKey = "";		

	if (null == this.m_objInputAtom && null == this.m_heEventAtom)
	{
		return;
	}
	
	if (null != this.m_objInputAtom)
	{
		var objBindedAtom = this._getBindedAtom(this.m_objInputAtom.getVarName(), this.m_strScrollName, this.m_objInputAtom);
		
		nFieldIndex = this.m_objPopupHeader.getFieldIndex(objBindedAtom.getVarName());
		strOrderField = this.m_objPopupHeader.getOrderField(objBindedAtom.getVarName());
		strOrderKey = objBindedAtom.getValue();
	}
	else
	{
		var strRowID = this.m_heEventAtom.id;
		var nEditIndex = strRowID.substring(strRowID.lastIndexOf('_') + 1);

		if (null == nEditIndex)
		{
			return;
		}

		strOrderField = this.m_objPopupHeader.getOrderFieldOnEditIndex(nEditIndex);

		strOrderKey = this.m_heEventAtom.value;
	}
	
	objPopupInfo.ShowTreeExtend = this.m_bShowTreeExtend;
	objPopupInfo.ShowTreeRoot = this.m_bShowTreeRoot;
	objPopupInfo.ShowTreeLine = this.m_bShowTreeLine;
	objPopupInfo.TreeHeader = objTreeHeader;
	objPopupInfo.FieldIndex = nFieldIndex;
	objPopupInfo.OrderField = strOrderField;
	objPopupInfo.OrderKey = strOrderKey;
	
	var objOpener = window.opener;
	
	if (null != objOpener)
	{
		objPopupInfo.Opener = objOpener;
	}
	else
	{
		objPopupInfo.Opener = self;
	}

	objPopupInfo.ModelSubPath = GetModelSubPath();
}

/**
* 일반 팝업에 전달할 매개변수 정보를 구성합니다.
* @param xnResultDoc
* @param xnXSL
* @return 전달 매개변수
*/
PopupAtom.prototype._makePopupInfo = function (xnResultDoc, xnXSL)
{
	var objPopupInfo =
	{
		ModelName : GetModelName(),
		VarName : this.m_strVarName,
		SQLIndex : this.m_nSQLIndex,
		BackgroundColor : this.m_strBackgroundColor,
		ResultDoc : xnResultDoc,
		XSL : xnXSL,
		PopupTitle : this.m_strPopupTitle,
		Width : this.m_nWidth,
		Height : this.m_nHeight,
		FontFamily : this.m_strFontFamily,
		FontSize : this.m_nFontSize,
		FontColor : this.m_strFontColor,
		FontBold : this.m_strFontBold,
		FontItalic : this.m_strFontItalic,
		FontUnderline : this.m_strFontUnderline,
		FontStrikeout : this.m_strFontStrikeout,
		Border : this.m_bBorder,
		ButtonGap : PopupAtom.BUTTON_GAP,
		Gap : PopupAtom.GAP,
		PopupAtom : this
	}
	
	return objPopupInfo;
}

/**
 * 팝업창에서 선택한 결과를 팝업에 묶인 아톰에 설정합니다.
 *
 * @param strScrollName
 * @param heEventAtom
 * @param xnDataRow
 */
PopupAtom.prototype._assignPopupResultData = function (xnDataRow)
{
	if (null == xnDataRow)
		return;
		
	var strScrollName = this.m_strScrollName;
	var heEventAtom = this.m_heEventAtom;
	
	var objPopupHeader = this.m_objPopupHeader;
	if (null == objPopupHeader)
	{
		return;
	}
	
	var xnColumnList = xnDataRow.childNodes;
	if (null == xnColumnList)
	{
		return;
	}
	
	//Script 팝업완료, 팝업동작 이벤트 파라미터
	var strScriptValue = "";
	
	var nLen = objPopupHeader.getColumnLength();
	for (var i = 0; i < nLen; i=i+1)
	{
		if (2 == objPopupHeader.getColumnDisplayType(i))
		{
			continue;
		}
		
		var strRefVarName = objPopupHeader.getColumnRefVarName(i);
		
		var objBindedAtom = this._getBindedAtom(strRefVarName, strScrollName, this.m_objInputAtom);
		if (null == objBindedAtom)
		{
			continue;
		}
		
		var xnColumn = xnColumnList[i];
		if (null == xnColumn)
		{
			continue;
		}
		
		var strValue = XmlLib.getTextValue(xnColumn);
		
		//스크립트 팝업 이벤트 파라미터를 만든다.
		// 형식: 값1$값2$값3
		var strTempValue = strValue;
		if (i != nLen - 1)
		{
			strTempValue = strTempValue + "$";
		}
		strScriptValue = strScriptValue + strTempValue;
		
		if (objBindedAtom.isOperation())
		{
			objBindedAtom.setIsOperation(this.isOperation());
		}
		
		objBindedAtom.setValue(strValue);
		
		if (objBindedAtom.isOperation())
		{
			objBindedAtom.setIsOperation(true);
		}
	}
	
	// _팝업동작
	// 아톰 동작이 발생한 후(팝업창이 닫힌하고 값을 아톰에 세팅한 후)에 발생합니다.
	var nSearchResult = (0 == strScriptValue.length) ? 0 : 1;
	if (-1 != ScriptAtomEvent.onExecutePopup(this.m_nScriptIndex, nSearchResult, strScriptValue))
	{
		ScriptAtomEvent.onExecutePopupAfter(this.m_nScriptIndex, nSearchResult, strScriptValue);
	}
	
	// _팝업완료
	//ScriptAtomEvent.onEndPopup(this.m_nScriptIndex, strScriptValue);
}

PopupAtom.prototype._assignSearchPopupResultData = function (xnDataRow)
{
	var heEventAtom = this.m_heEventAtom;
	
	var objPopupHeader = this.m_objPopupHeader;
	if (null == objPopupHeader)
	{
		return;
	}
	
	var xnColumnList = xnDataRow.childNodes;
	if (null == xnColumnList)
	{
		return;
	}
	var hePop = heEventAtom.parentNode;
	var hePopInputs = hePop.childNodes;
	var nLen = xnColumnList.length;
	for (var i = 0; i < nLen; i=i+1)
	{
		var hePopInput = hePopInputs[i + 1];
		var xnColumn = xnColumnList[i];
		if (null == xnColumn)
		{
			continue;
		}
		
		var strValue = XmlLib.getTextValue(xnColumn);
		if (null == strValue)
		{
			strValue = "";
		}
		hePopInput.value = strValue;
	}
}

/**
 * 팝업으로 선택된 값을 그리드에 설정한다.
 */
PopupAtom.prototype._assignGridPopupResult = function (heGridAtom, xnDataRow)
{
	var xnColumnList = xnDataRow.childNodes;
	if (null == xnColumnList)
	{
		return;
	}
	
	var nLen = xnColumnList.length;
	for (var i = 0 ; i < nLen; i=i+1)
	{
		var strRefName = this.m_objPopupHeader.getColumnRefVarName(i);
		var strValue = XmlLib.getTextValue(xnColumnList[i]);
		
		heGridAtom.setPopValue(strRefName, strValue);
	}
}

/**
 * 팝업창에 묶인 아톰을 가져옵니다.
 *
 * @param strRefVarName
 * @param strScrollName
 * @param heEventAtom
 */
PopupAtom.prototype._getBindedAtom = function (strRefVarName, strScrollName, objInputAtom)
{
	var objBindedAtom = null;
	
	if (null != strScrollName && 0 < strScrollName.length)
	{
		if (null == objInputAtom)
		{
			return null;
		}
	
		var objScrollAtom = null;
		if (ContainsScrollAtom())
		{
			objScrollAtom = ScrollAtom.getAtom(strScrollName)
		}
		if (null != objScrollAtom)
		{
			var nRowIndex = objInputAtom.getRowIndex();
			objBindedAtom = objScrollAtom.getBindedAtom(strRefVarName, nRowIndex);
		}
		
		// 스크롤에 묶여 있지 않으면 그리드에 포함되었는지를 검사한다.
		if (null == objScrollAtom && ContainsGridExAtom())
		{
			var objGridExAtom = GridExAtom.getAtom(strScrollName);
			if (null != objGridExAtom)
			{
				objBindedAtom = objGridExAtom.getBindedAtom(strRefVarName);
			}
		}
	}
	else
	{
		objBindedAtom = null;
		if (ContainsInputDataAtom())
		{
			objBindedAtom = InputDataAtom.getAtom(strRefVarName);
		}
		if (null == objBindedAtom && ContainsInputTimeAtom())
		{
			objBindedAtom = InputTimeAtom.getAtom(strRefVarName);
		}
	}
	
	return objBindedAtom;
}

PopupAtom.prototype._isTreePopup = function ()
{
	return this.m_objPopupHeader.isTreePopup();
}

/**
 * 자체정의 팝업에서 아톰 입력 값과 일치하는 node로만 구성된 xml을 생성 한다.
 *
 * @param	strValue : 아톰 입력 값
 * @param	strVarName : 아톰의 변수명
 */
PopupAtom.prototype._makeTempMemoryPopupData = function (strValue, strVarName)
{		
	if (strValue.length == 0)
	{
		return this.m_xnResultDoc;
	}
	
	var xnTempResultDoc = XmlLib.createXML("BindPopup");
	var xnTempPopNode = xnTempResultDoc.selectSingleNode("/BindPopup");

	var xnHeaderInfo = XmlLib.createChild(xnTempPopNode, "HeaderInfo");
	this._makePopupHeaderRequest(xnHeaderInfo);
	
	strValue = Utils.replace(strValue, ",",""); //숫자에 통화기호 (',')가 들어갈경우 제외
	
	var nColumnLen = this.m_objPopupHeader.getColumnLength();
	for (var columnIndex = 0; columnIndex < nColumnLen; columnIndex=columnIndex+1)
	{
		var strRefVarName = this.m_objPopupHeader.getColumnRefVarName(columnIndex);
		if (strRefVarName == strVarName)
		{	
			var xnDataRowList = XmlLib.selectNodeList(this.m_xnResultDoc, "/BindPopup/DataRow");
			if (null == xnDataRowList)
			{
				return 0;
			}
		
			var nRowLen = xnDataRowList.length;
			for (var rowIndex = 0; rowIndex != nRowLen; rowIndex=rowIndex+1)
			{
				var xnDataRow = xnDataRowList[rowIndex];
				if (null != xnDataRow)
				{				
					var xnColumnList = xnDataRow.childNodes;
					if (null != xnColumnList)
					{
						var xnColumn = xnColumnList[columnIndex];
						if (null != xnColumn)
						{
							var strMemoryValue = XmlLib.getTextValue(xnColumn);
							
							if (strValue.charAt(0)=="%")
							{
								var strTemp = strValue.substring(1);
								
								if (strMemoryValue.indexOf(strTemp) >= 0)
								{
									XmlLib.importChildNode(xnTempPopNode, xnDataRow, true);
								}
							}
							else if (strMemoryValue.indexOf(strValue) == 0)
							{
								XmlLib.importChildNode(xnTempPopNode, xnDataRow, true);
							}
						}
					}
				}
			}
		}
	}
	
	// 검색 결과가 없을 때, 전체 재검색 속성이 설정 된 경우
	if (0 == xnTempResultDoc.documentElement.childNodes.length && "Y" == this.m_strReSearchAll)
	{
		return this.m_xnResultDoc;
	}

	return xnTempResultDoc;
}

/**
 * 메모리 팝업 설정된 입력란에 값이 있으면 팝업동작을 수행한다.
 */
PopupAtom.prototype._handleKeyMemoryPopup = function ()
{
	for (var i = 0; i < this.m_objPopupHeader.getColumnLength(); i++)
	{
		var strRefVar = this.m_objPopupHeader.getColumnRefVarName(i);
		var objAtom = this._getBindedAtom(strRefVar, null, null);
		
		if (null != objAtom)
		{
			var strValue = objAtom.getValue();
			if (null != strValue && 0 < strValue.length)
			{
				this.setIsOperation(false);
			
				this.executeMemoryPopup(strRefVar, strValue, objAtom, objAtom.getScrollName());
				
				this.setIsOperation(true);
			
				break;
			}
		}
	}
}

/**
 * 자체정의 데이터를 '값$값$값' 형식의 배열로 가져옵니다.
 */
PopupAtom.prototype._getPopupItemStringList = function ()
{
	var arDataInfoList = new Array();
	
	for (var i = 0, nLen = this.m_arDataInfoList.length; i != nLen; i=i+1)
	{
		var objDataInfo = this.m_arDataInfoList[i];
		if (null != objDataInfo)
		{
			var arPopupItemList = objDataInfo.getPopupItemList();
			if (null != arPopupItemList)
			{
				arDataInfoList.push(arPopupItemList.join('$'));
			}
		}
	}
	
	return arDataInfoList;
}

/**
 * 스마트페이퍼에서 팝업 데이터 추가하기  
 */
PopupAtom.prototype.addNewData = function ()
{
	this.hideEditBox();
	
	if (PopupAtom.MEMORYDATA == this.m_nPopKind)
	{
		if (null != this.m_objPopupHeader)
		{
			//묶인 아톰의 값을 가져와서 '값$값$값' 형태로 만든다.
			var strDataInfo = "";
			for (var i = 0, nLen = this.m_objPopupHeader.getColumnLength(); i < nLen; i=i+1)
			{
				if (2 == this.m_objPopupHeader.getColumnDisplayType(i))
				{
					continue;
				}
				
				var strRefVarName = this.m_objPopupHeader.getColumnRefVarName(i);
				var objBindedAtom = this._getBindedAtom(strRefVarName, this.m_strScrollName, this.m_objInputAtom);
				if (null != objBindedAtom)
				{
					var strValue = objBindedAtom.getValue();
					if (null == strValue || 0 == strValue.length)
					{
						alert("팝업 데이터에 빈 값을 추가할 수 없습니다.");
						return;
					}
					
					strDataInfo += strValue;
					if (i != nLen - 1)
					{
						strDataInfo += "$";
						
					}
				}
			}
			
			var objPopupMemoryDataInfo = new PopupMemoryDataInfo(strDataInfo, "", false, "", "", false);
			this.m_arDataInfoList.push(objPopupMemoryDataInfo);
			
			PQService.saveSPFWithChangedPopup(this.m_strVarName, this._getPopupItemStringList().join('#'));
			
			this._initMemoryData();
		}
	}
}

/**
 * 스마트페이퍼에서 팝업 데이터 제거하기  
 */
PopupAtom.prototype.removeData = function (nIndex)
{
	this.hideEditBox();
	
	if (PopupAtom.MEMORYDATA == this.m_nPopKind)
	{
		var arDataInfoList = new Array();
		
		for (var i = 0, nLen = this.m_arDataInfoList.length; i != nLen; i=i+1)
		{
			var objDataInfo = this.m_arDataInfoList[i];
			if (null != objDataInfo && nIndex != i)
			{
				arDataInfoList.push(objDataInfo);
			}
		}
		
		this.m_arDataInfoList = arDataInfoList;
		
		PQService.saveSPFWithChangedPopup(this.m_strVarName, this._getPopupItemStringList().join('#'));
		
		this._initMemoryData();
	}
}

PopupAtom.prototype.showEditBox = function (objInputAtom, strScrollName)
{
	this.m_objInputAtom = objInputAtom;
	this.m_strScrollName = strScrollName;
	
	var heEditBox = document.getElementById("POPUP_EDITBOX_" + this.m_strVarName);
	heEditBox.style.visibility = "visible";			
}

PopupAtom.prototype.hideEditBox = function ()
{
	var heEditBox = document.getElementById("POPUP_EDITBOX_" + this.m_strVarName);
	heEditBox.style.visibility = "hidden";			
}


PopupAtom.DBDATA = 0;
PopupAtom.MEMORYDATA = 1;

//PopupAtom.POPUP_TREE_BODY_CONTENT = "__TREE_BODY_CONTENT_";

PopupAtom.GAP = 10;
PopupAtom.BUTTON_GAP = 33;

/**
 * 아톰리스트
 */
PopupAtom._atoms = new Object();

PopupAtom.init = function ()
{
	for (var strVarName in PopupAtom._atoms)
	{
		if ("" == strVarName)
			continue;
			
		var objAtom = PopupAtom._atoms[strVarName];
		
		objAtom.init();
	}
}

PopupAtom.getAtom = function (strVarName)
{
	var objAtom = PopupAtom._atoms[strVarName];
	// 수행조건 팝업에 포함된 Pop아톰을 찾는다. 
	if (null == objAtom && ContainsSearchConditionAtom())
	{
		var objSearchCondition = SearchConditionAtom.getAtom(strVarName.substring(0, strVarName.indexOf("_")));
		if (null != objSearchCondition)
		{
			objAtom = objSearchCondition.getManager().getPopUpType(parseInt(strVarName.substring(strVarName.indexOf("_") + 1)), strVarName);
		}
	}
	
	return objAtom;
}

PopupAtom.XSL = null;
PopupAtom.getXSL = function ()
{
	if (null == PopupAtom.XSL)
	{
		if (IsWPQModel())
		{
			PopupAtom.XSL = XmlLib.loadXMLFromFile("./ups/sys/xsl/PopupAtomToHtml.xsl");
		}
		else
		{
			PopupAtom.XSL = PQService.getXSL("/ups/sys/xsl/PopupAtomToHtml.xsl");
		}
	}
	
	return PopupAtom.XSL;
}

/**
 * 팝업 아톰 전체에 대해서 유효성 검사 수행
 */
PopupAtom.checkPopupForeignKey = function ()
{
 	GlobalField.setServiceName("ForeignKeyCheck");
	GlobalField.setServiceEventName("Popup");
		
	var xnRequest = MakeRequest.createRequestNode();
	
	MakeRequest.makeServiceRequest(xnRequest);
	
	var xnAtomRequest = MakeRequest.getAtomRequestNode(xnRequest);
	
	var bCheck = false;
	
	for (var strVarName in PopupAtom._atoms)
	{
		if ("" == strVarName)
			continue;
			
		var objAtom = PopupAtom._atoms[strVarName];
		
		if (objAtom.isCheckPopupForeignKey())
		{
			objAtom.makePopupRequest(xnAtomRequest);
			bCheck = true;
		}
	}
	
	if (bCheck)
	{
		g_objMakeRequest.makeTouchAtomRequest(xnAtomRequest);
		g_objMakeRequest.makeScrollAtomRequest(xnAtomRequest);
		
		var xnResult = PQService.executeForeignKeyCheck(xnRequest.ownerDocument);

		var xnModel = XmlLib.selectSingleNode(xnResult, "/Result/Model")

		var nResult = XmlLib.getAttribute(xnModel, "ForeignKeyCheckResult");
		if (null != nResult && 0 == nResult)
		{
			return false;
		}
	}
	
	return true;
}

/**
 * 팝업 아톰 전체에 대해서 request 생성
 */
PopupAtom.makeRequest = function (xnAtomRequest)
{
	for (var strVarName in PopupAtom._atoms)
	{
		if ("" == strVarName)
			continue;
		
		var objAtom = PopupAtom._atoms[strVarName];
		
		objAtom.makePopupRequest(xnAtomRequest);
	}
}

PopupAtom.handleMemoryPopupResult = function ()
{
	for (var strVarName in PopupAtom._atoms)
	{
		if ("" == strVarName)
			continue;
		
		var objAtom = PopupAtom._atoms[strVarName];
		
		if (objAtom.isMemoryPopup())
		{
			objAtom._handleKeyMemoryPopup();
		}
	}
}

/**
 * 스마트페이퍼에서 팝업 데이터를 수정할 수 있도록 팝업묶기 표시  
 */
PopupAtom.toggleVisibilityOfEditBox = function ()
{
	for (var strVarName in PopupAtom._atoms)
	{
		if ("" == strVarName)
			continue;
		
		var heEditBox = document.getElementById("POPUP_EDITBOX_" + strVarName);
		if ("visible" == heEditBox.style.visibility)
		{
			heEditBox.style.visibility = "hidden";			
		}
		else
		{
			heEditBox.style.visibility = "visible";			
		}
	}
}

/**
 * 스마트페이퍼에서 팝업 데이터 추가하기  
 */
PopupAtom.addNewData = function (strVarName)
{
	if ("" == strVarName)
	{
		return;
	}
	
	var objAtom = PopupAtom._atoms[strVarName];
	if (null != objAtom)
	{
		objAtom.addNewData();
	}
}

/**
 * 스마트페이퍼에서 팝업 데이터 추가 버튼 보이기
 * @param strVarName 팝업 아톰 변수명
 * @param objInputAtom 팝업이 발생한 입력란 아톰
 * @param strScrollName 입력란 아톰이 묶인 스크롤 변수명  
 */
PopupAtom.showEditBox = function (strVarName, objInputAtom, strScrollName)
{
	if (IsWPQModel())
	{
		if ("" == strVarName)
		{
			return;
		}
		
		var objAtom = PopupAtom._atoms[strVarName];
		if (null != objAtom)
		{
			objAtom.showEditBox(objInputAtom, strScrollName);
		}	
	}
}

/**
 * 스마트페이퍼에서 팝업 데이터 추가 버튼 감추기  
 */
PopupAtom.hideEditBox = function (strVarName)
{
	if (IsWPQModel())
	{
		if ("" == strVarName)
		{
			return;
		}
		
		var objAtom = PopupAtom._atoms[strVarName];
		if (null != objAtom)
		{
			objAtom.hideEditBox();
		}
	}
}

/**
 * DB 데이터 팝업의 팝업 속성들을 저장하는 클래스
 *
 * 이 정보를 이용해서 PopupHeader를 만듭니다.
 */
function PopupDBDataInfo (strRefVarName, nDisplayType, nFieldIndex, strFieldName,
							strFieldType, strStepInfo, strClassChar)
{
	this.m_strRefVarName = strRefVarName;
	this.m_nDisplayType = nDisplayType;
	this.m_nFieldIndex = nFieldIndex;
	this.m_strFieldName = strFieldName;
	this.m_strFieldType = strFieldType;
	this.m_strStepInfo = strStepInfo;
	this.m_strClassChar = strClassChar;
}	
	
PopupDBDataInfo.prototype.getRefVarName = function ()
{
	return this.m_strRefVarName;
}

PopupDBDataInfo.prototype.getDisplayType = function ()
{
	return this.m_nDisplayType;
}

PopupDBDataInfo.prototype.getFieldIndex = function ()
{
	return this.m_nFieldIndex;
}

PopupDBDataInfo.prototype.getFieldName = function ()
{
	return this.m_strFieldName;
}

PopupDBDataInfo.prototype.getFieldType = function ()
{
	return this.m_strFieldType;
}

PopupDBDataInfo.prototype.getStepInfo = function ()
{
	return this.m_strStepInfo;
}

PopupDBDataInfo.prototype.getClassChar = function ()
{
	return this.m_strClassChar;
}

PopupDBDataInfo.prototype.setRefVarName = function (strRefVarName)
{
	this.m_strRefVarName = strRefVarName;
}


/**
 * 자체정의 데이터 팝업의 팝업 속성을 저장하는 클래스
 *
 * 이 정보를 이용해서 PopupHeader를 만듭니다.
 */
function PopupMemoryDataInfo (strPopupItem, strRefVarName,
						bConnectionModel, strConnectionModelName, strConnectionRefKey, bButtonExec)
{
	this.m_strPopupItem = Utils.replace(strPopupItem, ",","$"); 
	this.m_arPopupItemList = (null != this.m_strPopupItem) ? this.m_strPopupItem.split("$") : null;
	this.m_arRefVarNameList = (null != strRefVarName) ? strRefVarName.split("$") : null;
	
	this.m_bConnectionModel = bConnectionModel;
	this.m_strConnectionModelName = strConnectionModelName;
	this.m_arConnectionRefKey = strConnectionRefKey;
	this.m_bButtonExec = bButtonExec;
}

PopupMemoryDataInfo.prototype.getPopupItemList = function ()
{
	return this.m_arPopupItemList;
}

PopupMemoryDataInfo.prototype.getRefVarNameList = function ()
{
	return this.m_arRefVarNameList;
}

PopupMemoryDataInfo.prototype.isConnectionModel = function ()
{
	return this.m_bConnectionModel;
}

PopupMemoryDataInfo.prototype.getConnectionModelName = function ()
{
	return this.m_strConnectionModelName;
}

PopupMemoryDataInfo.prototype.getConnectionRefKey = function ()
{
	return this.m_arConnectionRefKey;
}

PopupMemoryDataInfo.prototype.isButtonExec = function ()
{
	return this.m_bButtonExec;
}


/**
 * 팝업 컬럼의 정보를 저장하는 클래스
 *
 * PopupHeader가 각 컬럼에 대한 정보를 관리하는데 사용합니다.
 */
function PopupColumn (strRefVarName, nDisplayType, strFieldName, strFieldType, strDisplayInfo, strStepInfo)
{
	this.m_strRefVarName = strRefVarName;
	this.m_nDisplayType = nDisplayType;
	
	this.m_strFieldName = strFieldName;
	this.m_strFieldType = strFieldType;
	this.m_strStepInfo = strStepInfo;
	this.m_strDisplayInfo = strDisplayInfo;
}

PopupColumn.prototype.getRefVarName = function ()
{
	return this.m_strRefVarName;
}

PopupColumn.prototype.getDisplayType = function ()
{
	return this.m_nDisplayType;
}

PopupColumn.prototype.getFieldName = function ()
{
	return this.m_strFieldName;
}

PopupColumn.prototype.getFieldType = function ()
{
	return this.m_strFieldType;
}

PopupColumn.prototype.getDisplayInfo = function ()
{
	return this.m_strDisplayInfo;
}

PopupColumn.prototype.getStepInfo = function ()
{
	return this.m_strStepInfo;
}

PopupColumn.prototype.setRefVarName = function (strRefVarName)
{
	this.m_strRefVarName = strRefVarName;
}


function PopupConnectionModelInfo (bConnectionMadel, strConnectionRefKey, strConnectionModelName, bButtonExec)
{
	this.m_bConnectionModel = bConnectionMadel;
	this.m_strConnectionRefKey = strConnectionRefKey;
	this.m_strConnectionModelName = strConnectionModelName;
	this.m_bButtonExec = bButtonExec;
}

PopupConnectionModelInfo.prototype.isConnectionModel = function ()
{
	return this.m_bConnectionModel;
}

PopupConnectionModelInfo.prototype.getConnectionModelName = function ()
{
	return this.m_strConnectionModelName;
}

PopupConnectionModelInfo.prototype.getConnectionRefKey = function ()
{
	return this.m_strConnectionRefKey;
}

PopupConnectionModelInfo.prototype.isButtonExec = function ()
{
	return this.m_bButtonExec;
}


/**
 * 팝업 헤더 정보를 저장는 클래스
 *
 * DataInfo를 이용하여 Column을 만들어서 리스트로 관리합니다.
 */
function PopupHeader ()
{
	this.m_arColumnList = new Array();
	this.m_arConnectionModelInfo = new Array();
	
	this.m_nTreePopup = false;
}
	
PopupHeader.prototype.getConnctionModelInfo = function (nIndex)
{
	return this.m_arConnectionModelInfo[nIndex];
}

PopupHeader.prototype.getColumnLength = function ()
{
	return this.m_arColumnList.length;
}

PopupHeader.prototype.getColumnDisplayType = function (nIndex)
{
	return this.m_arColumnList[nIndex].getDisplayType();
}

PopupHeader.prototype.setColumnRefVarName = function (nIndex, strRefName)
{
	this.m_arColumnList[nIndex].setRefVarName(strRefName);
}

PopupHeader.prototype.getColumnRefVarName = function (nIndex)
{
	return this.m_arColumnList[nIndex].getRefVarName();
}

PopupHeader.prototype.getFieldIndex = function (strVarName)
{
	var nLen = this.m_arColumnList.length;
	for (var i = 0; i < nLen; i=i+1)
	{
		var objColumn = this.m_arColumnList[i];
		if (strVarName == objColumn.getRefVarName())
		{
			return i;
		}
	}
	
	return "";
}

PopupHeader.prototype.getOrderField = function (strVarName)
{
	var nLen = this.m_arColumnList.length;
	for (var i = 0; i < nLen; i=i+1)
	{
		var objColumn = this.m_arColumnList[i];
		if (strVarName == objColumn.getRefVarName())
		{
			return objColumn.getFieldName();
		}
	}
	
	return "";
}

/**
 * 수행조건 팝업의 경우, Binded된 아톰의 VarName으로 OrderField를 찾을수 없다. 
 * 팝업이 실행된 수행조건 Row에 해당 unit의 Edit Index로 컬럼을 찾을수 있다
 * @param nEditIndex 팝업이 실행된 Edit의 Index
 * @return OrderFieldName
 */
PopupHeader.prototype.getOrderFieldOnEditIndex = function (nEditIndex)
{
	for (var i = 0; i < this.m_arColumnList.length; i=i+1)
	{
		if (i == nEditIndex)
		{
			return this.m_arColumnList[i].getFieldName();
		}
	}
	
	return "";
}	

PopupHeader.prototype.getColumnDisplayInfo = function (nIndex)
{
	return this.m_arColumnList[nIndex].getDisplayInfo();
}

PopupHeader.prototype.getColumnFieldName = function (nIndex)
{
	return this.m_arColumnList[nIndex].getFieldName();
}

PopupHeader.prototype.getColumnFieldType = function (nIndex)
{
	return this.m_arColumnList[nIndex].getFieldType();
}

PopupHeader.prototype.isTreePopup = function ()
{
	return this.m_nTreePopup;
}

PopupHeader.prototype.init = function (nPopKind, arDataInfo)
{
	if (null == arDataInfo)
	{
		return;
	}
	
	if (PopupAtom.DBDATA == nPopKind)
	{
		this._initDBDataHeader(arDataInfo);
	}
	else if (PopupAtom.MEMORYDATA == nPopKind)
	{
		this._initMemoryDataHeader(arDataInfo);
		this._initConnectionModelInfo(arDataInfo);
	}
}


/**
 * DB 데이터 팝업의 헤더를 구성합니다.
 *
 * @param arDataInfo DB 데이터 팝업의 팝업 정보를 저장하고 있는 DataInfo 리스트
 */
PopupHeader.prototype._initDBDataHeader = function (arDataInfo)
{
	var nLen = arDataInfo.length;
	for (var i = 0; i < nLen; i=i+1)
	{
		var objDataInfo = arDataInfo[i];
		
		var strRefVarName = objDataInfo.getRefVarName();
		var nDisplayType = objDataInfo.getDisplayType();
		var strFieldName = objDataInfo.getFieldName();
		var strFieldType = objDataInfo.getFieldType();
		var strStepInfo = objDataInfo.getStepInfo();
		var strClassChar = objDataInfo.getClassChar();
		
		var strDisplayInfo = "";
		
		if (null != strStepInfo && 0 < strStepInfo.length
			&& null != strClassChar && 0 < strClassChar.length)
		{
			this.m_nTreePopup = true;
			strDisplayInfo = "$LEVEL:" + strStepInfo + "$" + strClassChar;
		}
		
		var objPopupColumn = new PopupColumn(strRefVarName, nDisplayType, strFieldName, strFieldType, strDisplayInfo);
		
		this._addColumn(objPopupColumn);
	}
}

/**
 * 자체정의 데이터 팝업의 헤더를 구성합니다.
 *
 * @param arDataInfo 자체정의 데이터 팝업의 팝업 정보를 저장하고 있는 DataInfo 리스트
 */
PopupHeader.prototype._initMemoryDataHeader = function (arDataInfo)
{
	var objDataInfo = arDataInfo[0];
	if (null == objDataInfo)
	{
		return;
	}
	
	var arRefVarNameList = objDataInfo.getRefVarNameList();
	if (null == arRefVarNameList)
	{
		return;
	}
	
	var nLen = arRefVarNameList.length;
	for (var i = 0; i < nLen; i=i+1)
	{
		var strRefVarName = arRefVarNameList[i];

		var objPopupColumn = new PopupColumn(strRefVarName, 0, "", "");
		
		this._addColumn(objPopupColumn);
	}
}

PopupHeader.prototype._addColumn = function (objPopupColumn)
{
	this.m_arColumnList.push(objPopupColumn);
}

PopupHeader.prototype._initConnectionModelInfo = function (arDataInfo)
{
	var nLen = arDataInfo.length;
	for (var i = 0; i < nLen; i=i+1)
	{
		var objDataInfo = arDataInfo[i];
		
		var bConnectionModel = objDataInfo.isConnectionModel();
		var strConnectionRefKey = objDataInfo.getConnectionRefKey();
		var strConnectionModelName = objDataInfo.getConnectionModelName();
		var bButtonExec = objDataInfo.isButtonExec();
		
		var objConInfo = new PopupConnectionModelInfo(bConnectionModel, strConnectionRefKey,strConnectionModelName, bButtonExec);
		
		this.m_arConnectionModelInfo.push(objConInfo);
	}
}


/** 
 * 팝업 이벤트 처리
 */

function PopupOnDblClick (strVarName, strScrollName, objInputAtom, objEvent)
{
	if (window.event)
	{
		objEvent = window.event;
	}
	
	var objAtom = PopupAtom.getAtom(strVarName);
	if (null == objAtom)
	{
		return;
	}
	
	return objAtom.executeInputDataPopup(strScrollName, objInputAtom, objEvent);
}