TreeAtom.TREE_BODY = "__TREE_BODY_";
TreeAtom.TREE_BODY_CONTENT = "__TREE_BODY_CONTENT_";
TreeAtom.TREE_BODY_UPBUTTON = "__TREE_BODY_UPBUTTON_"; 
TreeAtom.TREE_BODY_DOWNBUTTON = "__TREE_BODY_DOWNBUTTON_"; 
TreeAtom.TREE_BODY_LOCATIONBAR = "__TREE_BODY_LOCATIONBAR_"; 

TreeAtom.INDEP_TREE = 0; // 단일체계
TreeAtom.UPDOWN_TREE = 1; // 상하위체계
TreeAtom.SCRIPT_TREE = 2; // 사용자정의

/**
 * 트리  Javascript 클래스 목록
 * 	- TreeAtom
 *	- TreeColumn
 *	- TreeHeader
 *	- TreeNode
 */

function TreeAtom (strVarName, // 1
				nScriptIndex, // 2
				nSQLIndex, // 3
				bDireceExec, // 4
				bRootKey, // 5
				strRootKey, // 6
				bShowTreeExtend, // 7
				bShowTreeRoot, // 8
				bShowTreeLine, // 9
				bFullRowSelect, // 10
				bGridLines, // 11
				nItemHeight, // 12
				bVanish, // 13
				bDisabled, // 14
				objTreeHeader, // 15
				bInsertImage, // 16
				bUseSelectedImage, //17
				strImageFilePath, //18
				nSplitWidth, //19
				nImageKey,  //20
				bBodyUnderline //21
				) 
{
	this.m_strVarName = strVarName;				// 트리 변수 이름
	this.m_nScriptIndex = nScriptIndex;
	this.m_nSQLIndex = nSQLIndex;
	this.m_bDirectExec = bDireceExec;			// 즉시실행 여부
	this.m_bRootKey = bRootKey;					// 최상위키 설정여부
	this.m_strRootKey = strRootKey;				// 최상위키
	this.m_bShowTreeExtend = bShowTreeExtend;	// 트리 확장표시 여부
	this.m_bShowTreeRoot = bShowTreeRoot;		// 트리 최상위 표시 여부
	
	this.m_bShowTreeLine = bShowTreeLine;		// 트리 구분선 표시 여부
	if (is_android || is_iphone)
	{
		this.m_bShowTreeLine = false;
	}
	
	this.m_bFullRowSelect = bFullRowSelect;
	this.m_bGridLines = bGridLines;
	this.m_nItemHeight = nItemHeight;
	this.m_bVanish = bVanish;
	this.m_bDisabled = bDisabled;
	this.m_objTreeHeader = objTreeHeader;
	
	//이미지 삽입 관련
	
	this.m_bInsertImage = bInsertImage;
	this.m_bUseSelectedImage = bUseSelectedImage;
	this.m_strImageFilePath = strImageFilePath;
	this.m_nSplitWidth = nSplitWidth;
	this.m_nImageKey = nImageKey;

	this.m_heTreeBody = document.getElementById(TreeAtom.TREE_BODY + strVarName);
	this.m_heTreeBodyTable = document.getElementById(TreeAtom.TREE_BODY_CONTENT + strVarName);
	this.m_heTreeDiv = document.getElementById(strVarName);
	this.m_bTreePopup = false;
	this.m_strTreePopupOrderField = "";
	this.m_strTreePopupOrderKey = "";
	this.m_strIndexField = "";
	this.m_arTreeNodeList = new Array();
	this.m_objEventNode = null;	// 노드 클릭 이벤트가 발생해서 동작이 완료 될 때까지 유효하다.
	this.m_objSelectNode = null;	// 선택된 노드 저장. 새로운 검색을 요청 할 때까지 유효하다.
	this.m_bFirstRequest = true;	// DataSet을 최초의 요청시에 초기화 시키기 위한 flag
	
	// 팝업트리일 경우에만 아이콘 Path를 제대로 찾기 위해 사용합니다.
	this.m_strWebRootPath = "./";
	this.m_nTreePopupHandle = 100;	// 팝업 트리에서 사용되는 검색 결과 node 시작 핸들값
	
	this.m_bMouseHeaderDown = false;
	
	this.m_nSelectedColumnIndex = 0; // 선택된 컬럼의 인덱스
	this.m_bResized = false; //리사이즈가 일어났었다? 아니다?

	this.m_bChangeWidthStatus = false;
	this.m_bBodyUnderline = bBodyUnderline; //body 글꼴의 밑줄 여부 

	this.m_nButtonWidth = 35;
}

/**
 * @return "TreeAtom"
 */
TreeAtom.prototype.getAtomType = function ()
{
	return "TreeAtom";
}

/**
 * @return 아톰의 HTML 엘리먼트
 */
TreeAtom.prototype.getHTML = function ()
{
	return this.m_heTreeDiv;
}

TreeAtom.prototype.getVarName = function ()
{
	return this.m_strVarName;
}

TreeAtom.prototype.getLevelChar = function ()
{
	return this.m_objTreeHeader.getLevelChar();
}

TreeAtom.prototype.getColumnValue = function (strItemName)
{
	var nIndex = this.m_objTreeHeader.getColumnIndex(strItemName)
	
	if (null == this.m_objSelectNode)
	{
		return null;
	}
	
	return this.m_objSelectNode.getColumnValue(nIndex);
}

TreeAtom.prototype.isDirectExec = function ()
{
	return this.m_bDirectExec;
}

/**
 * 아톰리스트에 추가
 */
TreeAtom.prototype.putAtom = function ()
{
	if (this.m_bTreePopup)
	{
		g_objParent.TreeAtom._atoms[this.m_strVarName] = this;
	}
	else
	{
		TreeAtom._atoms[this.m_strVarName] = this;
	}
}

TreeAtom.prototype.setValue = function (xnAtom)
{
	var strIsDoSearch = xnAtom.getAttribute("IsDoSearch");
	if (null == strIsDoSearch || "N" == strIsDoSearch)
	{
		this._setScriptResult(xnAtom)
		return;
	}
	
	this._clearAtom();
	
	// 트리 팝업이고, 레벨정보가 있는 아톰일 경우
	if (this.m_bTreePopup && this._isTreePopupDefaultKeyField())
	{
		var xnDataRowList = XmlLib.selectNodeList(xnAtom, "./DataRow");
		
		this._createPopupNodes(xnDataRowList);
		
		var strTreePopupHandle = xnAtom.getAttribute("TreePopupHandle");
		if (null != strTreePopupHandle)
		{
			this.m_nTreePopupHandle = Utils.parseInt(strTreePopupHandle);
		}
	}
	else
	{
		this._setScriptResult(xnAtom);	
	}
	
	// 선택행 스타일 표시
	var nSelectedHandle = xnAtom.getAttribute("SelectedHandle");
	this._setSelectNodeStyle(nSelectedHandle);

	this._hideUnVisibleColumnContent();
	//location bar생성
	this._makeLocationBar();
	
	// 트리팝업이고, 기본키가 설정이 안된 트리 항목에 연결된 입력란에서 이벤트가 발생할 경우
	// 단순 팝업처럼 보여주기 위해 상태를 alone으로 만든다.
	if (this.m_bTreePopup && !this._isTreePopupDefaultKeyField())
	{
		this.setAloneAllNode(); //모든노드를 alone 상태로 설정
	}
	else
	{
		this._closeAllNode(); // 모든노드를 닫는다.
	}

	if (is_iphone || is_android)
	{	
		this.m_objHScroll = new iScroll(this.m_strVarName+"_WRAPPER", { vScroll:false, hideScrollbar:false }, this);
	}
}

/**
 *	모든 노드를 닫는다.
 */
TreeAtom.prototype._closeAllNode = function ()
{
	for (var i = 0; i < this.m_arTreeNodeList.length; i += 1)
	{
		var objNode = this.m_arTreeNodeList[i];
		
		objNode.closeNode();
	}
}

/**
 *	모든 노드를 alone 상태로 설정한다.
 */
TreeAtom.prototype.setAloneAllNode = function ()
{
	for (var i = 0; i < this.m_arTreeNodeList.length; i += 1)
	{
		var objNode = this.m_arTreeNodeList[i];
		
		objNode.m_objPrevNode = null;
		objNode.m_objNextNode = null;
		objNode.m_objParentNode = null;
		objNode.m_arChildNodeList = null;
		this.m_nLevel = 0;
		
		var heNobr = objNode._getIconHTML().parentNode;
		while (2 < heNobr.childNodes.length)
		{
			var heImg = heNobr.childNodes[0];
			heNobr.removeChild(heImg);
		}
		
		if (0 == i) // 첫노드
		{
			objNode.setState(TreeNode.AT);
		}
		else if (this.m_arTreeNodeList.length - 1 == i) // 마지막 노드
		{
			objNode.setState(TreeNode.AB);
		}
		else
		{
			objNode.setState(TreeNode.AM);
		}
	}
}

TreeAtom.prototype.setTreePopup = function (bTreePopup)
{
	this.m_bTreePopup = bTreePopup;
}

TreeAtom.prototype.setTreePopupOrderField = function (strOrderField)
{
	this.m_strTreePopupOrderField = strOrderField;
}

TreeAtom.prototype.setTreePopupOrderKey = function (strOrderKey)
{
	this.m_strTreePopupOrderKey = strOrderKey;
}

TreeAtom.prototype.setIndexField = function (strIndexField)
{
	this.m_strIndexField = strIndexField;
}
	
/**
 * 팝업트리일 경우에만 아이콘 Path를 제대로 찾기 위해 사용합니다.
 */ 
TreeAtom.prototype.getWebRootPath = function ()
{
	return this.m_strWebRootPath;
}

TreeAtom.prototype.setWebRootPath = function (strWebRootPath)
{
	this.m_strWebRootPath = strWebRootPath;
}

/**
 * 선택표시 (f9 기능)
 */	
TreeAtom.prototype.vanish = function ()
{
	if (this.m_bVanish)
	{
		// 현재 감춤 상태이면 표시한다.
		if ("hidden" == this.m_heTreeDiv.style.visibility)
		{
			this.m_heTreeDiv.style.visibility = "visible";
		}
		else
		{
			// 표시된 상태이면 감춘다.
			this.m_heTreeDiv.style.visibility = "hidden";
		}
	}
}
	
TreeAtom.prototype.isTreePopup = function ()
{
	return this.m_bTreePopup;
}

TreeAtom.prototype.onClick = function (nHandle, bIconClick)
{
	if (this.m_bDisabled)
	{
		return;
	}

	this._setEventNode(nHandle);
	this._setSelectNodeStyle(nHandle);
	
	if (bIconClick)
	{
		this._executeTreeAction();
		this._changeVisibilityOfMoveButton();
		this._makeLocationBar();
	}
	else
	{
		if (!this.m_bTreePopup)
		{
			// 입력란 연결
			this._executeconnectionInput();
			
			// 연결검색
			PQConnectionSearch.execute(this.m_strVarName);
		}
	}
	
	this._clearEventNode();
}

TreeAtom.prototype.onDblClick = function (nHandle)
{
	if (this.m_bDisabled)
	{
		return;
	}
	
	if (this.m_bTreePopup)
	{
		this.returnPopupResult();
	}
	else
	{
		this._executeTreeAction();
	}
	
	this._clearEventNode();
}
	
/**
 * _선택변경 -> _누름 이벤트 처리
 */
TreeAtom.prototype.onMouseDown = function (nHandle)
{
	if (this.m_bDisabled || this.m_bTreePopup)
	{
		return ;
	}
	
	this._setEventNode(nHandle);
	this._setSelectNodeStyle(nHandle);
	
	if (-1 == ScriptAtomEvent.onChangeSelect(this.m_nScriptIndex))
	{
		if (null != objEvent)
		{
			objEvent.returnValue = false;
		}
		return;
	}
	else
	{
		ScriptAtomEvent.onChangeSelectAfter(this.m_nScriptIndex);
	}
	
	if (-1 == ScriptAtomEvent.onEndChangeSelect(this.m_nScriptIndex))
	{
		if (null != objEvent)
		{
			objEvent.returnValue = false;
		}
		return;
	}
	
	if (-1 == ScriptAtomEvent.onClick(this.m_nScriptIndex, 0, nHandle))
	{
		return;
	}
	else
	{
		ScriptAtomEvent.onClickAfter(this.m_nScriptIndex, 0, nHandle);
	}
}
	
TreeAtom.prototype.returnPopupResult = function ()
{
	if (null != this.m_objSelectNode)
	{
		var xnDataRow = this.m_objSelectNode.getDataRow();
	
		// TreePopupAtomWindow.html
		ReturnPopupResult(xnDataRow);
	}
	
	window.self.close();
}

TreeAtom.prototype.onScroll = function (heEventItem)
{
	if (null != this.m_objTreeHeader && null != heEventItem)
	{
		var nPos = heEventItem.scrollLeft;
		
		this.m_objTreeHeader.setScrollPos(nPos);
	}
}


////////////////////////////////////////
// public method

TreeAtom.prototype.init = function ()
{
	this.m_objTreeHeader.init(this.m_strVarName);
	
	this._hideUnVisibleColumn();

	this._makeMoveButton();
}

/**
 * 스마트폰용 상하 이동 버튼
 */
TreeAtom.prototype._makeMoveButton = function ()
{
	var browseW = this.m_heTreeDiv.style.pixelWidth;
	var browseH = this.m_heTreeDiv.style.pixelHeight;
	var headerH = this.m_objTreeHeader.m_heTreeHeaderTable.clientHeight;

	var heUpButtonDiv = document.createElement("div");
	heUpButtonDiv.id = TreeAtom.TREE_BODY_UPBUTTON + this.m_strVarName;
	this.m_heTreeDiv.appendChild(heUpButtonDiv);
	heUpButtonDiv.style.position = "absolute";
	heUpButtonDiv.style.left = (browseW - this.m_nButtonWidth) + "px";
	heUpButtonDiv.style.top = headerH + "px";
	heUpButtonDiv.style.width = this.m_nButtonWidth + "px";
	heUpButtonDiv.style.height = this.m_nButtonWidth + "px";
	heUpButtonDiv.style.backgroundImage = "url(/ups/sys/image/pq/atom/browse/sc_up_on.png)";
	heUpButtonDiv["onmousedown"] = new Function("event", "TreeAtom.onMouseDownUpButton4Mobile('" + this.m_strVarName + "', event)");
	

	var heDownButtonDiv = document.createElement("div");
	heDownButtonDiv.id = TreeAtom.TREE_BODY_DOWNBUTTON + this.m_strVarName;
	this.m_heTreeDiv.appendChild(heDownButtonDiv);
	heDownButtonDiv.style.position = "absolute";
	heDownButtonDiv.style.left = (browseW - this.m_nButtonWidth) + "px";
	heDownButtonDiv.style.top = (browseH - this.m_nButtonWidth) + "px";
	heDownButtonDiv.style.width = this.m_nButtonWidth + "px";
	heDownButtonDiv.style.height = this.m_nButtonWidth + "px";
	heDownButtonDiv.style.backgroundImage = "url(/ups/sys/image/pq/atom/browse/sc_dn_on.png)";
	heDownButtonDiv["onmousedown"] = new Function("event", "TreeAtom.onMouseDownDownButton4Mobile('" + this.m_strVarName + "', event)");

	this._changeVisibilityOfMoveButton();
}
/**
 *위치표시바
 */
TreeAtom.prototype._makeLocationBar = function()
{
	if (null != document.getElementById(TreeAtom.TREE_BODY_LOCATIONBAR + this.m_strVarName))
	{
		this.m_heTreeDiv.removeChild(document.getElementById(TreeAtom.TREE_BODY_LOCATIONBAR + this.m_strVarName));
	}

	var browseW = this.m_heTreeDiv.style.pixelWidth;
	var browseH = this.m_heTreeDiv.style.pixelHeight;
	
	var headerH = this.m_objTreeHeader.m_heTreeHeaderTable.clientHeight;
	var nScrollHeight = this.m_heTreeBody.scrollHeight;
	var nTableTop = this.m_heTreeBodyTable.style.pixelTop;
	
	var nBarMovingH =(browseH - headerH) - (this.m_nButtonWidth * 2);

	var nBarH = ( (browseH - headerH) / (nScrollHeight - nTableTop)) * (nBarMovingH);
	var nBarY = ((-1 * nTableTop) / (nScrollHeight - nTableTop)) * (nBarMovingH);

	var nButtonWidth = 6;
	//스크롤보다 클때 bar 생성
	if (nScrollHeight - nTableTop > browseH)
	{
		var heLocationBar = document.createElement("div");
		heLocationBar.id = TreeAtom.TREE_BODY_LOCATIONBAR + this.m_strVarName;
		this.m_heTreeDiv.appendChild(heLocationBar);
		heLocationBar.style.position = "absolute";
		heLocationBar.style.left = (browseW - (this.m_nButtonWidth/2) - (nButtonWidth/2)) + "px";
		heLocationBar.style.top = headerH + this.m_nButtonWidth + nBarY + "px";
		heLocationBar.style.width = nButtonWidth + "px";
		heLocationBar.style.height = nBarH + "px";
		heLocationBar.style.backgroundColor = "#828282";
		heLocationBar.style.webkitBorderRadius = "3px 3px";

	}
}
/**
 * 스마트폰용 상하 이동 버튼의 보이기 여부 설정
 */
TreeAtom.prototype._changeVisibilityOfMoveButton = function ()
{
	var upButton = document.getElementById(TreeAtom.TREE_BODY_UPBUTTON + this.m_strVarName);
	var downButton = document.getElementById(TreeAtom.TREE_BODY_DOWNBUTTON + this.m_strVarName);
	
	//body table의 높이.
	var nRowSumH = 0;
	var nRowH = 0;
	var nBodyRowCount = this.m_heTreeBodyTable.rows.length;
	for (var i = 0; i<nBodyRowCount; i++)
	{
		nRowSumH += Utils.parseInt(this.m_heTreeBodyTable.rows[i].style.height);
		nRowH = Utils.parseInt(this.m_heTreeBodyTable.rows[i].style.height);
	}

	var isVisible = this.m_heTreeBody.scrollHeight > this.m_heTreeBody.style.pixelHeight;
	var nTableTop = Utils.parseInt(this.m_heTreeBodyTable.style.top);
	if (isVisible || nTableTop < 0)
	{
		upButton.style.backgroundImage = "url(/ups/sys/image/pq/atom/browse/sc_up_on.png)";
		downButton.style.backgroundImage = "url(/ups/sys/image/pq/atom/browse/sc_dn_on.png)";	
	}
	else
	{
		upButton.style.backgroundImage = "url(/ups/sys/image/pq/atom/browse/sc_up.png)";
		downButton.style.backgroundImage = "url(/ups/sys/image/pq/atom/browse/sc_dn.png)";	
	}
}

TreeAtom.prototype._changeTreeWidth  = function ()
{
	var heBodyRow = this.m_heTreeBodyTable.rows;
	var nBodyRowCount = heBodyRow.length;
	var nBodyColumn = this.m_heTreeBodyTable.rows[0].cells.length;
	
	var arMaxLength = new Array(nBodyColumn);
	
	//tree body의 컬럼 넓이중 가장 큰 넓이값만 추출한다.
	for (var i = 0; i < nBodyColumn ; i++ )
	{
		arMaxLength[i]= 0;
		for (var j = 0; j < nBodyRowCount ; j++)
		{
			var heBodyCol = heBodyRow[j].cells[i];
			var nColumnPadding = Utils.strPixelToint(heBodyCol.style.paddingRight) + Utils.strPixelToint(heBodyCol.style.paddingLeft);
			
			var nColumnWidth = heBodyCol.childNodes[0].offsetWidth;

			if (this.m_bChangeWidthStatus && i == 0)
			{
				nColumnWidth =  heBodyCol.offsetWidth;
			}
			
			if (i == 0)
			{
				nColumnWidth = nColumnWidth-(18*2);
			}
			else
			{
				nColumnWidth += nColumnPadding;
			}

			if (arMaxLength[i] < nColumnWidth)
			{
				arMaxLength[i] = nColumnWidth
			}
		}
	}
	
	//Tree Header의 넓이 값을 추출한다.

	var heHeaderCol = this.m_objTreeHeader.m_heTreeHeaderTable.rows[0];
	var nHeaderColumnCount = heHeaderCol.cells.length
	var nHeaderMaxlength = 0;
	var nContentWidth = 0;
	for (var i = 0; i < nHeaderColumnCount; i++)
	{
		nHeaderMaxlength = heHeaderCol.cells[i].offsetWidth;

		if (arMaxLength[i] < nHeaderMaxlength)
		{
			arMaxLength[i] = nHeaderMaxlength
		}
		
		this._changeHeaderWidth(i, arMaxLength[i]);
		
		this._changeBodyWidth(i, arMaxLength[i]);
		
		this.m_objTreeHeader.m_arColumnList[i].m_nWidth = arMaxLength[i];

		if (this.m_objTreeHeader.m_arColumnList[i].m_bVisible)
		{
			nContentWidth = nContentWidth + arMaxLength[i];
		}

	}
	
	if (is_ie)
	{
		nContentWidth += nHeaderColumnCount * 2; //padding값
	}

	var heContentDiv = document.getElementById(this.m_strVarName + "_CONTENT");
	
	heContentDiv.style.width = nContentWidth + "px";
	this.m_heTreeBody.style.width = nContentWidth + "px";
	
	this.m_bChangeWidthStatus = true;
}

TreeAtom.prototype._changeTreeHeight  = function ()
{
	var heHeaderContent = document.getElementById(TreeNode.TREE_HEADER_CONTENT_ITEM + this.getVarName());
	var heBodyContent = document.getElementById("__TREE_BODY_" + this.getVarName());
	
	if (null != heBodyContent){
		
		var nTreeHeaderContentHeight = heHeaderContent.scrollHeight;

		if (20 != nTreeHeaderContentHeight)
		{
			var nBodyRowCount = this.m_heTreeBodyTable.rows.length;
			
			for (var i = 0; i<nBodyRowCount; i++)
			{
				this.m_heTreeBody.style.top =  nTreeHeaderContentHeight+"px";
				this.m_heTreeBodyTable.rows[i].style.height = nTreeHeaderContentHeight+"px";
			}
		}
	}
}

/**
 * "표시안함" 속성을 가진  컬럼과, 상위키인 칼럼 을 숨긴다.
 * colgroup 태그의 width를 변경한다.
 */
TreeAtom.prototype._hideUnVisibleColumn = function ()
{
	// 팝업으로 생성된 트리의 경우 헤더 부분의 테이블이  생성 되지 않는다.
	if (null == this.m_objTreeHeader.getHeaderTable())
	{
		return ;
	}
	
	var nColSize = this.m_objTreeHeader.getColumnLength();
	for (var i = 0; i < nColSize; i+=1)
	{
		var nWidth = this.m_objTreeHeader.getColumnWidth(i);
	
		if(!this.m_objTreeHeader.isColumnVisible(i) || 			// 표시 안함 일 경우 숨김
				this.m_objTreeHeader.isParentKeyColumn(i) || 	// 상위키 일 경우 숨김 
				0 >= nWidth)								// 컬럼 길이가 음수 일 경우  숨김 
		{
			this.m_objTreeHeader.getHeaderTable().rows[0].cells[i].style.display = "none";
		}
	}
}
/**
 * "표시안함" 속성을 가진  컬럼과, 상위키인 칼럼 을 숨긴다.
 * colgroup 태그의 width를 변경한다.
 */
TreeAtom.prototype._hideUnVisibleColumnContent = function ()
{
	// 팝업으로 생성된 트리의 경우 헤더 부분의 테이블이  생성 되지 않는다.
	if (null == this.m_objTreeHeader.getHeaderTable())
	{
		return ;
	}
	
	var nColSize = this.m_objTreeHeader.getColumnLength();
	for (var i = 0; i < nColSize; i+=1)
	{
		var nWidth = this.m_objTreeHeader.getColumnWidth(i);
	
		if(!this.m_objTreeHeader.isColumnVisible(i) || 			// 표시 안함 일 경우 숨김
				this.m_objTreeHeader.isParentKeyColumn(i) || 	// 상위키 일 경우 숨김 
				0 >= nWidth)								// 컬럼 길이가 음수 일 경우  숨김 
		{
			for (var j=0, len= this.m_heTreeBodyTable.rows.length ;j < len ;j++ )
			{
				this.m_heTreeBodyTable.rows[j].cells[i].style.display = "none";
			}
		}
	}
}

/**
 * 트리 노드 테이블에서 해당 칼럼이 현재 보여지면 true 리턴, 안 보이면 false
 */
TreeAtom.prototype.isTreeBodyColumnVisible = function (nCol)
{
	if (this.m_bTreePopup)
	{
		return true;
	}
	
	return (0 < this.m_heTreeBodyTable.rows[0].cells[nCol].firstChild.style.pixelWidth) ? true : false;
}

/**
 * 요청정보를 만든다.
 */
TreeAtom.prototype.makeRequest = function (xnRequest, bNodeExpand)
{
	var xnAtom = XmlLib.createChild(xnRequest, "Tree");
	xnAtom.setAttribute("VarName", this.m_strVarName);
	xnAtom.setAttribute("SQLIndex", this.m_nSQLIndex);
	
	if (this.m_bRootKey)
	{
		xnAtom.setAttribute("TopRootKey", "Y");
	}
	
	if (this.m_bFirstRequest)
	{
		xnAtom.setAttribute("FirstRequest", "Y");
		this.m_bFirstRequest = false;
	}
	
	if (null == this.m_objSelectNode)
	{
		xnAtom.setAttribute("SelectHandle", "0");
	}
	else
	{
		xnAtom.setAttribute("SelectHandle", this.m_objSelectNode.getNodeHandle());
	}
	
	if (true == bNodeExpand)
	{
		xnAtom.setAttribute("NodeExpand", "1");
	}
	
	this._makeTreeServiceRequest(xnAtom);
	
	this.m_objTreeHeader.makeRequest(xnAtom);
	
	this._makeValueAttrib(xnAtom);
}

/**
 * 연결 검색 실행
 */
TreeAtom.prototype.executeConnectionSearch = function ()
{
	GlobalField.setServiceName("SearchAction");
	GlobalField.setServiceEventName("Tree");
	GlobalField.setEventVarName(this.m_strVarName);
	
	var xnRequest = MakeRequest.createRequestNode();
	
	MakeRequest.makeServiceRequest(xnRequest);
	var xnAtomRequest = MakeRequest.getAtomRequestNode(xnRequest);
	
	MakeRequest.makeAtomRequest(xnRequest, true);
	
	this._makeTreeRequest(xnAtomRequest, false);
	
	var xnResultDoc = PQService.executeService(xnRequest.ownerDocument);
	
	this._clearAtom();
	
	HandleResult.execute(xnResultDoc);
}

/**
 * 트리전개를 수행한다.
 */
TreeAtom.prototype.expandNode = function (strAttr)
{
	var arAttr = strAttr.split(":");	// Type : Handle
	var strType = arAttr[0];
	var nHandle = Utils.parseInt(arAttr[1]);
	
	var objNode = this._getTreeNodeByHandle(nHandle);
	
	if (null != objNode)
	{
		if ("1199" == strType)	// 자동
		{
			this.onClick(nHandle, true);
		}
		else if ("1197" == strType)	// 축소
		{
			if (objNode.isOpen())
			{
				this.onClick(nHandle, true);
			}
		}
	}
}

/**
 * 트리 검색완료 후처리 스크립트 동작 실행
 */
TreeAtom.prototype.onEndSearchAfter = function ()
{
	ScriptAtomEvent.onEndSearchAfter(this.m_nScriptIndex);
}

TreeAtom.prototype._makeTreeServiceRequest = function (xnAtom)
{
	var xnServiceInfo = XmlLib.createChild(xnAtom, "ServiceInfo");
	
	var nTreeType = this._getTreeType();
	var strOrderField = this._getOrderField();
	var strLevelInfo = this._getLevelInfo();
	
	if (TreeAtom.UPDOWN_TREE == nTreeType && !strOrderField)
	{
		throw new NotConfigTreeAtomParentKey();
	}
	
	xnServiceInfo.setAttribute("TreeType", nTreeType);
	xnServiceInfo.setAttribute("OrderBy", strOrderField);
	xnServiceInfo.setAttribute("OrderKey", this._getOrderKey());
	xnServiceInfo.setAttribute("LevelInfo", strLevelInfo);
	xnServiceInfo.setAttribute("TreePopup", (this.m_bTreePopup) ? "Y" : "N");

	var objColumn = this.m_objTreeHeader.getColumnByFieldName(strOrderField);
	xnServiceInfo.setAttribute("FieldType", (null == objColumn) ? 0 : objColumn.getFieldType());

	if(strLevelInfo.length > 0)		// 레벨정보가 없으면 단계필드를 사용하지 않는다.
	{
		xnServiceInfo.setAttribute("IndexField", this.m_strIndexField);
	}
	else
	{
		xnServiceInfo.setAttribute("IndexField", "");
	}
	
	if (this.m_bTreePopup)
	{
		xnServiceInfo.setAttribute("TreePopupHandle", this.m_nTreePopupHandle);
	}
}

TreeAtom.prototype._clearAtom = function ()
{
	this._clearEventNode();
	
	this._clearSelectNode();
	
	this.m_arTreeNodeList.length = 0;
	
	var nLen = this.m_heTreeBodyTable.rows.length;
	for (var i = nLen - 1; i >= 0; i--)
	{
		this.m_heTreeBodyTable.deleteRow(i);
	}
	
	this._initTreeBodyTableTopPosition();
	this._changeVisibilityOfMoveButton();
}

TreeAtom.prototype._clearEventNode = function ()
{
	this.m_objEventNode = null;
}

TreeAtom.prototype._clearSelectNode = function ()
{
 	this.m_objSelectNode = null;
}

TreeAtom.prototype._setEventNode = function (nHandle)
{
	this.m_objEventNode = this._getTreeNodeByHandle(nHandle);
}

/**
 * 선택행의 스타일 변경
 * 이전 선택 한 노드의 배경색은 원래로 돌리고,
 * 새로 선택 한 노드의 배경색은 반전 시킨다.
 */
TreeAtom.prototype._setSelectNodeStyle = function (nHandle)
{
	if (null != this.m_objSelectNode)
	{
		var heNode = this.m_objSelectNode.getNodeHTML();

		if (null != heNode.childNodes[0])
		{
			// 조건 배경색이 있으면 넣고 아니면, 트리 배경색과 맞춘다
			var strConditionBGColor = "" == this.m_objSelectNode.getConditionBGColor() ? this.m_heTreeBodyTable.style.backgroundColor : this.m_objSelectNode.getConditionBGColor();
			var strConditionFontColor = "" == this.m_objSelectNode.getConditionFontColor() ? this.m_heTreeBodyTable.style.color : this.m_objSelectNode.getConditionFontColor();
		
			heNode.style.backgroundColor = strConditionBGColor;
			heNode.style.color = strConditionFontColor;
			
			//트리아이콘 짝수 선택
			if (this.m_bInsertImage && this.m_bUseSelectedImage)
			{
				var nTreeIconIndex = heNode.childNodes[0].firstChild.childNodes.length - 2;

				var heTreeIcon = heNode.childNodes[0].firstChild.childNodes[nTreeIconIndex];

				var nXpos = Utils.strPixelToint(heTreeIcon.style.backgroundPositionX) + this.m_nSplitWidth;
				
				heTreeIcon.style.backgroundPosition = nXpos + "px 0px";
			}
		}
	}
	
	this.m_objSelectNode = this._getTreeNodeByHandle(nHandle);
	
	if (null != this.m_objSelectNode)
	{
		var heNode = this.m_objSelectNode.getNodeHTML();
		
		heNode.style.backgroundColor = "#191970";
		heNode.style.color = "#FFFFFF";
		
		//트리아이콘 짝수 선택
		if (this.m_bInsertImage && this.m_bUseSelectedImage)
		{
			var nTreeIconIndex = heNode.childNodes[0].firstChild.childNodes.length - 2;

			var heTreeIcon = heNode.childNodes[0].firstChild.childNodes[nTreeIconIndex];

			var nXpos = Utils.strPixelToint(heTreeIcon.style.backgroundPositionX) - this.m_nSplitWidth;
			
			heTreeIcon.style.backgroundPosition = nXpos + "px 0px";
		}

		if (heNode.offsetTop + (heNode.offsetHeight * 3) > this.m_heTreeBody.clientHeight - this.m_heTreeBodyTable.style.pixelTop)
		{
			var nTop = this.m_heTreeBodyTable.style.pixelTop;;
			this.m_heTreeBodyTable.style.top = nTop -  (heNode.offsetHeight) + "px";
		}
	}
	
}

/**
 * 트리 노드 이벤트에 대한 동작 수행
 */
TreeAtom.prototype._executeTreeAction = function ()
{
	var objEventNode = this.m_objEventNode;
	if (null == objEventNode)
	{
		return;
	}
	
	if (TreeAtom.INDEP_TREE == this.m_objTreeHeader.getTreeType())
	{
		var nCurLevel = objEventNode.getLevel();
		var nMaxLevel = this.m_objTreeHeader.getMaxLevel();
		if (-1 > nCurLevel || nMaxLevel < nCurLevel)
		{
			return;
		}
		else if (nMaxLevel == nCurLevel)
		{
			if (!objEventNode.isAlone())
			{
				objEventNode.setAlone();
			}

			return;
		}
	}
	
	this._executeTreeNodeAction();
}

TreeAtom.prototype._executeTreeNodeAction = function ()
{
	var objEventNode = this.m_objEventNode;
	if (null == objEventNode)
	{
		return;
	}
	
	// 닫힌상태이면 
	if (objEventNode.isClose())
	{
		// child가 있으면 여는 동작
		if (objEventNode.hasChild())
		{
			objEventNode.setOpen();
			objEventNode.openNode();
		}
		// 없으면 검색 요청 & 여는 동작
		else
		{
			this._requestTreeNodeAction();
		}
		
	}
	// 열린상태이면 닫는 동작
	else if (objEventNode.isOpen())
	{
		objEventNode.setClose();
		objEventNode.closeNode();
	}
	// 자식노드가 없는 상태이면 아무 동작도 안한다.
	else if (objEventNode.isAlone())
	{
	}
}

/**
 * 서버에 현재 노드의 하위 노드에 대한 검색동작을 요청합니다.
 */
TreeAtom.prototype._requestTreeNodeAction = function ()
{
	this._setModelInfo();
	var xnRequestDoc = this._makeRequest();
	
	var xnResultDoc = null;
	
	var objWindow = window;
	
	// 트리 팝업 인경우라면 트리가 열린 창의 부모(모델) 의 PQService 를 호출 한다
	if (this.m_bTreePopup)
	{
		objWindow = window.opener;
	}
	
	xnResultDoc = objWindow.PQService.executeService(xnRequestDoc);
	
	this._handleTreeActionResult(xnResultDoc);
}

TreeAtom.prototype._makeRequest = function ()
{
	var xnRequest = MakeRequest.createRequestNode();

	MakeRequest.makeServiceRequest(xnRequest);
	
	if (this.m_bTreePopup)
	{
		window.opener.MakeRequest.makeTouchAtomRequest(xnRequest);
	}
	else
	{
		MakeRequest.makeTouchAtomRequest(xnRequest);
	}
	
	this._makeTreeRequest(xnRequest, true);
	
	return xnRequest.ownerDocument;
}

TreeAtom.prototype._makeTreeRequest = function (xnRequest, bNodeExpand)
{
	var xnAtomRequest = MakeRequest.getAtomRequestNode(xnRequest);
	this.makeRequest(xnAtomRequest, bNodeExpand);
}
	
/**
 * 트리의 값을 전송한다.
 * 현재 유저에 의해 선택된 값만 전송한다. (트리에선 선택된 항목 값을 서버에서 치환 하기 위해 전송)
 * @param xnRequest
 */
TreeAtom.prototype._makeValueAttrib = function (xnAtom)
{
	var xnValueAttrib = XmlLib.createChild(xnAtom, "Value");
	
	if (null == this.m_objSelectNode)
	{
		return ;
	}
	
	var heNode = this.m_objSelectNode.getNodeHTML();

	var xnRowDataAttrib = XmlLib.createChild(xnValueAttrib, "RowData");
	
	for (var j = 0; j < heNode.childNodes.length; j++)
	{
		var heNobr = heNode.childNodes[j].childNodes[0];
		var strColValue = heNobr.childNodes[heNobr.childNodes.length - 1].innerHTML;
	
		XmlLib.createChildWithValue(xnRowDataAttrib, "ColData", strColValue);
	}
}

/**
 * 하위노드 검색 결과를 처리합니다.
 *
 * @param xnResultDoc
 */
TreeAtom.prototype._handleTreeActionResult = function (xnResultDoc)
{
	var objEventNode = this.m_objEventNode;
	if (null == objEventNode)
	{
		return;
	}
	
	if (null == xnResultDoc)
	{
		objEventNode.setAlone();
		objEventNode.setNonIcon();
		return;
	}
	
	var xnResult = HandleResult.getAtomResultNode(xnResultDoc);
	var xnTree = XmlLib.selectSingleNode(xnResult, "./Tree");
	var xnDataRowList = XmlLib.selectNodeList(xnTree, "DataRow");
	if (null == xnDataRowList || 0 == xnDataRowList.length)
	{
		objEventNode.setAlone();
		objEventNode.setNonIcon();
		return;
	}

	objEventNode.setOpen();
	
	if (this.m_bTreePopup)
	{
		this._createPopupNodes(xnDataRowList);
		
		var strTreePopupHandle = xnTree.getAttribute("TreePopupHandle");
		if (null != strTreePopupHandle)
		{
			this.m_nTreePopupHandle = Utils.parseInt(strTreePopupHandle);
		}
	}
	else
	{
		this._createNodes(xnDataRowList);
	}
	this._hideUnVisibleColumnContent();
}

/**
 *	@param nHandle - 트리노드의 핸들
 *	@return 해당되는 트리노드, 없으면 null 리턴
 */
TreeAtom.prototype.getNode = function (nHandle)
{
	for (var nIndex = 0; nIndex < this.m_arTreeNodeList.length; nIndex += 1)
	{
		var objNode = this.m_arTreeNodeList[nIndex]
		if (nHandle == objNode.getNodeHandle())
		{
			return objNode;
		}
	}
	
	return null;
}

/**
 * 노드 검색 결과를 가지고 노드를 생성합니다.
 *
 * @param xnDataRowList
 * @nLevel
 */
TreeAtom.prototype._createNodes = function (xnDataRowList)
{
	for (var i = 0; i < xnDataRowList.length; i += 1)
	{
		var xnDataRow = xnDataRowList[i];
	
		var strMyHandle = xnDataRow.getAttribute("MyHandle");
		var nParentHandle = Utils.parseInt(xnDataRow.getAttribute("ParentHandle"));
		var nLevel = (0 == nParentHandle) ? 0 : Utils.parseInt(xnDataRow.getAttribute("Level"));
		var nPrevHandle = Utils.parseInt(xnDataRow.getAttribute("PrevHandle"));
		var nNextHandle = Utils.parseInt(xnDataRow.getAttribute("NextHandle"));
		
		var objParentNode = this.getNode(nParentHandle);
		var objPrevNode = this.getNode(nPrevHandle);
		var objNextNode = this.getNode(nNextHandle);
		
		this._createNode(xnDataRow, strMyHandle, nLevel, objParentNode, objPrevNode, objNextNode);
	}
}

/**
 * key 문자열의 트리 레벨을 구한다.
 */
TreeAtom.prototype._getLevelOfRow = function (strOrderKey)
{
	var strInfo = this.m_objTreeHeader.getLevelInfo();
	var strChar = this.m_objTreeHeader.getLevelChar();
	
	var arField = strInfo.split(",");
	var strKey = "";
	
	for (var i = 0; i < strOrderKey.length; i += 1)
	{
		var ch = strOrderKey.charAt(i);
		if (ch != strChar)
		{
			strKey += ch;
		}
	}
	
	var nKeyLen = strKey.length;
	var nLength = 0;
	var nLevel = 0;
	
	for (var j = 0; j < arField.length; j++)
	{
		nLength += Utils.parseInt(arField[j]);
		
		if(nKeyLen <= nLength)
		{
			nLevel = j + 1;
			break;
		}
	}
	
	return nLevel;
}

/**
 * 트리팝업 검색 결과를 처리한다.
 * 검색 결과는 동일한 레벨로 처리되며, 부모-자식 관계만 설정된다.
 */
TreeAtom.prototype._createPopupNodes = function (xnDataRowList)
{
	if (null == xnDataRowList)
	{
		return;
	}
	
	for (var i = 0; i < xnDataRowList.length; i += 1)
	{
		var xnDataRow = xnDataRowList[i];
	
		var strMyHandle = xnDataRow.getAttribute("MyHandle");
		var nParentHandle = Utils.parseInt(xnDataRow.getAttribute("ParentHandle"));
		var objParentNode = this.getNode(nParentHandle);
		
		var nLevel = 0;
		if (null != objParentNode)
		{
			nLevel = objParentNode.getLevel() + 1;
		}
		
		this._createNode(xnDataRow, strMyHandle, nLevel, objParentNode, null, null);
	}
}

/**
 * 노드 검색 결과를 가지고 노드를 생성합니다.
 *
 * @param xnDataRow
 * nLevel			: 노드의 트리 레벨
 * objParentNode	: 생성될 노드의 부모 노드
 */
TreeAtom.prototype._createNode = function (xnDataRow, nHandle, nLevel, objParentNode, objPrevNode, objNextNode)
{
	if (null == nHandle)
	{
		alert("no handle");
		nHandle = -1;
	}
	
	var heBodyTable = this.m_heTreeBodyTable;
	
	var objTreeNode = new TreeNode(this, this.m_objTreeHeader, nHandle, nLevel,
						objParentNode, objPrevNode, objNextNode, xnDataRow, this.m_bGridLines, this.m_nItemHeight,
						this.m_bShowTreeExtend, this.m_bShowTreeRoot, this.m_bShowTreeLine, heBodyTable.style.fontSize);
	
	objTreeNode.init(heBodyTable);
	
	this._addNodeList(objTreeNode);
	
	if (!this.m_bTreePopup)
	{
		this._changeTreeHeight();
	}
	
	//하위 노드 펼칠때 넓이 조정 필요시 주석 제거 
	//this._changeTreeWidth();

	return objTreeNode;
}

TreeAtom.prototype._addNodeList = function (objTreeNode)
{
	this.m_arTreeNodeList.push(objTreeNode);
}


/**
 * 트리 형식 반환합니다.
 *
 * @retuen 트리 형식 0:독립관계리, 1:상하위관계리, 2:스크립트트리
 */
TreeAtom.prototype._getTreeType = function ()
{
	return this.m_objTreeHeader.getTreeType();
}

/**
 * 기본키가 설정된 항목의 항목명을 반환니다.
 *
 * @return 항목명 (트리 형식에 따라 0:단계구성이 된 항목의 항목명, 1:상위키가 설정된 항목의 항목명)
 */
TreeAtom.prototype._getOrderField = function ()
{
	var strOrderField = "";
	
	if (this._isOpenTreePopup())
	{
		strOrderField = this.m_strTreePopupOrderField;
	}
	else
	{
		strOrderField = this.m_objTreeHeader.getOrderField();
	}
	
	return strOrderField; 
}

/**
 * 기본키에 대한 키 값을 반환합니다.
 *
 * @return 기본키 값 (트리 형식에 따라 0:단계구성이 된 항목의 값, 1:하위키가 설정된 항목의 값)
 */
TreeAtom.prototype._getOrderKey = function ()
{
	var strOrderKey = "";
	
	if (this._isOpenTreePopup())
	{
		strOrderKey = this.m_strTreePopupOrderKey;
	}
	else
	{
		if (null != this.m_objEventNode)
		{
			strOrderKey = this.m_objEventNode.getOrderKey();
		}
	}		
	
	return strOrderKey;
}

TreeAtom.prototype._isOpenTreePopup = function ()
{
	if (this.m_bTreePopup && null == this.m_objEventNode)
	{
		return true;
	}
	
	return false;
}

TreeAtom.prototype._isTreePopupDefaultKeyField = function ()
{
	if (this.m_objTreeHeader.isDefaultKeyField(this.m_strTreePopupOrderField))
	{
		return true;
	}
	else
	{
		return false;
	}
}

/**
 * 단계 구성 정보를 반환합니다.
 * @return 단계구성정보 (현재레벨:최대레벨:단계구성:분류문자 ex> 1:3:2,2,2:*)
 */
TreeAtom.prototype._getLevelInfo = function ()
{
	// 상하위 트리는 단계정보가 필요없다.
	if (TreeAtom.UPDOWN_TREE == this._getTreeType())
	{
		return "";
	}
	
	// 트리 팝업이 열릴 때, 팝업에서 넘어온 필드와 트리 기본키 설정 항목의 필드가 틀리면
	// 레벨 정보를 구성하지 않습니다.
	if (this.m_bTreePopup && this._isOpenTreePopup() && !this._isTreePopupDefaultKeyField())
	{
		return "";
	}
	
	var strLevelInfo = this.m_objTreeHeader.getLevelInfo();
	var nMaxLevel = this.m_objTreeHeader.getMaxLevel();
	var nCurLevel = this._getLevelOfEventNode();
	
	strLevelInfo = nCurLevel + ":" + nMaxLevel + ":" + strLevelInfo;
	
	return strLevelInfo;
}

/**
 * 생성되는 노드의 부모 노드를 반환합니다.
 */
TreeAtom.prototype._getParentNodeOfCreateNode = function ()
{
	return this.m_objEventNode;
}

/**
 * 생성되는 노드의 이전 형제 노드를 본환합니다.
 */
TreeAtom.prototype._getPrevNodeOfCreateNode = function ()
{
	if (null == this.m_objEventNode)
	{
		return this.m_arTreeNodeList[this.m_arTreeNodeList.length - 1];
	}
	
	return null;
}

/**
 * 이벤트가 발생한 노드의 단계를 반환합니다.
 */
TreeAtom.prototype._getLevelOfEventNode = function ()
{
	if (null == this.m_objEventNode)
	{
		return -1;
	}
	
	return this.m_objEventNode.getLevel();
}


TreeAtom.prototype._setModelInfo = function ()
{
	//SetServiceName("TreeAction");
	GlobalField.setServiceName("SearchAction");
	GlobalField.setServiceEventName("TreeNode");
	GlobalField.setEventVarName(this.m_strVarName);
}

TreeAtom.prototype._executeconnectionInput = function ()
{
	if (this.m_bTreePopup)
	{
		return;
	}
	
	var objEventNode = this.m_objEventNode;
	if (null == objEventNode)
	{
		return ;
	}
	
	var arConInputInfo = new Array();
	
	var objTreeHeader = this.m_objTreeHeader;
	var nLen = objTreeHeader.getColumnLength();
	for (var i = 0; i < nLen; i++)
	{
		if (!objTreeHeader.isReferenceKeyColumn(i))
		{
			continue;
		}
		
		var strItemVarName = objTreeHeader.getColumnItemVarName(i);
		var strTableName = objTreeHeader.getTableName();
		var strFieldName = objTreeHeader.getColumnFieldName(i);
		var strColumnValue = objEventNode.getColumnValue(i);
		
		var objConInputInfo = new PQConnectionInputInfo(strItemVarName, strTableName, strFieldName, strColumnValue);
		
		arConInputInfo.push(objConInputInfo);
	}
	
	PQConnectionInput.execute(arConInputInfo);
}

/**
 * 스크립트 동작에 의해서 트리 구조가 변경된 것을 반영합니다.
 */
TreeAtom.prototype._setScriptResult = function (xnAtom)
{
	var xnColumnList = XmlLib.selectNodeList(xnAtom, "./Column");
	this._applyColumnChange(xnColumnList);

	var xnRowList = XmlLib.selectNodeList(xnAtom, "./DataRow");
	if (null != xnRowList)
	{
		this._applyRowChange(xnRowList);
	}
	
	var xnDeleteRowList = XmlLib.selectNodeList(xnAtom, "./DeleteRow");
	if (null != xnDeleteRowList)
	{
		this._applyDeleteRowChange(xnDeleteRowList);
	}
}

/**
 * Column 정보가 변경된 것을 적용
 */
TreeAtom.prototype._applyColumnChange = function (xnColumnList)
{
	var nCol = 0;
	var nLen = this.m_objTreeHeader.getColumnLength();
	
	for (var nIndex = 0; nIndex < xnColumnList.length; nIndex++)
	{
		var xnColumn = xnColumnList[nIndex];
		var strColumnName = xnColumn.getAttribute("ColumnName");
		var strColumnType = xnColumn.getAttribute("ColumnType");
		var strItemVarName = xnColumn.getAttribute("ItemVarName");
		var nWidth = Utils.parseInt(xnColumn.getAttribute("Width"));
		var strInsert = xnColumn.getAttribute("Insert");
		/**
		 * 열 추가 스크립트에서 항목정열 attribute 생성해서 적용해주어야 함
		 * 기본적으로 좌측 정렬로 차후 스크립트 적용
		 */
		var nAlignType = xnColumn.getAttribute("ColumnAlign");	
		if (null != strInsert && "Y" == strInsert)
		{
			// 열추가
			var objNewColumn = new TreeColumn (strColumnName, strItemVarName, "", "",
					false, "", false, true, strColumnType, 0, false, false, nWidth, nAlignType);
			this.m_objTreeHeader.addColumn(nCol, objNewColumn);
			this._makeColumnElement(nCol, nWidth);
			nCol ++;
		}
		else
		{
			var objColumn = this.m_objTreeHeader.getColumn(nCol);
			if (null != objColumn && objColumn.getItemName() == strColumnName && objColumn.getFieldType() == strColumnType
					&& objColumn.getItemVarName() == strItemVarName)
			{
				nCol ++;
			}
			else
			{
				// 열삭제일 경우에 해당되나, 열삭제 스크립트 없음
			}
		}
	}
}

TreeAtom.prototype._makeColumnElement = function (nCol, nWidth)
{
	var objCol = document.createElement("<COL>");
	objCol.style.width = nWidth + "px";
	
	var objColGroup = this.m_heTreeBodyTable.childNodes[0];

	if (objColGroup.childNodes.length == nCol)
	{
		objColGroup.appendChild(objCol);
	}
	else
	{
		objColGroup.insertBefore(objCol, objColGroup.childNodes[nCol]);
	}
}

/**
 * 트리의 Node 행이 추가, 수정된 것을 반영 합니다.
 */
TreeAtom.prototype._applyRowChange = function (xnRowList)
{
	for (var i = 0; i < xnRowList.length; i += 1)
	{
		var xnDataRow = xnRowList[i];
		
		var strFlag = xnDataRow.getAttribute("Flag");
		var strMyHandle = xnDataRow.getAttribute("MyHandle");
		
		if ("1" == strFlag)		// 행이 삽입 되었을 경우
		{
			var nParentHandle = Utils.parseInt(xnDataRow.getAttribute("ParentHandle"));
			var nLevel = Utils.parseInt(xnDataRow.getAttribute("Level"));
			var nPrevHandle = Utils.parseInt(xnDataRow.getAttribute("PrevHandle"));
			var nNextHandle = Utils.parseInt(xnDataRow.getAttribute("NextHandle"));
			
			var objParentNode = this.getNode(nParentHandle);
			var objPrevNode = this.getNode(nPrevHandle);
			var objNextNode = this.getNode(nNextHandle);

			this._createNode(xnDataRow, strMyHandle, nLevel, objParentNode, objPrevNode, objNextNode);
		}
		else if ("2" == strFlag)	// 값이 수정되었을 경우
		{
			var objMyNode = this._getTreeNodeByHandle(strMyHandle);
			
			objMyNode.setNodeValue(xnDataRow);
		}
	}
	if (!this.m_bTreePopup)
	{
		this._changeTreeWidth();
	}
}

/**
 * 트리의 Node 행이 삭제된 것을 반영합니다.
 */
TreeAtom.prototype._applyDeleteRowChange = function (xnDeleteRowList)
{
	var nLen = xnDeleteRowList.length;
	
	for (var i = 0; i < nLen; i++)
	{
		var xnDeleteRow = xnDeleteRowList[i];
		
		var strMyHandle = xnDeleteRow.getAttribute("MyHandle");
		
		this._deleteTreeNode(strMyHandle);
	}
}

/**
 * 해당 핸들의 트리노드를 삭제한다.
 */
TreeAtom.prototype._deleteTreeNode = function (strHandle)
{
	for (var i = 0; i < this.m_arTreeNodeList.length; i++)
	{
		var objNode = this.m_arTreeNodeList[i]
		
		if (strHandle == objNode.getNodeHandle())
		{
			// html element 삭제
			var rowIndex = objNode.getNodeHTMLIndex();
			this.m_heTreeBodyTable.deleteRow(rowIndex);
		
			// node 객체 삭제
			objNode.deleteSelf();
			this.m_arTreeNodeList.splice(i, 1);
			break;
		}
	}
}

TreeAtom.prototype._getTreeNodeByHandle = function (nHandle)
{
	for (var i = 0; i < this.m_arTreeNodeList.length; i++)
	{
		if (nHandle == this.m_arTreeNodeList[i].getNodeHandle())
		{
			return this.m_arTreeNodeList[i];
		}
	}
	return null;
}

TreeAtom.prototype._setHeaderCursor = function (strCursorType)
{	
	this.m_objTreeHeader.m_heTreeHeaderTable.style.cursor = strCursorType;
}

TreeAtom.prototype._getHeaderCursor = function ()
{
	return this.m_objTreeHeader.m_heTreeHeaderTable.style.cursor;
}
TreeAtom.prototype.onMouseMoveTreeHeaderColumn = function (heColumn, nColumnIndex)
{
	if (this.m_bDisabled)
	{
		return;
	}
	
	var nOffsetX = event.offsetX;
	var nColWidth = heColumn.offsetWidth;
	
	if (nColWidth - 8 < nOffsetX && nOffsetX < nColWidth)
	{
		this._setHeaderCursor("col-resize");
	}
	else
	{
		if (false == this.m_bMouseHeaderDown && "col-resize" == this._getHeaderCursor())
		{
			this._setHeaderCursor("default");
		}
	}
	
}

TreeAtom.prototype.onMouseUpTreeHeaderColumn = function (heColumn)
{
	if (this.m_bDisabled)
	{
		return;
	}
	
	//헤더 스타일 변경시 적용될 코드
}

TreeAtom.prototype.onMouseOverTreeHeaderColumn = function (heColumn, nColumnIndex)
{
	if (this.m_bDisabled)
	{
		return;
	}
	//헤더 스타일 변경시 적용될 코드
}

TreeAtom.prototype.onMouseOutTreeHeaderColumn = function (heColumn)
{
	if (this.m_bDisabled)
	{
		return;
	}
	
	if (!this.m_bMouseHeaderDown)
	{
		//헤터 스타일 변경시 적용될 코드
		
		//마우스 기본으로..
		this._setHeaderCursor("default");
	}
	
}

TreeAtom.prototype.onMouseDownTreeHeaderColumn = function (heColumn)
{
	if (this.m_bDisabled)
	{
		return;
	}
	
	var nIndex = Utils.parseInt(heColumn.cellIndex);
	var nRowIndex = Utils.parseInt(heColumn.parentElement.parentElement.parentElement.RowIndex);
	
	if (2 == event.button)
	{
		//this._showContextMenu(objEvent);
	}
	else
	{
		if ("col-resize" == this._getHeaderCursor())
		{
			this.m_nOldXPos = event.screenX;
			this.m_bMouseHeaderDown = true;
			this.m_nSelectedColumnIndex = nIndex;
			this.m_bResized = true;
		}
	}
	
	event.returnValue = false;
	
}

TreeAtom.prototype.isMouseHeaderDown = function ()
{
	if (this.m_bMouseHeaderDown)
	{
		return true;
	}
	return false;
}

TreeAtom.prototype.mouseUpHeaderDown = function (objEvent)
{
	if (this.m_bMouseHeaderDown)
	{
		// 헤더 칼럼 넓이 조정
		this._plusColumnWidth(this.m_nSelectedColumnIndex, objEvent.screenX - this.m_nOldXPos, false);
		
		//헤더 높이 조정
		this._changeTreeHeight();
		
		var heColumnLine = document.getElementById("__TREE_COLUMNLINE_" + this.m_strVarName);
		heColumnLine.style.visibility = "hidden";

		//content DIV, tree body DIV 조정 
		var nColLen = this.m_objTreeHeader.m_arColumnList.length
		var nSumW = 0; 
		for (var i=0; i < nColLen ; i++)
		{
			nSumW += this.m_objTreeHeader.m_arColumnList[i].m_nWidth;
		}
		if (is_ie)
		{
			nSumW += nColLen * 2; //padding 값
		}
		
		var heContentDiv = document.getElementById(this.m_strVarName + "_CONTENT");
		var nTreeWidth = Utils.parseInt(this.m_heTreeDiv.style.width);

		if (nSumW > nTreeWidth)
		{
			heContentDiv.style.width = nSumW + "px";
			this.m_heTreeBody.style.width = nSumW + "px";
		}
		else
		{
			heContentDiv.style.width = nTreeWidth + "px";
			this.m_heTreeBody.style.width = nTreeWidth + "px";
		}
	}
	this.m_bMouseHeaderDown = false;
}

TreeAtom.prototype.mouseMoveHeaderDown = function (objEvent)
{
	if (this.m_bMouseHeaderDown)
	{
		// 헤더 칼럼 넓이 조정
		this._plusColumnWidth(this.m_nSelectedColumnIndex, objEvent.screenX - this.m_nOldXPos, true);
		
		//헤더 높이 조정
		this._changeTreeHeight();

		this._setHeaderCursor("col-resize");
		
		var heColumnLine = document.getElementById("__TREE_COLUMNLINE_" + this.m_strVarName);
		heColumnLine.style.pixelLeft = objEvent.clientX - this.m_heTreeDiv.offsetLeft;
		heColumnLine.style.visibility = "visible";

		//content DIV, tree body DIV 조정 
		var nColLen = this.m_objTreeHeader.m_arColumnList.length
		var nSumW = 0; 
		for (var i=0; i < nColLen ; i++)
		{
			nSumW += this.m_objTreeHeader.m_arColumnList[i].m_nWidth;
		}
		if (is_ie)
		{
			nSumW += nColLen * 2; //padding 값
		}
		
		var heContentDiv = document.getElementById(this.m_strVarName + "_CONTENT");
		var nTreeWidth = Utils.parseInt(this.m_heTreeDiv.style.width);

		if (nSumW > nTreeWidth)
		{
			heContentDiv.style.width = nSumW + "px";
			this.m_heTreeBody.style.width = nSumW + "px";
		}
		else
		{
			heContentDiv.style.width = nTreeWidth + "px";
			this.m_heTreeBody.style.width = nTreeWidth + "px";
		}
		
	}
	objEvent.returnValue = false;
}

TreeAtom.prototype._plusColumnWidth = function  (nColIndex, nOffset, bOnlyHead)
{
	var nCurWidth = this.m_objTreeHeader.m_arColumnList[nColIndex].getWidth();
	
	var nNewWidth = nCurWidth + nOffset;
	if (nNewWidth < 2)
	{
		nNewWidth = 2;
	}
		
	this._changeHeaderWidth(this.m_nSelectedColumnIndex, nNewWidth);
	
	if (!bOnlyHead)
	{
		this._changeBodyWidth(this.m_nSelectedColumnIndex, nNewWidth);
		
		this.m_objTreeHeader.m_arColumnList[nColIndex].setWidth(nNewWidth);
	}
}

TreeAtom.prototype._changeHeaderWidth = function (nColumnIndex, nWidth)
{
	var heColumnHeader = this.m_objTreeHeader.m_heTreeHeaderTable.rows[0]
	if (null != heColumnHeader)
	{
		heColumnHeader.cells[nColumnIndex].style.width = nWidth + "px";
	}
}

TreeAtom.prototype._changeBodyWidth = function (nColumnIndex, nWidth)
{
	if (null != this.m_heTreeBodyTable.rows[0] && 
		null != this.m_heTreeBodyTable.rows[0].cells[nColumnIndex])
	{
		this.m_heTreeBodyTable.rows[0].cells[nColumnIndex].style.width = nWidth + "px";
	}
}

TreeAtom.prototype._initTreeBodyTableTopPosition = function ()
{
	this.m_heTreeBodyTable.style.top = "0px";
}

TreeAtom.prototype.onMouseDownUpButton4Mobile = function ()
{
	var top = this.m_heTreeBodyTable.style.pixelTop;
	top += (this.m_nItemHeight * 2);
	if (top > 0)
	{
		top = 0;
	}

	this.m_heTreeBodyTable.style.top = top + "px";
	this._makeLocationBar();

}

TreeAtom.prototype.onMouseDownDownButton4Mobile = function ()
{
	var top = this.m_heTreeBodyTable.style.pixelTop;
	top -= (this.m_nItemHeight * 2);

	//body table의 높이.
	var nRowSumH = 0;
	var nRowH = 0;
	var nBodyRowCount = this.m_heTreeBodyTable.rows.length;
	for (var i = 0; i<nBodyRowCount; i++)
	{
		nRowSumH += Utils.parseInt(this.m_heTreeBodyTable.rows[i].style.height);
		nRowH = Utils.parseInt(this.m_heTreeBodyTable.rows[i].style.height);
	}
	
	//body div 높이
	var nBodyH = Utils.parseInt(this.m_heTreeBody.style.height);

	var nScrollH = nRowSumH - nBodyH;

	var bScroll = nRowSumH > this.m_heTreeBody.style.pixelHeight;
	//스크롤 할 부분이 있을 경우에만 동작처리 
	if (bScroll)
	{
		if ((top* -1) < (nScrollH + nRowH + 40))
		{
			this.m_heTreeBodyTable.style.top = top + "px";
		}
	}
	this._makeLocationBar();

}

/**
 * 아톰리스트
 */
TreeAtom._atoms = new Object();

TreeAtom.init = function ()
{
	for (var strVarName in TreeAtom._atoms)
	{
		var objAtom = TreeAtom._atoms[strVarName];
		
		objAtom.init();
	}
}

TreeAtom.getAtom = function (strVarName)
{
	return TreeAtom._atoms[strVarName];
}

/**
 * 검색창 아톰 리스트에서, 첫번째 검색창 아톰을 찾아 반환한다
 */
TreeAtom.getFirstAtom = function ()
{
	var objTreeAtom = null;
	
	for (var strVarName in TreeAtom._atoms)
	{
		objTreeAtom = TreeAtom._atoms[strVarName];
		
		if (null != objTreeAtom)
		{
			return objTreeAtom;
		}
	}
	
	return objTreeAtom;
}

TreeAtom.onScroll = function (strVarName, heEventItem)
{
	var objTreeAtom = TreeAtom.getAtom(strVarName);
	if (null == objTreeAtom)
	{
		return;
	}
	
	objTreeAtom.onScroll(heEventItem);
}

TreeAtom.makeRequest = function (xnAtomRequest)
{
	for (var strVarName in TreeAtom._atoms)
	{
		var objAtom = TreeAtom._atoms[strVarName];
		if (null != objAtom)
		{
			objAtom.makeRequest(xnAtomRequest);
		}
	}
}

TreeAtom.makeDireceExecRequest = function (xnAtomRequest)
{
	for (var strVarName in TreeAtom._atoms)
	{
		var objAtom = TreeAtom.getAtom(strVarName);
		
		if (objAtom.isDirectExec())
		{
			objAtom.makeRequest(xnAtomRequest);
		}
	}
}

TreeAtom.getHeaderDownAtom = function ()
{
	for (var strVarName in TreeAtom._atoms)
	{
		var objTreeAtom = TreeAtom._atoms[strVarName];
		
		if (null != objTreeAtom)
		{
			if (objTreeAtom.isMouseHeaderDown())
			{
				return objTreeAtom;
			}
		}
	}
	return null;
}
TreeAtom.onMouseMoveTreeHeaderColumn = function (strVarName, heColumn, nColumnIndex)
{
	var objAtom = TreeAtom.getAtom(strVarName);
	if (null != objAtom)
	{
		objAtom.onMouseMoveTreeHeaderColumn(heColumn, nColumnIndex);
	}
}

TreeAtom.onMouseUpTreeHeaderColumn = function (strVarName, heColumn)
{
	var objAtom = TreeAtom.getAtom(strVarName);
	if (null != objAtom)
	{
		objAtom.onMouseUpTreeHeaderColumn(heColumn);
	}
}

TreeAtom.onMouseOverTreeHeaderColumn = function (strVarName, heColumn, nColumnIndex)
{
	var objAtom = TreeAtom.getAtom(strVarName);
	if (null != objAtom)
	{
		objAtom.onMouseOverTreeHeaderColumn(heColumn, nColumnIndex);
	}
	
}

TreeAtom.onMouseOutTreeHeaderColumn = function  (strVarName, heColumn)
{
	var objAtom = TreeAtom.getAtom(strVarName);
	if (null != objAtom)
	{
		objAtom.onMouseOutTreeHeaderColumn(heColumn);
	}	
}

TreeAtom.onMouseDownTreeHeaderColumn = function (strVarName, heColumn)
{
	var objAtom = TreeAtom.getAtom(strVarName);
	if (null != objAtom)
	{
		objAtom.onMouseDownTreeHeaderColumn(heColumn);
	}
}

TreeAtom.onMouseDownUpButton4Mobile = function (strVarName, objEvent)
{
	objEvent = HTMLLib.getEvent(objEvent);
	
	var objAtom = TreeAtom.getAtom(strVarName);
	if (null != objAtom)
	{
		objAtom.onMouseDownUpButton4Mobile();
	}
	
	objEvent.cancelBubble = true;
}

TreeAtom.onMouseDownDownButton4Mobile = function (strVarName, objEvent)
{
	objEvent = HTMLLib.getEvent(objEvent);
	
	var objAtom = TreeAtom.getAtom(strVarName);
	if (null != objAtom)
	{
		objAtom.onMouseDownDownButton4Mobile();
	}
	
	objEvent.cancelBubble = true;
}


function TreeColumn (strItemName, strItemVarName, strTableName, strFieldName,
					bReferenceKey, strDisplayInfo, bDefaultKey, bVisible,
					strFieldType, nDisplayType, bParentKey, bChildKey,
					nWidth, nAlignType)
{
	this.m_strItemName = strItemName;			// 항목제목
	this.m_strItemVarName = strItemVarName;		// 항목명
	
	this.m_strTableName = strTableName;			// 테이블명
	this.m_strFieldName = strFieldName;			// 필드명
	
	this.m_bReferenceKey = bReferenceKey;		// 참조정보키 설정 여부
	
	this.m_strDisplayInfo = strDisplayInfo;		// 표현형식
	this.m_bDefaultKey = bDefaultKey;			// 기본키 설정 여부
	
	this.m_bVisible = bVisible;					// 표시여부
	this.m_strFieldType = strFieldType;			// Field 자료형

	this.m_nDisplayType = nDisplayType;			// 일반 트리에서는 0,  팝업창 제외 표시일 경우 1
		
	this.m_bParentKey = bParentKey;				// 상위키
	this.m_bChildKey = bChildKey;				// 하위키
	
	this.m_nWidth = nWidth;
	this.m_nAlignType = nAlignType;				// 항목정렬
	
	this.m_strLevelInfo = "";
	this.m_nMaxLevel = 0;
	this.m_strLevelChar = "";
	
	this.m_heColumn = null;
}

TreeColumn.prototype.getItemVarName = function ()
{
	return this.m_strItemVarName;
}

TreeColumn.prototype.getItemName = function ()
{
	return this.m_strItemName;
}

TreeColumn.prototype.getTableName = function ()
{
	return this.m_strTableName;
}

TreeColumn.prototype.getFieldName = function ()
{
	return this.m_strFieldName;
}

TreeColumn.prototype.getFieldType = function ()
{
	return this.m_strFieldType;
}

TreeColumn.prototype.getLevelChar = function ()
{
	return this.m_strLevelChar;
}

TreeColumn.prototype.getMaxLevel = function ()
{
	return this.m_nMaxLevel;
}

TreeColumn.prototype.getLevelInfo = function ()
{
	return this.m_strLevelInfo;
}

TreeColumn.prototype.getWidth = function ()
{
	return this.m_nWidth;
}
TreeColumn.prototype.setWidth = function (nWidth)
{
	this.m_nWidth = nWidth;
}
TreeColumn.prototype.getAlignType = function ()
{
	return this.m_nAlignType;
}

TreeColumn.prototype.getUserDisplayInfo = function ()
{
	return this.m_strDisplayInfo;
}

TreeColumn.prototype.getDisplayType = function ()
{
	return this.m_nDisplayType;
}

TreeColumn.prototype.isReferenceKey = function ()
{
	return this.m_bReferenceKey;
}

TreeColumn.prototype.isDefaultKey = function ()
{
	return this.m_bDefaultKey;
}

TreeColumn.prototype.isParentKey = function ()
{
	return this.m_bParentKey;
}

TreeColumn.prototype.isChildKey = function ()
{
	return this.m_bChildKey;
}

TreeColumn.prototype.isVisible = function ()
{
	return this.m_bVisible;
}

TreeColumn.prototype.init = function (heColumn)
{
	this.m_heColumn = heColumn;
	
	if (this.m_bDefaultKey)
	{
		this._initInfo();
	}
}
	
TreeColumn.prototype._initInfo = function ()
{
	var strDisplayInfo = this.m_strDisplayInfo;
	
	if (-1 < strDisplayInfo.indexOf("LEVEL:"))
	{
		this._initLevelInfo();
	}
	else
	{
		this._initDisplayInfo();
	}
}

TreeColumn.prototype._initLevelInfo = function ()
{
	var strDisplayInfo = this.m_strDisplayInfo;
	
	var arDisplayInfo = strDisplayInfo.split("$");
	
	var arLevel = arDisplayInfo[1].split(":");
	
	var strStep = arLevel[1];
	var strLevelChar = arDisplayInfo[2];
	
	this.m_nMaxLevel = strStep.split(",").length;
	var arStepInfo = strStep.split(",");
	
	this.m_strLevelInfo = strStep + ":" + strLevelChar;
	this.m_strLevelChar = strLevelChar;
}

TreeColumn.prototype._initDisplayInfo = function ()
{
	// MagicXML에서 m_strDisplayInfo가 있는 컴럼에 m_bDefaultKey을 참으로 설정했기 때문에 거짓으로 바꿔준다.
	this.m_bDefaultKey = false;
}


function TreeHeader (nTreeType, strRowCondition, arColumnList)
{
	this.m_nTreeType = nTreeType;	// 트리 동작 방법	0:단일체계, 1:상하위체계, 2:사용자정의
	
	this.m_arColumnList = arColumnList;
	
	this.m_nDefaultKeyIndex = -1;	// 구성 단계 설정된 항목 or 하위키 설정 항목
	this.m_nParentKeyIndex = -1;		// 상위키 설정 항목
	this.m_nChildKeyIndex = -1;		// 하위키 설정 항목
	
	this.m_heTreeHeaderDiv = null;
	this.m_heTreeHeaderTable = null;
	
	this.m_strRowCondition = strRowCondition;	// 조건별 구분색 (조건$색깔;조건$색깔;....)
	this.m_alRowCondition = new Array();	// 조건별 구분색을 {필드명 : 조건, 조건색} 형태로 저장한다.
}

////////////////////////////////////////
// getter / setter

TreeHeader.prototype.getColumnLength = function ()
{
	return this.m_arColumnList.length;
}

TreeHeader.prototype.getTreeType = function ()
{
	return this.m_nTreeType;
}

TreeHeader.prototype.getColumnWidth = function (nCount)
{
	return this.m_arColumnList[nCount].getWidth();
}

TreeHeader.prototype.getTableName = function ()
{
	return this.m_arColumnList[0].getTableName();
}

/**
 * 기본키가 설정된 항목의 항목 인덱스를 반환니다.
 *
 * @return 항목인덱스 (트리 형식에 따라 0:단계구성이 된 항목의 인덱스, 1:하위키가 설정된 항목의 인덱스)
 */
TreeHeader.prototype.getOrderFieldIndex = function ()
{
	var nDefaultKeyIndex = -1;
	
	if (TreeAtom.UPDOWN_TREE == this.m_nTreeType)
	{
		nDefaultKeyIndex = this.m_nChildKeyIndex;
	}
	else
	{
		nDefaultKeyIndex = this.m_nDefaultKeyIndex;
	}
	
	return nDefaultKeyIndex;
}

/**
 * 기본키가 설정된 항목의 항목명을 반환니다.
 *
 * @return 항목명 (트리 형식에 따라 0:단계구성이 된 항목의 항목명, 1:상위키가 설정된 항목의 항목명)
 */
TreeHeader.prototype.getOrderField = function ()
{
	var nDefaultKeyIndex = -1;

	if (TreeAtom.UPDOWN_TREE == this.m_nTreeType)
	{
		nDefaultKeyIndex = this.m_nParentKeyIndex;
	}
	else
	{
		nDefaultKeyIndex = this.m_nDefaultKeyIndex;		
	}
	
	var strOrderField = "";
	if (-1 != nDefaultKeyIndex)
	{
		strOrderField = this.m_arColumnList[nDefaultKeyIndex].getItemVarName();
		if (null == strOrderField || 0 == strOrderField.length)
		{
			strOrderField = this.m_arColumnList[nDefaultKeyIndex].getFieldName();
		}
	}
	
	return strOrderField;
}

/**
 * 기본키에 대한 키 값을 반환합니다.
 *
 * @return 기본키 값 (트리 형식에 따라 0:단계구성이 된 항목의 값, 1:하위키가 설정된 항목의 값)
 */
TreeHeader.prototype.getOrderKey = function ()
{
	var nDefaultKeyIndex = -1;

	if (TreeAtom.UPDOWN_TREE == this.m_nTreeType)
	{
		nDefaultKeyIndex = this.m_nParentKeyIndex;
	}
	else
	{
		nDefaultKeyIndex = this.m_nDefaultKeyIndex;
	}
	
	var strOrderKey = "";
	if (-1 != nDefaultKeyIndex)
	{
		strOrderKey = this.m_arColumnList[nDefaultKeyIndex].getValue();
	}
	
	return strOrderKey;
}

TreeHeader.prototype.getLevelChar = function ()
{
	if(null != this.m_arColumnList[this.m_nDefaultKeyIndex])
	{
		return this.m_arColumnList[this.m_nDefaultKeyIndex].getLevelChar();
	}
	return null;
}

TreeHeader.prototype.getMaxLevel = function ()
{
	if (null == this.m_arColumnList[this.m_nDefaultKeyIndex])
	{
		return null;
	}
	return this.m_arColumnList[this.m_nDefaultKeyIndex].getMaxLevel();
}

TreeHeader.prototype.getLevelInfo = function ()
{
	if (null == this.m_arColumnList[this.m_nDefaultKeyIndex])
	{
		return null;
	}
	return this.m_arColumnList[this.m_nDefaultKeyIndex].getLevelInfo();
}

TreeHeader.prototype.getWidth = function ()
{
	var nWidth = 0;
	if (null != this.m_heTreeHeaderTable)
	{
		nWidth = Utils.parseInt(this.m_heTreeHeaderTable.style.width);
	}
	
	return nWidth;
}

TreeHeader.prototype.getHeaderTable = function ()
{
	return this.m_heTreeHeaderTable;
}

TreeHeader.prototype.getConditionSize = function ()
{
	return this.m_alRowCondition.length;
}

TreeHeader.prototype.getConditionInfo = function (nRow)
{
	return this.m_alRowCondition[nRow];
}

/**
 * 해당 컬럼이 visible 인지를 리턴
 */
TreeHeader.prototype.isColumnVisible = function (nCol)
{
	return this.m_arColumnList[nCol].isVisible();
}

TreeHeader.prototype.getColumnDisplayType = function (nCol)
{
	return this.m_arColumnList[nCol].getDisplayType();	
}

TreeHeader.prototype.getColumnFieldName = function (nCol)
{
	return this.m_arColumnList[nCol].getFieldName();	
}

TreeHeader.prototype.getColumnFieldType = function (nCol)
{
	return this.m_arColumnList[nCol].getFieldType();
}

TreeHeader.prototype.getColumnVarName = function (nCol)
{
	return this.m_arColumnList[nCol].getItemVarName();
}

TreeHeader.prototype.getColumnIndex = function (strItemName)
{
	var nLen = this.m_arColumnList.length;
	for (var i = 0; i < nLen; i++)
	{
		if (strItemName == this.m_arColumnList[i].getItemVarName())
		{
			return i;
		}
	}
	
	return -1;
}

TreeHeader.prototype.getColumnItemVarName = function (nIndex)
{
	return this.m_arColumnList[nIndex].getItemVarName();
}

TreeHeader.prototype.isReferenceKeyColumn = function (nIndex)
{
	return this.m_arColumnList[nIndex].isReferenceKey();
}

TreeHeader.prototype.isParentKeyColumn = function (nIndex)
{
	if (TreeAtom.UPDOWN_TREE == this.m_nTreeType && this.m_nParentKeyIndex == nIndex)
	{
		return true;
	}
	
	return false;
}

TreeHeader.prototype.isDefaultKeyField = function (strOrderField)
{
	if (strOrderField == this.getOrderField())
	{
		return true;
	}
	
	return false;
}

TreeHeader.prototype.setScrollPos = function (nPos)
{
	if (null != this.m_heTreeHeaderDiv)
	{
		this.m_heTreeHeaderDiv.scrollLeft = nPos;
	}
}

////////////////////////////////////////
// public method

TreeHeader.prototype.init = function (strVarName)
{
	this._initHTML(strVarName);
	
	var heHeaderRow = null;
	if (null != this.m_heTreeHeaderTable)
	{
		heHeaderRow = this.m_heTreeHeaderTable.rows[0];
	}
	
	var arColumnList = this.m_arColumnList;
	var nLen = arColumnList.length;
	for (var i = 0, j = 0; i < nLen; i++)
	{
		var objColumn = arColumnList[i];
		
		var heColumn = null;
		
		if (null != heHeaderRow)
		{
			heColumn = heHeaderRow.cells[j];
			j++;
		}
		
		objColumn.init(heColumn);			
		this._initKeyInfo(objColumn, i);
	}
	
	this._checkDefaultKey();
	
	this._makeColorCondition();
}

TreeHeader.prototype.makeRequest = function (xnAtom)
{
	var strLevelInfo = this.getLevelInfo();
	if (null != strLevelInfo)
	{
		xnAtom.setAttribute("LevelInfo", strLevelInfo);
		xnAtom.setAttribute("LevelChar", this.getLevelChar());
		xnAtom.setAttribute("OrderColumn", this.getOrderFieldIndex());
	}

	var arColumnList = this.m_arColumnList;
	var nLen = arColumnList.length;
	for (var i = 0; i < nLen; i++)
	{
		var objColumn = arColumnList[i];
		var xnColumn = XmlLib.createChild(xnAtom, "Column");
				
		xnColumn.setAttribute("UserDisplayInfo", objColumn.getUserDisplayInfo());
		xnColumn.setAttribute("ItemVarName", objColumn.getItemVarName());
		xnColumn.setAttribute("ColumnName", objColumn.getItemName());
		xnColumn.setAttribute("ColumnType", objColumn.getFieldType());
		xnColumn.setAttribute("ColumnWidth", objColumn.getWidth());
		xnColumn.setAttribute("IsReferenceKey", objColumn.isReferenceKey() ? "true" : "false");
		xnColumn.setAttribute("ColumnAlign", objColumn.getAlignType());
	}
}

TreeHeader.prototype.getColumn = function (nCol)
{
	return this.m_arColumnList[nCol];
}

/**
 *	@param strFieldName - 필드명
 *	@return 필드명에 해당되는 컬럼
 */
TreeHeader.prototype.getColumnByFieldName = function (strFieldName)
{
	var nLen = this.m_arColumnList.length;
	for (var i = 0; i < nLen; i += 1)
	{
		if (this.m_arColumnList[i].getFieldName() == strFieldName)
		{
			return this.m_arColumnList[i];
		}
	}
	
	return null;
}

TreeHeader.prototype.addColumn = function (nCol, objColumn)
{
	this.m_arColumnList.splice(nCol, 0, objColumn);
	
	this._makeColumnElement(nCol, objColumn.getWidth());
	
	this._makeHeaderTableElement(nCol, objColumn);
}

////////////////////////////////////////
// private method

TreeHeader.prototype._initHTML = function (strVarName)
{
	this.m_heTreeHeaderDiv = document.getElementById(TreeHeader.TREE_HEADER + strVarName);
	
	this.m_heTreeHeaderTable = document.getElementById(TreeHeader.TREE_HEADER_CONTENT + strVarName);
}

/**
 * 열추가시 COL 엘리먼트 생성
 */
TreeHeader.prototype._makeColumnElement = function (nCol, nWidth)
{
	var heColGroup = this.m_heTreeHeaderTable.childNodes[0];

	var heCol = document.createElement("<COL>");
	heCol.style.width = nWidth + "px";
	
	if (heColGroup.childNodes.length - 1 <= nCol)
	{
		heColGroup.appendChild(heCol);
	}
	else
	{
		heColGroup.insertBefore(heCol, heColGroup.childNodes[nCol]);
	}
}

/**
 * 열추가시 TD 엘리먼트 생성
 */
TreeHeader.prototype._makeHeaderTableElement = function (nCol, objColumn)
{
	var heTR = this.m_heTreeHeaderTable.childNodes[1].childNodes[0];
	
	var heTD = document.createElement("<TD>");
	heTD.style.width = objColumn.getWidth() + "px";
	heTD.innerText = objColumn.getItemName();
	
	if (heTR.childNodes.length - 1 <= nCol)
	{
		heTR.appendChild(heTD);
	}
	else
	{
		heTR.insertBefore(heTD, heTR.childNodes[nCol]);
	}
}

TreeHeader.prototype._initKeyInfo = function (objColumn, nIndex)
{
	// 만약 단계구성과 부모키가 동시에 설정되는 경우는 구성이 잘못된 폼입니다.
	if (this._isDefaultKey(objColumn))
	{
		this.m_nDefaultKeyIndex = nIndex;
	}
	else if (this._isParentKey(objColumn))
	{
		this.m_nParentKeyIndex = nIndex;
	}
	else if (this._isChildKey(objColumn))
	{
		this.m_nChildKeyIndex = nIndex;
	}
}

/**
 * 독립적 관계트리 인데, 기본키 값이 설정이 되어 있지 않는 경우에는 트리가 동작 하지 않으므로,
 * 첫번째 컬럼을 기본키로 넣어 주어, 트리 내용을 볼 수 있게 한다.
 */
TreeHeader.prototype._checkDefaultKey = function ()
{
	if (TreeAtom.INDEP_TREE == this.m_nTreeType && this.m_nDefaultKeyIndex < 0)
	{
		if (this.getColumnLength() > 0)
		{
			this.m_nDefaultKeyIndex = 0;
		}
	}
}

/**
 * 문자열 형식의 조건별 구분색을
 * {
 * 		strColumnFieldName : 필드명,
 * 		strCondition : 조건식,
 *		strColor : 색깔
 * };
 * 형식으로 만들어 저장한다
 */
TreeHeader.prototype._makeColorCondition = function ()
{
	var alRowConditions = this.m_strRowCondition.split(";");
	
	for (var i = 0, nLen = alRowConditions.length; i < nLen; i++)
	{
		var alRowCondition = alRowConditions[i].split("$");

		var objRowCondition = {
			strCondition : Utils.trim(alRowCondition[0]),
			strBGColor : Utils.trim(alRowCondition[1]),
			strFontColor : Utils.trim(alRowCondition[2])
		};
		
		this._addCondidtion(objRowCondition);
	}
}

/**
 * 조건형식에 맞춰진 데이터를 저당한다
 */
TreeHeader.prototype._addCondidtion = function (objRowCondition)
{
	this.m_alRowCondition.push(objRowCondition);
}

TreeHeader.prototype._isDefaultKey = function (objColumn)
{
	// 기본키가 두개 이상 설정되어 있으면, 먼저 설정된 것을 기본키로 합니다.
	if (-1 == this.m_nDefaultKeyIndex && objColumn.isDefaultKey())
	{
		return true;
	}
	
	return false;
}

TreeHeader.prototype._isParentKey = function (objColumn)
{
	// 상위키가 두개 이상 설정되어 있으면, 먼저 설정된 것을 상위키로 합니다.
	if (-1 == this.m_nParentKeyIndex && objColumn.isParentKey())
	{
		return true;
	}
	
	return false;
}

TreeHeader.prototype._isChildKey = function (objColumn)
{
	// 하위키가 두개 이상 설정되어 있으면, 먼저 설정된 것을 하위키로 합니다.
	if (-1 == this.m_nChildKeyIndex && objColumn.isChildKey())
	{
		return true;
	}
	
	return false;
}

TreeHeader.TREE_HEADER = "__TREE_HEADER_";
TreeHeader.TREE_HEADER_CONTENT = "__TREE_HEADER_CONTENT_";

function TreeNode (objTreeAtom, objTreeHeader, nHandle, nLevel,
					objParentNode, objPrevNode, objNextNode, xnDataRow,
					bGridLines, nItemHeight, bShowTreeExtend, bShowTreeRoot,
					bShowTreeLine, strFontSize)
{
	this.m_objTreeAtom = objTreeAtom;
	this.m_objTreeHeader = objTreeHeader;
	
	this.m_nHandle = nHandle;		// NodeIndex를 사용하던 것에서 Handle을 사용해서 Node를 구분 하는것으로 변경
	this.m_nLevel = nLevel;
	this.m_nState = TreeNode.CA;
	
	this.m_objParentNode = objParentNode;
	this.m_objPrevNode = objPrevNode;
	this.m_objNextNode = objNextNode;
	this.m_arChildNodeList = new Array();
	
	this.m_heTreeNode = null;
	this.m_xnDataRow = xnDataRow;
	
	this.m_bGridLines = bGridLines;				// 구분선
	this.m_nItemHeight = nItemHeight;			// 행 높이
	this.m_nFontSize = Utils.getPonitToPixel(Utils.parseInt(strFontSize));		// 폰트 크기
	
	this.m_bShowTreeExtend = bShowTreeExtend;	// 확장 표시
	this.m_bShowTreeRoot = bShowTreeRoot;		// 최상위 표시
	this.m_bShowTreeLine = bShowTreeLine;		// 구분선
	
	this.m_strConditionFontColor = "";
	this.m_strConditionBGColor = "";
}	
	
////////////////////////////////////////
// getter / setter

TreeNode.prototype.getNodeHandle = function ()
{
	return this.m_nHandle;
}

TreeNode.prototype.getOrderKey = function ()
{
	var nIndex = this.m_objTreeHeader.getOrderFieldIndex();
	
	var xnColumns = this.m_xnDataRow.childNodes;
	var strValue = "";
	if (null != xnColumns && null != xnColumns[nIndex])
	{
		strValue = XmlLib.getTextValue(xnColumns[nIndex]);
		if (null == strValue)
		{
			strValue = "";
		}
	}
	
	return strValue;
}

TreeNode.prototype.getDataRow = function ()
{
	return this.m_xnDataRow;
}

TreeNode.prototype.getConditionFontColor = function ()
{
	return this.m_strConditionFontColor;
}

TreeNode.prototype.getConditionBGColor = function ()
{
	return this.m_strConditionBGColor;
}

TreeNode.prototype.getNodeHTML = function ()
{
	return this.m_heTreeNode;
}

TreeNode.prototype.getNodeHTMLIndex = function ()
{
	if (null == this.m_heTreeNode)
	{
		return 0;
	}
	
	return this.m_heTreeNode.rowIndex;
}

TreeNode.prototype.getLevel = function ()
{
	return this.m_nLevel;
}

TreeNode.prototype.getState = function ()
{
	return this.m_nState;
}

TreeNode.prototype.getParentNode = function ()
{
	return this.m_objParentNode;
}

TreeNode.prototype.getNextNode = function ()
{
	return this.m_objNextNode;
}

TreeNode.prototype.getPrevNode = function ()
{
	return this.m_objPrevNode;
}

TreeNode.prototype.setNextNode = function (objNextNode)
{
	this.m_objNextNode = objNextNode;
}

TreeNode.prototype.setPrevNode = function (objPrevNode)
{
	this.m_objPrevNode = objPrevNode;
}

TreeNode.prototype.getLastChild = function ()
{
	return this.m_arChildNodeList[this.m_arChildNodeList.length - 1];
}

TreeNode.prototype.getColumnValue = function (nIndex)
{
	var xnColumns = this.m_xnDataRow.childNodes;
	var xnColumn = xnColumns[nIndex];
	
	return XmlLib.getTextValue(xnColumn);
}

TreeNode.prototype.hasChild = function ()
{
	if (null == this.m_arChildNodeList || 0 == this.m_arChildNodeList.length)
	{
		return false;
	}
	
	return true;
}

TreeNode.prototype.isAlone = function ()
{
	if (TreeNode.ALONE == this._getCurrentState())
	{
		return true;
	}
	
	return false;
}

TreeNode.prototype.isClose = function ()
{
	if (TreeNode.CLOSE == this._getCurrentState())
	{
		return true;
	}
	
	return false;
}

TreeNode.prototype.isOpen = function ()
{
	if (TreeNode.OPEN == this._getCurrentState())
	{
		return true;
	}
	
	return false;
}

TreeNode.prototype.setState = function (nState)
{
	this.m_nState = nState;
	
	this._setIcon();
}

TreeNode.prototype.setOpen = function ()
{
	this.setState(this.m_nState + TreeNode.STATEGAP);
}

TreeNode.prototype.setClose = function ()
{
	this.setState(this.m_nState - TreeNode.STATEGAP);
}

TreeNode.prototype.setAlone = function ()
{
	this.setState(this.m_nState + (TreeNode.STATEGAP * 2));
}

TreeNode.prototype.setHideHTML = function ()
{
	this._setDisplayHTML("none");
}

TreeNode.prototype.setShowHTML = function ()
{
	//block을 사용하면 행높이가 큰 경우  상하행들이 겹치는 문제 발생. 
	this._setDisplayHTML("");
}

////////////////////////////////////////
// public method

TreeNode.prototype.init = function (heBodyTable)
{
	this._createHTML(heBodyTable);
	
	this._setBrotherNode();
	
	this._setChildOfParentNode();
	
	this._setNodeState();
}
/**
 * 클릭시 자식노드가 없으면 확장 표시를 없앤다.. 
 */
TreeNode.prototype.setNonIcon = function()
{
	var node = this.m_heTreeNode;
	for (var i=0 ; i < this.m_heTreeNode.childNodes.length ;i++ )
	{
		if (null != node.childNodes[i].firstChild.childNodes[this.m_nLevel + 1] && node.childNodes[i].firstChild.childNodes[this.m_nLevel + 1].nodeName =="LABEL")
		{
			node.childNodes[i].firstChild.childNodes[this.m_nLevel + 1].style.backgroundImage = "";
			break;
		}
	}
}
TreeNode.prototype.closeNode = function ()
{
	this._hideChild();
}

TreeNode.prototype.openNode = function ()
{
	this._showChild();
}

/*
TreeNode.prototype.getChildNodeKeyList = function ()
{
	var arChildNodeList = this.m_arChildNodeList;
	if (null == arChildNodeList)
	{
		return "";
	}
	
	var strChildNode = "";
	var nLen = arChildNodeList.length;
	for (var i = 0; i < nLen; i++)
	{
		var objChild = arChildNodeList[i];
		if (null == objChild)
		{
			continue;
		}
		
		if ("" == strChildNode)
			strChildNode = objChild.getNodeIndex();
		else
			strChildNode = strChildNode + ";" + objChild.getNodeIndex();
	}
}
*/

TreeNode.prototype.addChildNode = function (objChildNode)
{
	this.m_arChildNodeList.push(objChildNode);
}

TreeNode.prototype.removeChildNode = function (objChildNode)
{
	for (var i = 0; this.m_arChildNodeList.length; i++)
	{
		if (this.m_arChildNodeList[i] == objChildNode)
		{
			this.m_arChildNodeList.splice(i, 1);
			break;
		}
	}
}

/**
 * 트리 노드가 삭제될때, 앞,뒤, 자식 노드들을 업데이트 한다.
 */
TreeNode.prototype.deleteSelf = function ()
{
	if (null != this.m_objNextNode)
	{
		this.m_objNextNode.setPrevNode(this.m_objPrevNode);
	}
	
	if (null != this.m_objPrevNode)
	{
		this.m_objPrevNode.setNextNode(this.m_objNextNode);
	}
	
	if (null != this.m_objParentNode)
	{
		this.m_objParentNode.removeChildNode (this);
	}
}

TreeNode.prototype.setNodeValue = function (xnDataRow)
{
	this.m_xnDataRow = xnDataRow;

	var heTR = this.m_heTreeNode;
	for (var i = 1; i < heTR.childNodes.length; i++)
	{
		var xnColumn = this.m_xnDataRow.childNodes[i];
	
		var heSpan = heTR.childNodes[i].childNodes[0].childNodes[0];
		
		if (null != heSpan && heSpan.tagName == "SPAN")
		{
			var strValue = XmlLib.getTextValue(xnColumn);
			if (null == strValue)
			{
				strValue = "";
			}
			
			heSpan.innerText = strValue;
		}
	}
}


////////////////////////////////////////
// private method

/**
	트리 노드 HTML 구조
	
	<tr>
	   	<td>
	   		<nobr>
	   			<img />
	   			...
	   			<span>값</span>
	   		</nobr>
	   	</td>
	   	...
	</tr>
 */
TreeNode.prototype._createHTML = function (heBodyTable)
{
	var heTreeNode = this._createNodeHTML(heBodyTable);
	
	// 행 높이 설정
	this.m_nItemHeight = this.m_nItemHeight + 3;
	heTreeNode.style.height = this.m_nItemHeight + "px";
	
	var bIcon = true;
	var xnColumns = this.m_xnDataRow.childNodes;
	var nLen = xnColumns.length;
	
	for (var i = 0; i < nLen; i++)
	{
		var xnColumn = xnColumns[i];
				
		var heColumn = document.createElement("td");
		heTreeNode.appendChild(heColumn);
		this._setColumnStyle(heColumn);
		heColumn.style.overflow = "hidden";
		heColumn.style.textOverflow = "ellipsis";
		
		var heColumnLayout = document.createElement("nobr");
		heColumn.appendChild(heColumnLayout);
					
		if (this.m_objTreeHeader.isColumnVisible(i) && !this.m_objTreeHeader.isParentKeyColumn(i) 
				&& (this.m_objTreeHeader.getColumnWidth(i) > 0 || this.m_objTreeAtom.isTreePopup()))
		{
			if (bIcon)
			{
				// 확장표시, 구분선을 그린다.
				this._renderIcon(heColumnLayout);
				bIcon = false;

				if (this.m_objTreeAtom.m_bInsertImage)
				{
					//그림 삽입
					this._setTreeIcon(heColumnLayout);
				}
			}
		}
		
		var strValue = XmlLib.getTextValue(xnColumn);

		if (null == strValue)
		{
			strValue = "";
		}		
		
		// 팝업 트리일 경우, 팝업창 제외 표시 속성, 또는 단계필드 일 경우, 내용을 공백 처리 한다.
		if (this.m_objTreeAtom.isTreePopup())
		{
			var nDisplayType = this.m_objTreeHeader.getColumnDisplayType(i);
			if (1 == nDisplayType || 3 == nDisplayType)
			{
				var nLength = strValue.length;
				strValue = "";
				
				for (var n = 0; n < nLength; n++)
				{
					strValue += " ";
				}
			}
		}
		
		var heSpan = document.createElement("span");
		heSpan.style.margin = "0px";
		heSpan.style.verticalAlign = "middle";
		// span 영역을 셀 크기만큼 늘린다.
	
		if (this.m_nItemHeight > this.m_nFontSize)
		{
			var nPaddingSize = (this.m_nItemHeight - this.m_nFontSize) / 2 + 1;
			heSpan.style.paddingTop = nPaddingSize.toString();
			heSpan.style.paddingBottom = nPaddingSize.toString();
			heTreeNode.style.height = (this.m_nItemHeight + 1) + "px";
		}
		else if (this.m_nItemHeight < this.m_nFontSize)
		{
			var nPaddingSize = (this.m_nFontSize - this.m_nItemHeight) / 2 + 1;
			heSpan.style.paddingTop = nPaddingSize.toString();
			heSpan.style.paddingBottom = nPaddingSize.toString();
			heTreeNode.style.height = ((this.m_nItemHeight) + (this.m_nFontSize - 12)) + "px";
		}
		
		heSpan.style.width = "100%";
		if (i >0)
		{
			var strColumnAlign = "left";
			switch (this.m_objTreeHeader.m_arColumnList[i].getAlignType()) {
				case 1:
					strColumnAlign ="center";
					break;
				case 2:
					strColumnAlign ="right";
					break;
				default:
					strColumnAlign ="left";
					break;
			}
	
			heColumn.align = strColumnAlign;
		}
		if (this.m_objTreeAtom.m_bBodyUnderline)
		{
			heSpan.style.textDecoration = "underline";
		}
		
		this._setConditionColor(i, heTreeNode, strValue);
		
		heColumnLayout.appendChild(heSpan);
		this._setColumnEvent(heSpan);
		
		var heText = document.createTextNode(strValue);
		heSpan.appendChild(heText);
		
	}
	
	this._setNodeEvent(heTreeNode);
	
	this._setNodeID(heTreeNode);
}

/**
 * 해당 노드의 행의 조건색을 정으한다
 * @param nColumnIndex
 * @param strFieldValue (필드값)
 */
TreeNode.prototype._setConditionColor = function (nColumnIndex, heTreeNode, strFieldValue)
{
	var strColVarName = this.m_objTreeHeader.getColumnVarName(nColumnIndex);
	if (null == strColVarName || 0 == strColVarName.length)
	{
		strColVarName = this.m_objTreeHeader.getColumnFieldName(nColumnIndex);
	}
	
	var strFieldType = this.m_objTreeHeader.getColumnFieldType(nColumnIndex);
	// 문자 형식인 경우 "'값'" 상태로 바꾼다 
	if ("CHAR" == strFieldType.toUpperCase() || "TEXT" == strFieldType.toUpperCase())
	{
		strFieldValue = Utils.changeFormatToChar(strFieldValue);
	}
			
	var nSize = this.m_objTreeHeader.getConditionSize();
	for (var i = 0; i < nSize; i+=1)
	{
		var objRowCondition = this.m_objTreeHeader.getConditionInfo(i);
		var strCondition = objRowCondition.strCondition;
		
		if (-1 != strCondition.indexOf(strColVarName))
		{
			// "=" => "==" 로
			strCondition = this._replaceEqualCharToCondition(strCondition);
			
			// 컬럼의값을 적용하여 조건절을 완성한다. 
			strCondition = Utils.replace(strCondition, strColVarName, strFieldValue);
			
			if (true == eval(strCondition))
			{
				heTreeNode.style.backgroundColor = objRowCondition.strBGColor;
				heTreeNode.style.color = objRowCondition.strFontColor;
				
				this.m_strConditionFontColor = objRowCondition.strFontColor;
				this.m_strConditionBGColor = objRowCondition.strBGColor;
				
				break;
			}
		}
	}
}

/**
 * 비교 내용이 같다("=") 인경우 
 * 자바스크립트가 인식할수 있는 같다("==") 로 바꿔 줍니다
 */
TreeNode.prototype._replaceEqualCharToCondition = function (strCondition)
{
	var strReplacedResult = strCondition;

	if (-1 != strCondition.indexOf("="))
	{
		if (-1 == strCondition.indexOf("<=") && -1 == strCondition.indexOf(">="))
		{
			strReplacedResult = Utils.replace(strCondition, "=", "==");
		}
	}

	return strReplacedResult;
}

/**
 * 트리노드 html 엘리먼트를 생성한다.
 * 생성되는 위치의 table상의 index 위치를 계산한다.
 */
TreeNode.prototype._createNodeHTML = function (heBodyTable)
{
	var nIndex = 0;
	
	if (null == this.m_objNextNode)
	{
		if (null == this.m_objPrevNode)
		{
			if (null == this.m_objParentNode)
			{
				nIndex = heBodyTable.rows.length;
			}
			else
			{
				var objLastBrotherNode = this.m_objParentNode.getLastChild();
				if (null == objLastBrotherNode)
				{
					nIndex = this.m_objParentNode.getNodeHTMLIndex() + 1;
				}
				else
				{
					var objLastNode = objLastBrotherNode;
					nIndex = objLastNode.getNodeHTMLIndex() + 1;
					
					while (null != objLastNode)
					{
						nIndex = objLastNode.getNodeHTMLIndex() + 1;
						objLastNode = objLastNode.getLastChild();
					}
				}
			}
		}
		else
		{
			nIndex = this.m_objPrevNode.getNodeHTMLIndex() + this.m_objPrevNode.getAllChildNodesCount() + 1;
		}
	}
	else
	{
		nIndex = this.m_objNextNode.getNodeHTMLIndex();
	}
	
	this.m_heTreeNode = heBodyTable.insertRow(nIndex);
	
	return this.m_heTreeNode;
}

/**
 *	@return 모든 자손노드의 개수
 */
TreeNode.prototype.getAllChildNodesCount = function ()
{
	var nCount = 0;
	
	for (var i = 0; i < this.m_arChildNodeList.length; i += 1)
	{
		var objNode = this.m_arChildNodeList[i];
		nCount += objNode.getAllChildNodesCount() + 1;
	}
	
	return nCount;
}

/**
*
*/
TreeNode.prototype._setTreeIcon = function (heColumnLayout)
{
	var objTreeAtom = this.m_objTreeAtom;

	var strImgUrl = objTreeAtom.m_strImageFilePath;
	
	var heImgLabel = document.createElement("label");
	
	this._setTreeIconStyle(heImgLabel);

	heImgLabel.style.background = "url("+strImgUrl+") 18px 0px no-repeat";

	
	var nXpos = (-objTreeAtom.m_nSplitWidth) * (this.m_nLevel);

	if (objTreeAtom.m_bUseSelectedImage && this.m_nLevel>0)
	{
		nXpos = nXpos * 2;
	}
	

	
	heImgLabel.style.backgroundPosition = nXpos + "px 0px";
	heColumnLayout.appendChild(heImgLabel);

}
/**
 * 확장표시, 구분선 아이콘을 그린다.
 */
TreeNode.prototype._renderIcon = function (heColumnLayout)
{
	var nLevel = this.m_nLevel;
	var objThis = this;
	
	var i = 0;
	if (this.m_bShowTreeRoot)
	{
		i = -1;		
	}
	else
	{
		i = 0;
	}
	
	var nStartFor = i;
	// 현재노드의 레벨에서 확장 표시 위치 이전까지의 부분에 들어가는 아이콘 그림
	for ( ; i < nLevel; i++)
	{
		var heImgLabel = document.createElement("label");
		this._setIconStyle(heImgLabel);
		
		if (this._isBlankIcon(i) && this.m_bShowTreeLine )
		{
			if (!this.m_bShowTreeRoot && i==nStartFor)
			{
				this._setBlankIcon(heImgLabel);
			}
			else
			{
				this._setVLineIcon(heImgLabel);
			}
		}
		else
		{
			this._setBlankIcon(heImgLabel);
		}
		
		heColumnLayout.appendChild(heImgLabel);
	}
	
	var heImgLabel = document.createElement("label");
	this._setIconStyle(heImgLabel);
	
	// 최상위 표시를 하지 않을 경우
	if (!this.m_bShowTreeRoot && nLevel == 0)
	{
		
		this._setBlankIcon(heImgLabel);
	}
	else
	{
		this._setIconImage(heImgLabel);
		heImgLabel.id = TreeNode.ICON_ID;
		heImgLabel.name = TreeNode.ICON_ID;
	
	}

	//스마트폰에서 아이콘 노드가 작아서 클릭하기 어려우므로
	if (is_android || is_iphone)
	{
		heColumnLayout.onclick = function ()
		{
			objThis.m_objTreeAtom.onClick(objThis.m_nHandle, true);
		}
	}
	else
	{
		heImgLabel.onclick = function ()
		{
			objThis.m_objTreeAtom.onClick(objThis.m_nHandle, true);
		}
	}
	
	heColumnLayout.appendChild(heImgLabel);
}

TreeNode.prototype._isBlankIcon = function (nLevel)
{
	var objParentNode = this.m_objParentNode;
	var nCurrentLevel = this.m_nLevel;
	
	for (var i = nCurrentLevel - 1; i > nLevel; i--)
	{
		if (null == objParentNode)
		{
			return false;
		}

		objParentNode = objParentNode.getParentNode();
	}
	
	if (null != objParentNode && null != objParentNode.getNextNode())
	{
		return true;
	}
	else
	{
		return false;
	}	
}


TreeNode.prototype._getNodeID = function ()
{
	 return TreeNode.TREE_HEADER_CONTENT_ITEM + this.m_objTreeAtom.getVarName();
}

TreeNode.prototype._getCurrentState = function ()
{
	var nState = this.m_nState;
	
	var nResult = TreeNode.CLOSE;
	
	if (TreeNode.CA <= nState && TreeNode.CB >= nState)
	{
		nResult = TreeNode.CLOSE;
	}
	else if (TreeNode.OA <= nState && TreeNode.OB >= nState)
	{
		nResult = TreeNode.OPEN;
	}
	else if (TreeNode.AA <= nState && TreeNode.AB >= nState)
	{
		nResult = TreeNode.ALONE;
	}
	
	return nResult;
}

TreeNode.prototype._getIconHTML = function ()
{
	var heColumn = null;

	// 화면에 표시되는 첫번째 컬럼을 찾아서 아이콘을 그려준다.
	for (var i = 0; i < this.m_heTreeNode.childNodes.length; i++)
	{
		if (this.m_objTreeAtom.isTreeBodyColumnVisible(i))
		{
			heColumn = this.m_heTreeNode.childNodes[i];
			break;
		}
	}

	if (null == heColumn)
	{
		return null;
	}
	
	// nobr tag
	var heColumnLayout = heColumn.firstChild;
	if (null == heColumnLayout)
	{
		return null;
	}
	
	// img, span tag
	var heItems = heColumnLayout.childNodes;
	if (null == heItems)
	{
		return null;
	}
	
	// 트리 상태 아이콘을 찾는다.
	var nLen = heItems.length;
	for (var i = 0; i < nLen; i++)
	{
		var heItem = heItems[i];
		if (null == heItem)
		{
			continue;
		}
		
		if (TreeNode.ICON_ID == heItem.id)
		{
			return heItem;
		}
	}
	
	return null;
}

/**	
 * 확장표시,구분선  아이콘 그림 파일경로를 리턴
 */
TreeNode.prototype._setIconImage = function (heImgLabel)
{
	var nState = this.m_nState;
	
	// 확장기호만 표시
	if (this.m_bShowTreeExtend && !this.m_bShowTreeLine)
	{
		nState = this._getCurrentState();
		if (TreeNode.CLOSE == nState)
		{
			nState = TreeNode.PL;
		}
		else if (TreeNode.OPEN == nState)
		{
			nState = TreeNode.MI;
		}
		else if (TreeNode.ALONE == nState)
		{
			nState = TreeNode.NO;
		}
		
	}
	// 관계선만 표시
	else if (!this.m_bShowTreeExtend && this.m_bShowTreeLine)
	{
		nState = (this.m_nState % 4) + 8;
	}
	// 확장 기호와 관계선 표시 안함
	else if (!this.m_bShowTreeExtend && !this.m_bShowTreeLine)
	{
		this._setBlankIcon(heImgLabel);
		return;
	}
	
	var nXpos = nState * -18;
	heImgLabel.style.backgroundPosition = nXpos + "px 0px";
}

TreeNode.prototype._setBlankIcon = function (heImgLabel)
{
	heImgLabel.style.backgroundPosition = "18px 0px";
}

TreeNode.prototype._setVLineIcon = function (heImgLabel)
{
	heImgLabel.style.backgroundPosition = "-216px 0px";
}

TreeNode.prototype._setBrotherNode = function ()
{
	var objPrevNode = this.m_objPrevNode;
	
	if (null != objPrevNode)
	{
		objPrevNode.setNextNode(this);
		
		this.m_objPrevNode = objPrevNode;
	}
	
	if (null != this.m_objNextNode)
	{
		this.m_objNextNode.setPrevNode(this);
	}
}

TreeNode.prototype._setChildOfParentNode = function ()
{
	if (null != this.m_objParentNode)
	{
		this.m_objParentNode.addChildNode(this);
	}
}

TreeNode.prototype._setNodeEvent = function (heTreeNode)
{
	/*
	heTreeNode.onmouseover = function ()
	{
		heTreeNode.style.backgroundColor = "#d3d3d3";
	}
	
	heTreeNode.onmouseout = function ()
	{
		heTreeNode.style.backgroundColor = "#FFFFFF";
	}
	*/
}

TreeNode.prototype._setColumnStyle = function (heColumn)
{
	heColumn.style.paddingLeft = TreeNode.COLUMN_PADDING + "px";
	heColumn.style.paddingRight = TreeNode.COLUMN_PADDING + "px";
	heColumn.style.verticalAlign = "middle";
	heColumn.style.textOverflow = "ellipsis";

	if (this.m_bGridLines)		// 셀 구분선 설정
	{
		heColumn.style.borderRight = TreeNode.BORDER_STYLE;
		heColumn.style.borderBottom = TreeNode.BORDER_STYLE;		
	}
}

TreeNode.prototype._setColumnEvent = function (heSpan)
{
	var objThis = this;
	
	heSpan.onclick = function ()
	{
		objThis.m_objTreeAtom.onClick(objThis.m_nHandle);
	}
	
	heSpan.ondblclick = function ()
	{
		objThis.m_objTreeAtom.onDblClick(objThis.m_nHandle);
	}
	
	heSpan.onmousedown = function ()
	{
		objThis.m_objTreeAtom.onMouseDown(objThis.m_nHandle);
	}
}

TreeNode.prototype._setNodeID = function (heTreeNode)
{
	var strNodeID = this._getNodeID();
	heTreeNode.setAttribute("id", strNodeID);
	heTreeNode.setAttribute("name", strNodeID);
}

TreeNode.prototype._setNodeState = function ()
{
	var nState = TreeNode.CA;
	
	if (null == this.m_objParentNode && null == this.m_objPrevNode)
	{
		nState = TreeNode.CA;
	}
	else
	{
		nState = TreeNode.CB;
	}
	
	this.setState(nState);
	
	this._setPrevNodeState();
}

TreeNode.prototype._setPrevNodeState = function ()
{
	if (null != this.m_objPrevNode)
	{
		var nPrevState = this.m_objPrevNode.getState();
		
		if (TreeNode.CA == nPrevState)
		{
			this.m_objPrevNode.setState(TreeNode.CT);
		}
		else if (TreeNode.CB == nPrevState)
		{
			this.m_objPrevNode.setState(TreeNode.CM);
		}
		else if (TreeNode.AB == nPrevState)
		{
			this.m_objPrevNode.setState(TreeNode.AM);
		}
	}
}

TreeNode.prototype._setIcon = function ()
{
	var heIcon = this._getIconHTML();
	if (null == heIcon)
	{
		return;
	}
	
	this._setIconImage(heIcon);
}

TreeNode.prototype._setIconStyle = function (heImgLabel)
{
	heImgLabel.style.width = TreeNode.ICON_WIDTH + "px";
	heImgLabel.style.height = TreeNode.ICON_WIDTH + "px";
	//heImgLabel.style.verticalAlign = "middle";
	
	heImgLabel.style.background = "url(/ups/sys/image/pq/atom/TreeAtom.gif) 18px 0px no-repeat";
	heImgLabel.style.overflow = "hidden";
	heImgLabel.style.display = "inline-block";
	heImgLabel.style.verticalAlign = "middle";
}

TreeNode.prototype._setTreeIconStyle = function (heImgLabel)
{
	heImgLabel.style.width = TreeNode.ICON_WIDTH + "px";
	heImgLabel.style.height = TreeNode.ICON_WIDTH + "px";
	
	heImgLabel.style.overflow = "hidden";
	heImgLabel.style.display = "inline-block";
}

TreeNode.prototype._hideChild = function ()
{
	var arChildNodeList = this.m_arChildNodeList;
	if (null == arChildNodeList)
	{
		return;
	}
	
	var nLen = arChildNodeList.length;
	for (var i = 0; i < nLen; i++)
	{
		var objChild = arChildNodeList[i];
		if (null == objChild)
		{
			continue;
		}
		
		objChild.setHideHTML();
		
		objChild.closeNode();
	}
}

TreeNode.prototype._showChild = function ()
{
	var arChildNodeList = this.m_arChildNodeList;
	if (null == arChildNodeList)
	{
		return;
	}
	
	var nLen = arChildNodeList.length;
	for (var i = 0; i < nLen; i++)
	{
		var objChild = arChildNodeList[i];
		if (null == objChild)
		{
			continue;
		}
			
		objChild.setShowHTML();
		
		if (objChild.isOpen())
		{
			objChild.openNode();
		}
	}
}

TreeNode.prototype._setDisplayHTML = function (strDisplay)
{
	this.m_heTreeNode.style.display = strDisplay;
}
	

TreeNode.COLUMN_PADDING = 2;
TreeNode.BORDER_STYLE = "1px solid lightgrey";

TreeNode.TREE_HEADER_CONTENT_ITEM = "__TREE_HEADER_CONTENT_ROW_";

TreeNode.ICON_ID = "StateIcon";
TreeNode.ICON_WIDTH = 18;

/**
	트리 노드 레벨 구성
	
	초기 레벨 : -1
	시작 레벨 : 0
 */
TreeNode.STARTLEVEL = 0;

/**
	상태 변화 오토마타	(-----> : click 동작)
	
	Close and Alone	----->	Open	<----->	Close and Not Alone
					 |
					 ---->	Alone
	노드 상태
	Close	: 닫힌 상태(+)
	Open	: 열린 상태(-)
	Alone	: 자식이 없는 상태
	
	노드 위치				 
	Alone	: 노드가 오직 하나 일 경우
	Top		: 노드 위치가 맨 위일 경우
	Middle	: 노드 위치가 가운데일 경우
	Bottom	: 노드 위치가 마지막일 경우
 */
TreeNode.STATEGAP = 4;

TreeNode.CLOSE = 0;
TreeNode.OPEN = 1;
TreeNode.ALONE = 2;

TreeNode.CA = 0;
TreeNode.CT = 1;
TreeNode.CM = 2;
TreeNode.CB = 3;

TreeNode.OA = 4;
TreeNode.OT = 5;
TreeNode.OM = 6;
TreeNode.OB = 7;

TreeNode.AA = 8;
TreeNode.AT = 9;
TreeNode.AM = 10;
TreeNode.AB = 11;

TreeNode.PL = 13;		// + 확장 기호만 표시
TreeNode.MI = 14;		// - 확장 기호만 표시
TreeNode.NO = 19;		// 확장 기호 표시 안함
