/**
 * WebScrollPagerRss Javascript 클래스 목록
 * 	- WebScrollAtom
 *	- ScrollRow
 *	- ScrollEvent
 *  - WebScrollButton
 *  - WebAtomPager
 *  - WebRssAtom
 *  - WebRssRow
 */

/**
 * 웹 스크롤 아톰 클래스
 * 스크롤 행 클래스를 이용해서 스크롤 기능을 수행합니다.
 *
 * 스크롤 행 인텍스 참고 
 *  - 0부터 : this.m_arRowList, html row id
 *  - 1부터 : 행번호, 일련번호
 */
var g_htWebDisplayAtom = new Hashtable();
var g_htWebDisplayOriginSize = new Hashtable();
var g_htWebDisplayMoveCount = new Hashtable();

function WebScrollAtom (strVarName, // 1
					nScriptIndex, // 2
					nSQLIndex,
					nDBIndex,
					nMaxRow, // 3
					nPageRow, // 4
					nRowCount, // 5
					nColumnCount, // 6
					bSerialAutoUpdate, // 7
					bSureInputScroll, // 8
					bRemoveRow, // 9
					bAddRow, // 10
					nWebScrollCurrentHeight, // 11
					nWebScollOriginWidth, // 12
					nWebScrollType, // 13
					objWebScrollPager, // 14
					objWebScrollButton, // 15
					objResizableObject, // 16
					bDisplayAtom, // 17
					nEffectType, // 18
					nInterval) // 19
{
	this.Atom (strVarName, "", strVarName, -1, nScriptIndex, nSQLIndex, nDBIndex);
	
	this.m_strRowID = strVarName + "_ScrollRow_";
	
	this.m_nMaxRow = nMaxRow;						// 최대 표시 행수
	this.m_nPageRow = nPageRow;						// 페이지당 표시 행 수
	this.m_nRowCount = nRowCount; // 매트릭스형 웹스크롤 행수
	this.m_nColumnCount = nColumnCount; // 매트릭스형 웹스크롤 열수
	this.m_bSureInputScroll = bSureInputScroll;
	this.m_arSureInputWebScrollAtomList = new Array();	// 유효행이 체크된 입력란 리스트
	
	this.m_arRowList = new Array();					// 스크롤 행 리스트
	this.m_arDeleteRowList = new Array();			// 스크롤 삭제행 리스트
	this.m_nSelectedRowIndex = 0;					// 선택된 행 인덱스
	this.m_strSelectedAtomVarName = "";	// 선택된 아톰의 VarName
	
	this.m_bRemoveRow = bRemoveRow;		// 행 삭제 단축 사용여부
	this.m_bAddRow = bAddRow;			// 행 추가 단축 사용 여부
	
	this.m_nLastValidRowIndex = -1;					// 플래그가 F, I, U인 마지막 행 인덱스를 저장합니다.
	
	this.m_bSerialAutoUpdate = bSerialAutoUpdate;	// 일련번호 자동수정
	
	this.m_heAtom = document.getElementById(strVarName);
	
	this.m_nScrollTop = 0; //스크롤의 현재 위치 저장, 위/아래 이동시 제어
	this.m_nStartHtmlRowIndex = 0; //현재 HTML을 가진 스크롤의 row 인덱스
	this.m_bEventIgnoreFlag = false; //스크롤 이벤트 무시하는 경우 설정 플래그
	
	// 웹 스크롤 타입
	// 0: 페이지목차
	// 1: 스크롤버튼
	// 2: 매트릭스
	this.m_nWebScrollType = nWebScrollType;
	
	// 페이지목차형 웹스크롤 아톰의 페이지 컨트롤, 그 외에는 null
	this.m_objWebScrollPager = objWebScrollPager;
	// 스크롤버튼형 웹스크롤 아톰의 버튼 컨트롤, 그 외에는 null
	this.m_objWebScrollButton = objWebScrollButton;
	
	/**
	 * 웹 아톰 - 웹스크롤 게시판, 문자방송
	 */
	this.m_nWebScrollCurrentHeight = nWebScrollCurrentHeight + this._getPagerHeight();
	this.m_nOriginWidth = nWebScollOriginWidth;
	this.m_objResizableObject = objResizableObject;
	this.m_bDisplayAtom = bDisplayAtom;
	this.m_nEffectType = nEffectType;
	this.m_nInterval = nInterval;
	this.m_objTimer = null;
}

WebScrollAtom.prototype = new Atom ();
WebScrollAtom.prototype.constructor = WebScrollAtom;

WebScrollAtom.prototype.getFieldName = function ()
{
	this.m_strFieldName;
}

WebScrollAtom.prototype.getSelectedRowIndex = function ()
{
	return this.m_nSelectedRowIndex;
}

WebScrollAtom.prototype.getLastValidRowIndex = function ()
{
	return this.m_nLastValidRowIndex;
}

WebScrollAtom.prototype.getOperationRowSize = function ()
{
	var nSize = this.getLastValidRowIndex() + 1;
	if (nSize < 1)
	{
		// 웹스크롤은 조회 하기전에 연산식으로 값을 받아와야 하므로, 최초의 한행은 연산식이 일어나게 값을 리턴함
		nSize = 1;
	}
	return nSize;
}

WebScrollAtom.prototype.getScrollHeight = function()
{
	return this.m_nWebScrollCurrentHeight;
}

WebScrollAtom.prototype.setSelectedRowIndex = function (idx)
{
	this.m_nSelectedRowIndex = idx;
}

/**
 * 웹 스크롤 인지의 여부를 반환한다
 */
WebScrollAtom.prototype.isWebScroll = function ()
{
	if (null == this.m_objWebScrollPager && null == this.m_objWebScrollButton)
	{
		return false;
	}
	
	return true;
}

WebScrollAtom.prototype.isWebDisplay = function ()
{
	return this.m_bDisplayAtom;
}

WebScrollAtom.prototype.getBindedAtom = function (strVarName, nRowIndex)
{
	var objRow = this.m_arRowList[nRowIndex];
	if (null == objRow)
	{
		return null;
	}
	
	return objRow.getBindedAtom(strVarName);
}

WebScrollAtom.prototype.getSelectedAtomVarName = function ()
{
	return this.m_strSelectedAtomVarName
}

WebScrollAtom.prototype.isBindAtomAction = function (nPropID)
{
	switch (nPropID)
	{
		case 344: // 초점주기
		case 343: // 연산실행
		case 299: // 입력검사
		case 347: // 팝업실행
			return true;
		default :
			return false;
	}
}

WebScrollAtom.prototype.loadRecord = function (nSearchOp)
{
	var nLoadSuccess = -1;
	
	// 1. 기존 값들을 지워 준다..
	if (-1 == nSearchOp)
	{
//			ClearContent (false, 0, false); 
	}

	var nDBIndex = -1;
	var strPrimaryItem;
	
	if (0 < this.m_arRowList.length)
	{
		var objRow = this.m_arRowList[0];
		var arAtoms = objRow.getBindedAtomList();
		
		for (var strAtom in arAtoms)
		{
			var objAtom = arAtoms[strAtom];
			if (null == objAtom || false == objAtom.isDefaultKey())
				continue;
			
			nDBIndex = objAtom.getDBIndex();
			if (0 > nDBIndex)
				continue;
			
			strPrimaryItem = objAtom.getFieldName();
			break;
		}
	}
	
	var objAtomPageQuery = new WebAtomPageQuery (strPrimaryItem);
	
	this.m_objWebScrollPager.setAtomPageQuery(objAtomPageQuery);

	// 스크롤에 관계설정이 되어 있는 경우 스크롤의 DATABASE를 가져옵니다.
//	if (0 != RelationFieldsAtoms.Count)
//	{
//		if (null == pDatabaseX)
//			pDatabaseX = GetDatabaseX (GetDBIndex (b2stLoad));
//	}

	// 실제 DB DATA를 LOAD하기 전에 관계설정 정보를 DBMASTER에 할당을 하여야 실제 SQL PARSING할때 그 값을 할당할 수 있습니다.
	// 이부분을 실행하지 않을 경우 SELECT 문의 WHERE절에 NULL값이 할당되어 DB LOAD의 ERROR가 발생합니다.
//	AllocateRelationValueToDBMaster ();

	// 3. 실제 DB Data Load 하기..
	var nSQLIndex = this.getSQLIndex();
	
	var objSelectQuery = g_objPQQuery.getSelectQuery(nSQLIndex);
	
	var strQuery = g_objQueryAtom.getSelectQueryString(objSelectQuery, nSearchOp);
	
	if (false == Utils.isEmpty(strQuery))
	{
		try
		{
			var strModuleKey = PQQuery.getModuleKey(nDBIndex);
			
			strQuery = this.m_objWebScrollPager.searchEnablePage(strQuery, nDBIndex, strModuleKey, this.m_nPageRow);
			
			var objDataTable = g_objDataService.executeOpenX(strQuery, 12, nDBIndex, strModuleKey);
			
			var arVariableList = objSelectQuery.getOutputAtomList();
			if (null != arVariableList || 0 < arVariableList.length)
			{
				this.handleDataTable(objDataTable, arVariableList);
				nLoadSuccess = 1;
			}
		}
		catch (e)
		{
			nResult = 0;
			alert(e.message);
		}
	}
	
	return nLoadSuccess;
}

WebScrollAtom.prototype.handleDataTable = function (objDataTable, arVariableList)
{
	//모두지우기 상태가 설정되어있으면 기존의 스크롤 값을 모두 지우고 새로운 스크롤 값을 반영한다.
	//모두지우기 상태가 설정되는 경우는 
	//1.스크롤.모두지우기() 스크립트가 실행된 경우,
	//2.기본키동작으로 스크롤의 값이 채워진 경우 등이다.
	if (-1 < this.m_nLastValidRowIndex)
	{
		this._deleteAllRow();		// 화면을 비운다.
	}
	
	if (null == objDataTable)
	{
		return;
	}
	
	var arRows = objDataTable.getRowData()
	var nResultLen = arRows.length;
	
	var nLastLen = this.m_arRowList.length;
	this._expandRow(nResultLen - nLastLen);
	
	for (var i = 0; i < nResultLen; i=i+1)
	{
		var arDataRow = arRows[i];
		var objRow = this.m_arRowList[i];
		
		if (null == arDataRow)
			continue;
		
		objRow.setDataValue(arDataRow, arVariableList, Define.NO_OCCUR_EVENT);
	}
	
	this._updateLastValidRowIndex();
	
	// 웹스크롤에 설정할 데이터가 없는 경우에는, clone하기 위해 미리 생성해 놓은 스크롤 Row 조차도 보이지 않게 하기 위해서
	// display 속성을 변경시켜 준다. 스크롤에 묶인 아톰들의 visibility가 각기 다르므로 display를 바꿈
	if (-1 == this.m_nLastValidRowIndex)
	{
		this.m_heAtom.style.display = "none";
	}
	else
	{
		this.m_heAtom.style.display = "block";
	}
	
	if (this.isWebDisplay())
	{
		this._setRowDisplay();
	}
	else if (this.isWebScroll())
	{
		this._handleWebScrollPageDataResult();
	}
}

WebScrollAtom.prototype._handleWebScrollPageDataResult = function ()
{
	var nVisibleRowCount = this._setRowDisplay();
	
	this.setWebScrollWidth(nVisibleRowCount);
	
	// 페이지 컨트롤의 결과를 반영하고 위치를 재설정 한다
	var nHeight = this.m_heAtom.offsetHeight + 14;
	var nWidth = this.m_heAtom.offsetWidth + 14;
	
	if (1 == this.m_nWebScrollType)
	{
		//this.m_objWebScrollButton.handleResult(strTotalPageCount);
		this.m_objWebScrollButton.replacePosition(this.m_nOriginWidth, nVisibleRowCount);
	}
	else
	{
		this.m_objWebScrollPager.handleDataResult();
	}
	
	// 웹 스크롤 아톰의 크기에 연관하여 크기 및 위치가 변하는 아톰의 속성을 변경해 준다
	this._changeAttributeRelationAtom();
}

/**
 * js에서 웹스크롤 조회후 연산식 실행
 */
WebScrollAtom.prototype.executeChangeOperation = function ()
{
	var htBindList = this.m_arRowList[0].m_htBindedAtomList;
	
	for (var strBindVarName in htBindList)
	{
		var objAtom = htBindList[strBindVarName];
		
		if (objAtom instanceof InputDataAtom && objAtom.isRelatedOperation())
		{
			PQOperation.executeScrollChangeOperation(strBindVarName, 0);
		}
	}
}

WebScrollAtom.prototype.handleResult = function (xnAtom, nOccurEventType)
{
	if (null == xnAtom)
	{
		return;
	}
	
	this._handleResult(xnAtom, nOccurEventType);
	
	if (this.isWebDisplay())
	{
		this._handleWebDisplayHandleResult();
	}
	else if (this.isWebScroll())
	{
		this._handleWebScrollPageHandleResult(xnAtom);
	}
}

WebScrollAtom.prototype.getSelectBindedAtomPrefix = function (strVarName)
{
	var objAtom = this.getBindedAtom(strVarName, this.m_nSelectedRowIndex);
	
	if (objAtom.getPrefix)
	{
		return objAtom.getPrefix();
	}
	return "";
}

WebScrollAtom.prototype.getSelectBindedAtomValue = function (strVarName)
{
	var objAtom = this.getBindedAtom(strVarName, this.m_nSelectedRowIndex);
	
	return objAtom.getValue();
}

WebScrollAtom.prototype.getSelectBindedAtomFieldName = function (strVarName)
{
	var objAtom = this.getBindedAtom(strVarName, this.m_nSelectedRowIndex);
	
	return objAtom.getFieldName();
}

/**
 * 스크롤에 묶인 아톰의 모든행의 값을 배열로 리턴 한다.
 */
WebScrollAtom.prototype.getAllBindedAtomValue = function (strVarName)
{
	var arResult = new Array();
	
	for (var i = 0; i < this.m_arRowList.length; i++)
	{
		var objRow = this.m_arRowList[i];
		
		var objAtom = objRow.getBindedAtom(strVarName);
		
		if (null != objAtom)
		{
			var strValue = objAtom.getValue();
			arResult.push(strValue);
		}
	}
	
	return arResult;
}

WebScrollAtom.prototype.init = function ()
{
	this._dropRow();
	this._initRow();
	this._createHtmlRow();
	
	if (this.isWebScroll())
	{
		if (1 == this.m_nWebScrollType)
		{
			this.m_objWebScrollButton.init();
		}
		else
		{
			this.m_objWebScrollPager.init();
		}
	}
	else
	{
		if (null == this.m_objWebScrollPager)
		{
			this.m_objWebScrollPager = new WebAtomPager(this.m_strVarName, 10, false, "#000000");
			this.m_objWebScrollPager.init();
		}
	}
}

// 처음에 아톰 리스트를 만들때만 호출합니다.
WebScrollAtom.prototype.addBindedAtom = function (objAtom)
{
	var objScrollRow = this.m_arRowList[0];
	if (null == objScrollRow)
	{
		objScrollRow = new ScrollRow(this.m_strRowID, 0, true);
		objScrollRow.initItemNum();
		
		this.m_arRowList[0] = objScrollRow;
	}
	
	objScrollRow.addBindedAtom(objAtom);
	
	if (objAtom.isSureInputScroll())
	{	
		this.m_arSureInputWebScrollAtomList.push(objAtom.getVarName());
	}
	
	// 스크립트 엔진에서 아톰 객체를 찾기 위해서 저장함
	if (objAtom.getScriptIndex)
	{
		var nScriptIndex = objAtom.getScriptIndex();
		Model._atomsByIndex[nScriptIndex] = objAtom;
	}
}

/**
 * 스크롤에 묶인 아톰의 값이 변하면 해당 행의 플래그를 바꿉니다.
 */
WebScrollAtom.prototype.modifyRow = function (nRowIndex, nOccurEventType, strBindVarName)
{
	// 데이터 입력란에서는 this.m_nSelectedRowIndex가 onFocus시점에서 설정되어 있습니다.
	// 다른 아톰에서는 this.m_nSelectedRowIndex가 설정되지 않습니다.
	if (0 <= nRowIndex)
	{
		this._modifyRow(this.m_arRowList, nRowIndex, nOccurEventType, strBindVarName);
	}
}

WebScrollAtom.prototype.modifyRowExcludeOperation = function (nRowIndex, nOccurEventType)
{
	// 데이터 입력란에서는 this.m_nSelectedRowIndex가 onFocus시점에서 설정되어 있습니다.
	// 다른 아톰에서는 this.m_nSelectedRowIndex가 설정되지 않습니다.
	if (0 <= nRowIndex)
	{
		this._modifyRowExcludeOperation(this.m_arRowList, nRowIndex, nOccurEventType);
	}
}

/**
 * 서버에 보낼 요청 XML을 만듭니다.
 * 아톰
 * @param xnAtom 스크롤 아톰 값이 추가될 노드
 */
WebScrollAtom.prototype.makeRequest = function (xnAtomRequest)
{
	var xnAtom = XmlLib.createChild(xnAtomRequest, "Scroll");
	
	xnAtom.setAttribute("VarName", this.m_strVarName);
	
	this._makeSureInputScrollInfo(xnAtom);
	
	this._makeBindedAtomInfo(xnAtom);
	
	this._makeRowRequest(xnAtom);
	
	if (this.isWebScroll() || this.isWebDisplay())
	{
		this.m_arDeleteRowList.length = 0;
	}
	else // 일반모델일 때에만 삭제 요청
	{
		this._makeDeleteRowRequest(xnAtom);
	}
	
	if (this.isWebScroll())
	{
		// 페이지 정보
		if (1 == this.m_nWebScrollType)
		{
			this.m_objWebScrollButton.makeRequest(xnAtom);
		}
		else
		{
			this.m_objWebScrollPager.makeRequest(xnAtom);
		}
		
		XmlLib.setAttribute(xnAtom, "WebScrollPage", "Y");
		
		XmlLib.setAttribute(xnAtom, "VisibleRow", this.m_nPageRow);
	}
	
	if (this.isWebDisplay())
	{
		var xnWebBoardPager = XmlLib.createChild(xnAtom, "WebAtomPager");
		XmlLib.setAttribute(xnWebBoardPager, "PageUnit", "1");
		XmlLib.setAttribute(xnWebBoardPager, "CurrentPage", "1");
		XmlLib.setAttribute(xnWebBoardPager, "TotalPageCount", "1");
	
		XmlLib.setAttribute(xnAtom, "WebScrollPage", "Y");
		
		XmlLib.setAttribute(xnAtom, "VisibleRow", this.m_nPageRow);
	}
}

/**
 * 아톰리스트에 추가
 */
WebScrollAtom.prototype.putAtom = function ()
{
	ScrollAtom._atoms[this.m_strVarName] = this;
}

/**
 * 스크롤에 묶인 아톰의 행 번호를 가져 옵니다.
 * 이벤트가 발생되는 시점에만 사용됩니다. 다른 경우에는 사용하면 안됩니다.
 * @param heAtom 발생한 이벤트의 해당 html 객체
 * @return 성공: html 객체가 묶인 스크롤의 행번호 실패 : -1
 */
WebScrollAtom.prototype.getRowIndex = function (heAtom)
{
	if (heAtom && heAtom.parentNode && heAtom.parentNode.id)
	{
		var strRowID = heAtom.parentNode.id;
		var nIndex = strRowID.indexOf("_ScrollRow_");
		if (-1 < nIndex)
		{
			var nLastIndex = strRowID.lastIndexOf("_");
			return this.m_nStartHtmlRowIndex + Utils.parseInt(strRowID.substring(nLastIndex + 1));
		}
	}
	
	return -1;
}


/**
 * 현재 행에서 다음 보여질 행으로 HTML포인터를 이동한다.
 * @param nPagePos 다음 보여질 행번호
 */
WebScrollAtom.prototype.moveHtmlRow = function (nRowPos)
{
	if (0 > nRowPos
		|| this.m_nMaxRow < (nRowPos + this.m_nPageRow)
		|| (null == this.m_arRowList && 0 == this.m_arRowList.length))
	{
		return;
	}
	
	var nDirection = 0;
	
	if (this.m_nStartHtmlRowIndex > nRowPos)
	{
		nDirection = WebScrollAtom.MOVEUP;
	}
	else if (nRowPos > this.m_nStartHtmlRowIndex)
	{
		nDirection = WebScrollAtom.MOVEDOWN;
	}
	
	if (nRowPos == this.m_nStartHtmlRowIndex
		|| (WebScrollAtom.MOVEUP == nDirection && 0 == this.m_nStartHtmlRowIndex))
	{
		return;
	}
	
	if ((WebScrollAtom.MOVEDOWN == nDirection)
		&& (nRowPos + this.m_nPageRow >= this.m_arRowList.length))
	{
		this._expandRow(nRowPos + this.m_nPageRow - (this.m_arRowList.length - 1));
	}
	
	if (WebScrollAtom.MOVEDOWN == nDirection)
	{
		for (var i = this.m_nStartHtmlRowIndex + (this.m_nPageRow-1), j = nRowPos + (this.m_nPageRow-1); i >= this.m_nStartHtmlRowIndex ; i=i-1, j=j-1)
		{
			var objTargetRow = this.m_arRowList[j];
			if (null != objTargetRow)
			{
				objTargetRow.moveHtmlRow(this.m_arRowList[i]);
				objTargetRow.setItemNum(-1);
				
			}
		}
	}
	else if (WebScrollAtom.MOVEUP == nDirection)
	{
		for (var i = this.m_nStartHtmlRowIndex, j = nRowPos, k = this.m_nStartHtmlRowIndex + (this.m_nPageRow-1); i<=k ; i=i+1, j=j+1)
		{
			var objTargetRow = this.m_arRowList[j];
			if (null != objTargetRow)
			{
				objTargetRow.moveHtmlRow(this.m_arRowList[i]);
				objTargetRow.setItemNum(-1);
			}
		}
	}
	
	this.m_nStartHtmlRowIndex = nRowPos;
}

/**
 * 인자로 받은 값만큼 top을 변경시킨다
 * 
 * @param nRepositionValue (top 변경 값)
 */
WebScrollAtom.prototype.repositionYPos = function (nRepositionValue)
{
	var nTop = this.m_heAtom.offsetTop;
	
	this.m_heAtom.style.top = (nTop + nRepositionValue) + "px";
}

/**
 * 인자로 받은 값만큼 left를 변경시킨다
 * 
 * @param nRepositionValue (left 변경 값)
 */
WebScrollAtom.prototype.repositionXPos = function (nRepositionValue)
{
	var nLeft = this.m_heAtom.offsetLeft;
	
	this.m_heAtom.style.left = (nLeft + nRepositionValue) + "px";
}

/**
 * WebDisplay아톰의 display 동작을 멈춘다.
 */
WebScrollAtom.prototype.stopWebDisplay = function ()
{
	if (this.m_objTimer)
	{
		window.clearInterval(this.m_objTimer);
	}
}

/**
 * WebDisplay아톰의 display동작을 다시 시작한다.
 */
WebScrollAtom.prototype.resumeWebDisplay = function ()
{
	if (this.m_objTimer)
	{
		var nInterval = this.m_nInterval;
		this.m_objTimer = window.setInterval("WebScrollAtom.moveEffect('" + this.m_strVarName + "', " + this.m_nEffectType + ")", nInterval);
	}
}

WebScrollAtom.prototype.checkSureInput = function()
{
}

WebScrollAtom.prototype.checkSureInputScroll = function ()
{
}

WebScrollAtom.prototype.onFocus = function (heAtom, objEvent)
{
	this.m_nSelectedRowIndex = this.getRowIndex(heAtom);
	var strVarName = heAtom.id;

	// _초점얻음 스크립트
	if (-1 != ScriptAtomEvent.onFocus(this.m_nScriptIndex, this.m_nSelectedRowIndex, strVarName))
	{
		ScriptAtomEvent.onFocusAfter(this.m_nScriptIndex, this.m_nSelectedRowIndex, strVarName);
	}
}

WebScrollAtom.prototype.onBlur = function (heAtom, objEvent)
{
	this.m_nSelectedRowIndex = this.getRowIndex(heAtom);
	var strVarName = heAtom.id;
	
	// _초점상실 스크립트
	if (-1 != ScriptAtomEvent.onBlur(this.m_nScriptIndex, this.m_nSelectedRowIndex, strVarName))
	{
		ScriptAtomEvent.onBlurAfter(this.m_nScriptIndex, this.m_nSelectedRowIndex, strVarName);
	}
}

WebScrollAtom.prototype.onClick = function (strSelectedAtomVarName, heAtom, objEvent)
{
	this.m_nSelectedRowIndex = this.getRowIndex(heAtom);
	
	//var strVarName = strSelectedAtomVarName;
	
	this.m_strSelectedAtomVarName = strSelectedAtomVarName;
	
	// _누름 스크립트
	if (-1 != ScriptAtomEvent.onClick(this.m_nScriptIndex, 6, this.m_nSelectedRowIndex, this.m_strSelectedAtomVarName))
	{
		ScriptAtomEvent.onClickAfter(this.m_nScriptIndex, this.m_nSelectedRowIndex, this.m_strSelectedAtomVarName);
	}
}

WebScrollAtom.prototype.onDblClick = function (heAtom, objEvent)
{
	this.m_nSelectedRowIndex = this.getRowIndex(heAtom);
	var strVarName = heAtom.id;

	// _두번누름 스크립트
	if (-1 != ScriptAtomEvent.onDblClick(this.m_nScriptIndex, this.m_nSelectedRowIndex, strVarName))
	{
		ScriptAtomEvent.onDblClickAfter(this.m_nScriptIndex, this.m_nSelectedRowIndex, strVarName);
	}
}

/**
 * 선택표시 (f9 기능)
 */
WebScrollAtom.prototype.vanish = function ()
{
	for (var nRowIndex = 0; nRowIndex < this.m_arRowList.length; nRowIndex=nRowIndex+1)
	{
		var objRow = this.m_arRowList[nRowIndex];
		
		objRow.vanish();
	}
}

/**
 * 스크롤의 유효행수를 나타 내어준다.
 * 사각형 그리기 또는 입력란 아톰중에 해당 스크롤 아톰의 변수명을 참조 변수 명으로 
 * 가지고 있는 아톰을 찾아서 행 수를  써준다.
 */
WebScrollAtom.prototype.viewValidRowCount = function ()
{
	var objAtom = ScrollAtom.findCountViewerAtom(this.m_strVarName);
	
	if (null == objAtom)
	{
		return;
	}
	
	objAtom.setValue(this._getValidRowCount().toString());
}

WebScrollAtom.prototype.moveNextRow = function ()
{
	if (this.m_nSelectedRowIndex == this.m_nLastValidRowIndex)
	{
		//스크롤 행을 추가하는것 구현해야함
	}
	
	this.m_nSelectedRowIndex ++;
}

WebScrollAtom.prototype.movePrevRow = function ()
{
	if (0 < this.m_nSelectedRowIndex)
	{
		this.m_nSelectedRowIndex --;
	}
}

WebScrollAtom.prototype.setWebScrollWidth = function (nVisibleRowCount)
{
	var nColumnWidth = Utils.parseInt(this.m_arRowList[0].getHTML().style.width);;
	
	switch (this.m_nWebScrollType)
	{
		case 1: // 스크롤버튼
			this.m_heAtom.style.width = nVisibleRowCount * nColumnWidth + "px";
			break;
		case 2: // 매트릭스
			var nMatrixColumnCount = (nVisibleRowCount < this.m_nColumnCount) ? nVisibleRowCount : this.m_nColumnCount;
			this.m_heAtom.style.width = nMatrixColumnCount * nColumnWidth + "px";
	}
}

WebScrollAtom.prototype.onclickIndex = function (bExecuteSearch)
{
	if (bExecuteSearch)
	{
		this._executeSearch();
	}
}

/**
 * 첫 페이지로 버튼 클릭
 */
WebScrollAtom.prototype.onclickFirstPage = function ()
{
	this._executeSearch();
}

/**
 * 앞 페이지로 버튼 클릭
 */
WebScrollAtom.prototype.onclickPrePage = function ()
{
	this._executeSearch();
}

/**
 * 뒷 페이지로 버튼 클릭
 */
WebScrollAtom.prototype.onclickNextPage = function ()
{
	this._executeSearch();
}

/**
 * 마지막 페이지로 버튼 클릭
 */
WebScrollAtom.prototype.onclickLastPage = function ()
{
	this._executeSearch();
}

/**
 * 페이저의 높이를 구한다.
 * 주의 : 반드시 생성자 함수 안에서만 딱 한번 사용되어야 한다. (그 외에는 사용될 일이 없음.)
 * 생성자 안에서 스크롤의 현재 높이를 재설정해주는 이유
 *  - 페이저가 아톰 내부에 위치해서, 아톰의 높이에까지 영향을 미친다.
 */
WebScrollAtom.prototype._getPagerHeight = function ()
{
	var bTabViewHidden = false;
	var heTabView = this.m_heAtom.parentNode;
	
	// 스크롤이 속해 있는 탭뷰가 숨겨진 상태면 잠시 보이게 한다.
	// 엘리먼트가 보여야 offsetHeight를 알 수 있다.
	if ("TabView" == heTabView.className && "none" == heTabView.style.display)
	{
		bTabViewHidden = true;
		heTabView.style.display = "block";
	}
	
	var nPagerHeight = 0;
	var hePager = document.getElementById("__WEBATOM_PAGECONTROL_" + this.m_strVarName);
		
	if (hePager)
	{
		// 14 는 페이저의 top-margin
		nPagerHeight = hePager.offsetHeight + 14;
	}
	
	// 스크롤이 속해 있는 탭뷰가 숨겨져 있는 상태이면 다시 숨긴다.
	if (bTabViewHidden)
	{
		heTabView.style.display = "none";
	}
	
	return nPagerHeight;
}

/**
 * 스크롤행중 유효한 행의 수를 반환한다.
 * @return nValidRowCount
 */
WebScrollAtom.prototype._getValidRowCount = function ()
{
	var nValidRowCount = 0;

	var arRowList = this.m_arRowList;
	var nLen = this.m_nLastValidRowIndex + 1;
	
	for (var nRowIndex = 0; nRowIndex < nLen; nRowIndex=nRowIndex+1)
	{
		var objRow = arRowList[nRowIndex];
		
		if (null != objRow)
		{
			// 유효한 스크롤 데이터 인가?
			// 하나라도 유효한 행이 있다면 유효!!
			if (this._isValidRow(objRow))
			{
				nValidRowCount = nValidRowCount + 1;
			}
		}
	}

	return nValidRowCount;
}

WebScrollAtom.prototype._isValidRow = function (objRow)
{
	if (null == objRow)
	{
		return false;
	}
	
	return objRow.checkSureInputScroll();
}

/**
 * 스크롤 결과를 처리합니다.
 *
 * 문서열림, 버튼 기능(앞장/뒷장)
 *
 * @param xnAtom 결과 XML
 */
WebScrollAtom.prototype._handleResult = function (xnAtom, nOccurEventType)
{
	var xnDataRowList = XmlLib.selectNodeList(xnAtom, "DataRow");
	if (null == xnDataRowList)
		return;
	
	var arRowList = this.m_arRowList;
	
	var nResultLen = xnDataRowList.length;
	var xnDataRow = null;
	var objRow = null;
	
	//모두지우기 상태가 설정되어있으면 기존의 스크롤 값을 모두 지우고 새로운 스크롤 값을 반영한다.
	//모두지우기 상태가 설정되는 경우는 
	//1.스크롤.모두지우기() 스크립트가 실행된 경우,
	//2.기본키동작으로 스크롤의 값이 채워진 경우 등이다.
	var strDeleteFlag = xnAtom.getAttribute("DeleteAll");
	if ("Y" == strDeleteFlag && 0 < this.m_nLastValidRowIndex)
	{
		this._deleteAllRow();		// 화면을 비운다.
	}
	
	var nLastLen = arRowList.length;
	this._expandRow(nResultLen - nLastLen);
	
	for (var i = 0; i < nResultLen; i=i+1)
	{
		xnDataRow = xnDataRowList[i];
		objRow = arRowList[i];
		
		if (null == objRow)
			continue;
		objRow.setValue(xnDataRow, nOccurEventType);
	}
	
	this._updateLastValidRowIndex();
}

/**
 * 웹 스크롤 아톰 기능에 한정되는 결과 처리를 한다
 * @param xnAtom 결과 
 */
WebScrollAtom.prototype._handleWebScrollPageHandleResult = function (xnAtom)
{
	var nVisibleRowCount = this._setRowDisplay();
	
	this.setWebScrollWidth(nVisibleRowCount);
	
	var xnWebBoardPager = XmlLib.selectSingleNode(xnAtom, "./WebAtomPager");
	
	// 페이지 컨트롤의 결과를 반영하고 위치를 재설정 한다
	var nHeight = this.m_heAtom.offsetHeight + 14;
	var nWidth = this.m_heAtom.offsetWidth + 14;
	
	if (1 == this.m_nWebScrollType)
	{
		var strTotalPageCount = xnWebBoardPager.getAttribute("TotalPageCount");
		
		this.m_objWebScrollButton.handleResult(strTotalPageCount);
		this.m_objWebScrollButton.replacePosition(this.m_nOriginWidth, nVisibleRowCount);
	}
	else
	{
		this.m_objWebScrollPager.handleResult(xnWebBoardPager);
	}
	
	// 웹 스크롤 아톰의 크기에 연관하여 크기 및 위치가 변하는 아톰의 속성을 변경해 준다
	this._changeAttributeRelationAtom();
}

/**
 * 웹 디스플레이 아톰에 추가적인 결과 처리를 한다.
 */
WebScrollAtom.prototype._handleWebDisplayHandleResult = function (xnAtom)
{
	this._setRowDisplay();
}

/**
 * 웹 게시판의 크기 변화에 관계된 아톰들의 위치 및 크기를 변경 한다
 */ 
WebScrollAtom.prototype._changeAttributeRelationAtom = function ()
{
	if (this.m_heAtom)
	{
		var bTabViewHidden = false;
		var heTabView = this.m_heAtom.parentNode;
		
		// 스크롤이 속해 있는 탭뷰가 숨겨진 상태면 잠시 보이게 한다.
		// 엘리먼트가 보여야 offsetHeight를 알 수 있다.
		if ("TabView" == heTabView.className && "none" == heTabView.style.display)
		{
			bTabViewHidden = true;
			heTabView.style.display = "block";
		}
		
		var nResizableValue = this.m_heAtom.offsetHeight - this.m_nWebScrollCurrentHeight;
		
		if (nResizableValue)
		{
			this.m_objResizableObject.commitBoundsStatus(nResizableValue, 0);
			
			this.m_nWebScrollCurrentHeight = this.m_heAtom.offsetHeight;
		}
		
		// 스크롤이 속해 있는 탭뷰가 숨겨져 있는 상태이면 다시 숨긴다.
		if (bTabViewHidden)
		{
			heTabView.style.display = "none";
		}
	}
}

/**
 * 행의 보임 여부를 설정한다 
 * - 웹 스크롤, 웹 디스플레이(문자방송) 아톰 기능
 * - 웹 스크롤, 웹 디스플레이(문자방송)아톰에서는 행에 값이 없는 경우 행을 보이지 않는다
 */
WebScrollAtom.prototype._setRowDisplay = function ()
{
	// 행의 display를 설정한다
	var nLastVisibleIndex = 0;
	for (var i = 0, nLen = this.m_arRowList.length; i < nLen; i++)
	{
		if (this.m_arRowList[i].isEmpty())
		{
			this.m_arRowList[i].setDisplay(false);
		}
		else
		{
			this.m_arRowList[i].setDisplay(true);
			nLastVisibleIndex = i;
		}
	}
	
	// 웹 디스플레이라면 움직임 효과를 준다.
	if (this.isWebDisplay())
	{
		if (this.m_objTimer)
		{
			window.clearInterval(this.m_objTimer);
		}
		
		// 태그가 만들어진 개수보다 데이터가 많으면  
		if (this.m_nPageRow <= nLastVisibleIndex)
		{
			nLastVisibleIndex = this.m_nPageRow - 1;
		}
			
		var heVisibleRow = this.m_arRowList[nLastVisibleIndex].getHTML();
		
		// 상하 스크롤일 때, 상하 슬라이드
		if (0 == this.m_nEffectType || 2 == this.m_nEffectType)
		{
			if (null != heVisibleRow)
			{
				// Marquee부분을 보이는 행까지 높이를 높혀야 한다.
				this.m_heAtom.style.height = heVisibleRow.offsetTop + this.m_nWebScrollCurrentHeight + "px";
			}
			// Marquee부분을 움직이게 한다.
			g_htWebDisplayAtom[this.m_strVarName] = this.m_heAtom;
			g_htWebDisplayOriginSize[this.m_strVarName] = this.m_nWebScrollCurrentHeight;
			g_htWebDisplayMoveCount[this.m_strVarName] = 0;
			
			var nInterval = this.m_nInterval;
			this.m_objTimer = window.setInterval("WebScrollAtom.moveEffect('" + this.m_strVarName + "', " + this.m_nEffectType + ")", nInterval);
		}
		// 좌우 스크롤일 때, 좌우 슬라이드
		else if (1 == this.m_nEffectType || 3 == this.m_nEffectType)
		{
			if (null != heVisibleRow)
			{
				// Marquee부분을 보이는 행까지 넓이를 넓혀야 한다.			
				this.m_heAtom.style.width = heVisibleRow.offsetLeft + this.m_nOriginWidth  + "px";
			}
			// Marquee부분을 움직이게 한다.
			g_htWebDisplayAtom[this.m_strVarName] = this.m_heAtom;
			g_htWebDisplayOriginSize[this.m_strVarName] = this.m_nOriginWidth;
			g_htWebDisplayMoveCount[this.m_strVarName] = 0;
			
			var nInterval = this.m_nInterval;
			this.m_objTimer = window.setInterval("WebScrollAtom.moveEffect('" + this.m_strVarName + "', " + this.m_nEffectType + ")", nInterval);
		}
	}
	
	return ++nLastVisibleIndex;
}

WebScrollAtom.prototype._makeSureInputScrollInfo = function (xnAtom)
{
	var strSureInputWebScrollAtomList = this.m_arSureInputWebScrollAtomList.join(",");
	
	xnAtom.setAttribute("SureInputWebScrollAtomList", strSureInputWebScrollAtomList);
	xnAtom.setAttribute("SelectedRow", this.m_nSelectedRowIndex);
}

/**
 * SQL객체 외부쿼리 실행시 SELECT로 검색된 값을 스크롤에 넣어주기 위해
 * 스크롤에 속한 아톰의 정보를 보내준다.
 */	
WebScrollAtom.prototype._makeBindedAtomInfo = function (xnAtom)
{
	var strVarNameList = "";
	var strAtomTypeList = "";
	
	var objAtomList = this.m_arRowList[0].getBindedAtomList();		
	for (var strKey in objAtomList)
	{
		var objAtom = objAtomList[strKey];
		
		strVarNameList += objAtom.getVarName() + ",";
		
		strAtomTypeList += objAtom.getAtomType() + ",";
	}
	
	xnAtom.setAttribute("VarNameList", strVarNameList.substring(0, strVarNameList.length));
	xnAtom.setAttribute("AtomTypeList", strAtomTypeList.substring(0, strAtomTypeList.length));
	xnAtom.setAttribute("SelectedAtomVarName", this.m_strSelectedAtomVarName);
}

/**
 * 행에 대한 요청 XML을 만듭니다.
 *
 * @param xnAtom 행 값이 추가될 스크롤 아톰 노드 
 */
WebScrollAtom.prototype._makeRowRequest = function (xnAtom)
{
	var arRowList = this.m_arRowList;
	var nLen = this.m_nLastValidRowIndex + 1;
	for (var i = 0; i < nLen; i=i+1)
	{
		var xnRow = XmlLib.createChild(xnAtom, "DataRow");
		
		var objRow = arRowList[i];
		if (null == objRow || objRow.isNone())
		{
			continue;
		}
		
		objRow.makeRequest(xnRow, this.m_strVarName);
	}
}

/**
 * 삭제된 행에 대한 요청 XML을 만듭니다.
 *
 * @param xnAtom 행 값이 추가될 스크롤 아톰 노드
 */
WebScrollAtom.prototype._makeDeleteRowRequest = function (xnAtom)
{
	var xnDeleteRow = XmlLib.createChild(xnAtom, "DeleteRow");
	
	var arDeleteRowList = this.m_arDeleteRowList;
	var nLen = arDeleteRowList.length;
	for (var i = 0; i < nLen; i=i+1)
	{
		var objRow = arDeleteRowList[i];
		
		var xnRow = XmlLib.createChild(xnDeleteRow, "DataRow");
		
		objRow.makeRequest(xnRow, this.m_strVarName);
	}
}

/**
 * 스크롤에 묶인 아톰을 초기화 합니다.
 */	
WebScrollAtom.prototype._initRow = function ()
{
	this.m_arRowList[0].initRow(true);
	this.m_nLastValidRowIndex = -1;
}

/**
 * 현재 가지고 있는 행을 모두 지웁니다.
 */
WebScrollAtom.prototype._dropRow = function ()
{
	var arRowList = this.m_arRowList;
	
	this.moveHtmlRow(0);
	
	var nLen = arRowList.length;
	for (var i = nLen - 1; i > 0; i=i-1)
	{
		this._remove(arRowList, i);
	}
	this.m_arDeleteRowList.length = 0;
}

/*
* 스크롤 초기화시 처음 보여지는 행만큼 html태그에 대응되는 rowList를 만듭니다.
*/
WebScrollAtom.prototype._createHtmlRow = function ()
{
	var arRowList = this.m_arRowList;
	
	// 스크롤버튼형, 매트릭스형은 플로팅모델
	if (1 == this.m_nWebScrollType || 2 == this.m_nWebScrollType)
	{
		var heFirstRow = arRowList[0].getHTML();
		heFirstRow.style.cssFloat = "left";
		heFirstRow.style.styleFloat = "left";
	}
}

/*
* rowList를 생성합니다.
* 표시행수 만큼의 rowList는 html을 가지게 하고, 그 이후의 rowList는 html을 가지지 않습니다.
* @param nCount 생성하고자 하는 행 개수
*/
WebScrollAtom.prototype._expandRow = function (nCount)
{
	if (0 > nCount)
		return;
		
	var arRowList = this.m_arRowList;
	
	var nMakeSize = arRowList.length + nCount;
	if (this.m_nPageRow < nMakeSize)
	{
		nMakeSize = this.m_nPageRow;
	}
	
	for (var i = arRowList.length; i < nMakeSize; i = i+1)
	{
		var objRow = arRowList[arRowList.length - 1];
		var objNewRow = objRow.clone(i, true);
		this._append(arRowList, objNewRow, objRow);
		objNewRow.setHTMLInfo(this.m_strRowID, i);
	}
}

WebScrollAtom.prototype._executeSearch = function ()
{
	if (g_bQWPClientMode)
	{
		this.loadRecord(SQL_RECORD_TYPE.EQUAL_RECORD);
		return;
	}
			
	GlobalField.setServiceName("InquiryAction");
	GlobalField.setServiceEventName("Normal");
	GlobalField.setEventVarName(this.m_strVarName);
	
	var xnRequest = MakeRequest.createRequestNode();
	var xnResultDoc = null;
	try
	{
		MakeRequest.makeServiceRequest(xnRequest);
		
		// 스크롤 DBIO에 필요한 아톰의 요청정보 추가
		//  - 관계설정이 될수 있는 아톰
		//  - 디비처리객체에서 '조건설정'에 사용될 수 있는 아톰
		MakeRequest.makeTouchAtomRequest(xnRequest);
		MakeRequest.makeDecoAtomRequest(xnRequest);
		
		var xnAtomRequest = MakeRequest.getAtomRequestNode(xnRequest);
		
		if (null != xnAtomRequest)
		{
			this.makeRequest(xnAtomRequest);
			
			xnResultDoc = PQService.executeService(xnRequest.ownerDocument);
		}
	}
	catch (e)
	{
		HandleException(e);
		return;
	}
	
	if (null != xnResultDoc && null != xnResultDoc.documentElement)
	{
		var xnScrollList = XmlLib.selectNodeList(xnResultDoc.documentElement, "//Scroll");
		
		for (var i = 0; i < xnScrollList.length; i++)
		{
			if (this.m_strVarName == xnScrollList[i].getAttribute("VarName"))
			{
				this.handleResult(xnScrollList[i], Define.NO_OCCUR_EVENT);
			} 
		}
	}
}

/**
 * 행 수정
 * 일련번호와 Flag를 수정합니다.
 *
 * @param arRowList
 * @param nSelectedRowIndex
 */
WebScrollAtom.prototype._modifyRow = function (arRowList, nSelectedRowIndex, nOccurEventType, strBindVarName)
{
	var objRow = arRowList[nSelectedRowIndex];
	objRow.setSerial(nSelectedRowIndex);
	
	// 행이 유효행이 되면, 외부 아톰 값을 가져오는 연산식을 수행한다.
	var bPrevNone = false;
	if (objRow.isNone())
	{
		bPrevNone = true;
	}
	
	objRow.updateFlag();
	this._updateLastValidRowIndex();
	
	if (bPrevNone)
	{
		// 유효행이 되는 시점에서 한번만 동작한다
		objRow.executeOuterOperation(nSelectedRowIndex);
	}
	
	if (null != strBindVarName || 0 < strBindVarName.length)
	{ 
		objRow.executeChangedOperation(nSelectedRowIndex, strBindVarName);
	}
	
	this.viewValidRowCount();
}

/**
 * 행 수정, 단 연산식을 수행하지 않습니다.
 * 
 * 일련번호와 Flag를 수정합니다.
 *
 * @param arRowList
 * @param nSelectedRowIndex
 */
WebScrollAtom.prototype._modifyRowExcludeOperation = function (arRowList, nSelectedRowIndex, nOccurEventType)
{
	var objRow = arRowList[nSelectedRowIndex];
	objRow.setSerial(nSelectedRowIndex);
	objRow.updateFlag();
	this._updateLastValidRowIndex();
	
	this.viewValidRowCount();
}

/**
 * 모든행을 지운다. (스크롤.모두지우기)
 */
WebScrollAtom.prototype._deleteAllRow = function ()
{
	while (1 < this.m_arRowList.length)
	{
		var objRow = this.m_arRowList.pop();
		this.m_heAtom.removeChild(objRow.getHTML());
	}
	
	this.m_arRowList[0].initRow();
	
	this._setRowInfo(0);
	this._updateLastValidRowIndex();
	this.viewValidRowCount();
}

/**
 * 이벤트가 발생한 행의 다음 모든 행에 대한 행 정보를 설정합니다.
 *
 * @param arRowList 행 리스트
 * @param nIndex 정보 설정 시작 인덱스
 */
WebScrollAtom.prototype._setRowInfo = function (nIndex)
{
	var arRowList = this.m_arRowList;
	var nLen = arRowList.length;
	for (var i = nIndex; i < nLen; i=i+1)
	{
		var objRow = arRowList[i];
		
		if (objRow.isNone())
		{
			continue;
		}
		
		if (this.m_bSerialAutoUpdate)
		{
			objRow.setItemNum(i);
			objRow.setSerial(i);
		
			objRow.updateFlag();
		}
	}
}

/**
 * 추가
 * @param arRowList 행 리스트
 * @param objNewRow 추가할 행
 */
WebScrollAtom.prototype._append = function (arRowList, objNewRow, objRow)
{
	var heNewRow = objNewRow.getHTML();
	
	if (null != heNewRow)
	{
		var hePager = document.getElementById("__WEBATOM_PAGECONTROL_" + this.m_strVarName);
		
		if (hePager &&
			(0 == this.m_nWebScrollType || 2 == this.m_nWebScrollType))
		{
			
			this.m_heAtom.insertBefore(heNewRow, hePager)			
		}
		else
		{
			this.m_heAtom.appendChild(heNewRow);
		}
		
		// 문자방송아톰 : 좌우 스크롤, 좌우 슬라이드 이면 Row를 일렬로 만든다.
		if (1 == this.m_nEffectType || 3 == this.m_nEffectType)
		{
			var objRowHTML = objRow.getHTML();
			
			heNewRow.style.position = "absolute";
			heNewRow.style.top = objRowHTML.offsetTop + "px";
			heNewRow.style.left = objRowHTML.offsetLeft + objRowHTML.offsetWidth  + "px";
		}
	}

	arRowList.push(objNewRow);
}

/**
 * 삽입
 * @param objNewRow 추가할 행
 * @param nIndex 삽입 할 인덱스
 */
WebScrollAtom.prototype._insert = function (objNewRow, nIndex)
{
	this.m_arRowList.splice(nIndex, 0, objNewRow);
	
	//행을 추가 하면 기존의 rowIndex도 바뀌게 되므로 바뀐뒤의 rowIndex기준
	//으로 묶인 모든 아톰의 rowIndex를 재설정한다.	
	for (var i = nIndex, len = this.m_arRowList.length; i < len; i=i+1)
	{
		this.m_arRowList[i].setRowIndex(i);
	}
	//추가한 행의 다음행의 html을 이동시킨다.
	//nIndex = 추가한 행의 index
	//len = 추가한행의 보이는 위치의 가장 마지막 위치
	for (var i = nIndex, len = this.m_nPageRow + this.m_nStartHtmlRowIndex; i <= len ; i=i+1)
	{
		this.m_arRowList[i].moveHtmlRow(this.m_arRowList[i+1]);
		this.m_arRowList[i].setItemNum(-1);
	}
}

/**
 * 삭제
 * @param arRowList 행 리스트
 * @param nIndex 삭제 할 인덱스
 */
WebScrollAtom.prototype._remove = function (arRowList, nIndex)
{
	var objRow = arRowList[nIndex];
	var heAtom = objRow.getHTML();
	if (null != heAtom)
	{
		this.m_heAtom.removeChild(heAtom);
	}
	
	arRowList.splice(nIndex, 1);
}

/**
 * 마지막으로 값을 가지고 있는 행의 인덱스를 찾아서 저장합니다. 
 */
WebScrollAtom.prototype._updateLastValidRowIndex = function ()
{
	var arRowList = this.m_arRowList;
	var nLen = arRowList.length;
	for (var i = 0; i < nLen; i=i+1)
	{
		var objRow = arRowList[i];
		if (!objRow.isNone())
		{
			this.m_nLastValidRowIndex = i;
		}
	}
}

WebScrollAtom.prototype.setValueForExcel = function (xnResult, bOldDataKeep)
{
	var xnDataRowList = XmlLib.selectNodeList(xnResult, "RowData");
	
	if (null == xnDataRowList)
		return;

	var arRowList = this.m_arRowList;
	
	var nResultLen = xnDataRowList.length;
	var xnDataRow = null;
	var objRow = null;
	
	//기존 데이터 보전
	if(false == bOldDataKeep)
	{
		this._initRow();
		this._deleteAllRow();
	}
	
	var nLastLen = arRowList.length;
	if(-1 == this.m_nLastValidRowIndex)
	{
		this._expandRow(nResultLen - nLastLen);
	}
	else
	{
		this._expandRow(nResultLen);
	}
	for (var i = 0; i < nResultLen && nLastLen < this.m_nMaxRow; i=i+1)
	{
		xnDataRow = xnDataRowList[i];
		if(-1 == this.m_nLastValidRowIndex)
		{	
			objRow = arRowList[i];
		}
		else
		{
			objRow = arRowList[nLastLen];
		
		}
		objRow.setFlag("Y");
		if (null == objRow)
			continue;
		objRow.setValueExcel(xnDataRow);
		nLastLen = nLastLen+1;
	}
	
	this._updateLastValidRowIndex();
	
	//연계효과 실행
	this._changeAttributeRelationAtom();

}

WebScrollAtom.prototype.setRowBindedValue = function (nRowIndex, strBindedName, strValue)
{
	var objAtom = this.getBindedAtom(strBindedName, nRowIndex);
	if (null != objAtom)
	{
		objAtom.setValue(strValue);	
	}
}

WebScrollAtom.prototype.action = function (nPropID, arArgs, objRetVal)
{
	switch (nPropID)
	{
		default : return this.getProperty (nPropID, arArgs, objRetVal);
	}
}

WebScrollAtom.prototype.getProperty = function (nNameID, arArgs, objRetVal)
{
	switch (nNameID)
	{
		case 0 : case 203 : return this.get_ScrollProperty (203, arArgs, objRetVal);	
		case 18 : case 374 : return this.get_ScrollProperty (374, arArgs, objRetVal);
		case 15 : case 442 : return this.get_ScrollProperty (442, arArgs, objRetVal);
		default : return StdCore.E_NOT_DEF_PROPERTY;
	}
}

WebScrollAtom.prototype.setProperty = function (nNameID, arArgs, objRetVal)
{
	switch (nNameID)
		{
		case 0 : case 203 : return this.set_ScrollProperty (203, arArgs, objRetVal);
		case 18 : case 374 : return this.set_ScrollProperty (374, arArgs, objRetVal);
		default : return StdCore.E_NOT_DEF_PROPERTY;
	}
}

WebScrollAtom.prototype.get_ScrollProperty = function (nNameID, arArgs, objRetVal)
{
	switch (nNameID)
	{
		case 203 : // 값
		{
			if (null == arArgs || 2 > arArgs.length) 
				return StdCore.E_NOT_MATCH_PARAM_CNT;
			
			var nRowID  = -1;
			var strAtomName = "";
			
			if (arArgs[1].getType() == CVariantX._vtString)
			{  //열, 행
				nRowID  = arArgs[2].toInt ();
				strAtomName	= arArgs[1].toStringX ();
			}
			else 
			{ //행, 열
				nRowID  = arArgs[1].toInt ();
				strAtomName	= arArgs[2].toStringX ();
			}

			nRowID = this.getRealIndex (nRowID);
			nRowID  = (-1 == nRowID) ? nSelRow : nRowID;
			
			var objAtom = this.getBindedAtom(strAtomName, nRowID);
			if (null != objAtom)
			{
				var strData = objAtom.getValue();
				var strType = objAtom.getFieldType();
				
				CVariantX.setReturnValue(strData, objRetVal, strType)
			}
		} break;
		case 374 : // 선택행
			var nReturn = this.getRealReturnIndex(this.m_nSelectedRowIndex);
			objRetVal.setValueType(CVariantX._vtInt, nReturn);
			break;
		case 442 : // 유효행수
			objRetVal.setValueType(CVariantX._vtInt, this._getCountSureInputRow());
			break;
		default : return StdCore.E_NOT_DEF_PROPERTY;
	}
	return StdCore.S_OK;
}

WebScrollAtom.prototype.set_ScrollProperty = function (nNameID, arArgs, objValue)
{
	switch (nNameID)
	{
		case 203: // 값
		{
			if (null == arArgs || 2 > arArgs.length)
			{
				return StdCore.E_NOT_MATCH_PARAM_CNT;
			}
			
			var nRowIndex = -1;
			var strVarName = "";
			
			if (arArgs[1].getType() == CVariantX._vtString)
			{	//열, 행
				nRowIndex = arArgs[2].toInt();
				strVarName	= arArgs[1].toStringX();
			}
			else 
			{	//행, 열
				nRowIndex  = arArgs[1].toInt ();
				strVarName	= arArgs[2].toStringX ();
			}
			
			nRowIndex = this.getRealIndex(nRowIndex);
			nRowIndex = (-1 == nRowIndex) ? 0 : nRowIndex;
			
			var strValue = objValue.toStringX();
			
			var objAtom = this.getBindedAtom(strAtomName, nRowID);
			if (null != objAtom)
			{
				objAtom.setValue(strValue);
			}
			break;
		}
		case 374: // 선택행
			var nSelectRow = objValue.toInt();
			nSelectRow = this.getRealIndex(nSelectRow);
			this.m_nSelectedRowIndex = nSelectRow;
			break;
		case 442: // 유효행수
			break;
		default: return StdCore.E_NOT_DEF_PROPERTY;
	}
	return StdCore.S_OK;
}

WebScrollAtom.prototype.getCellProperty = function (strProperVar, nRow, nPropID, objRetVal, nPropIDEx)
{
	var nResult = StdCore.S_OK;

	if (nPropID == 0 || nPropID == 203)
	{
		var objBindAtom = this.getBindedAtom(strProperVar, nRow);
		if (null != objBindAtom)
		{
			var strData = objBindAtom.getValue();
			CVariantX.setReturnValue(strData, objRetVal, objBindAtom.getFieldType())
		} 
	}
	else if (nPropID == 369)	// 라디오/체크의 속성(체크)를 가져오기 위한 
	{
	}
	else if (nPropID == 483)	// 콤보박스의 속성(선택번호)를 가져오기 위한
	{
	}
	else
	{
	}
	return nResult;
}

//자연어스크립트에서 셀속성변경에 해당하는 사용법 변경으로 별도 함수로 뺌 
WebScrollAtom.prototype.cellPropertyChange = function (strProperVar, nRow, nPropID, objSetVal, objSetVal2)
{
	var nResult = StdCore.S_OK;
	if (nPropID == 0 || nPropID == 203)
	{
		var objBindAtom = this.getBindedAtom(strProperVar, nRow);
		if (null != objBindAtom)
		{
			objBindAtom.setValue(objSetVal.toStringX());
		}
	}
	else if (nPropID == 369)
	{
	}
	else if (nPropID == 483)
	{
	}
	else
	{
		// 행번호-1일때 전체행 속성변경 추가
		var nStartRow = 0, nEndRow = this.m_arRowList.length;
		if (-1 != nRow)
		{
			nStartRow = nRow;
			nEndRow = nRow + 1;
		}
		
		for (var nRowIndex = nStartRow ; nRowIndex < nEndRow ; nRowIndex++)
		{
			var objBindAtom = this.getBindedAtom(strProperVar, nRowIndex);
			
			this.setPropertyTarget(objBindAtom, nPropID, objSetVal, nRowIndex);
		}
	}
	return nResult;
}

WebScrollAtom.prototype.setPropertyTarget = function (objTarget, nPropID, pValue, nScrollRowIndex)
{
	if (-1 == nPropID || null == pValue)
		return StdCore.E_NOT_DEF_PROPERTY;

	if (null == objTarget)
		objTarget = this;

	var nResult = StdCore.S_OK;
	try
	{
		nResult = objTarget.setProperty (nPropID, null , pValue, nScrollRowIndex);
	}
	catch (e)
	{
		nResult = StdCore.E_NOT_DEF_PROPERTY;
	}
	
	return nResult;
}

WebScrollAtom.prototype._getCountSureInputRow = function ()
{
	var nValidRow = 0;

	for (var i = 0; i < this.m_arRowList.length; i+=1)
	{
		var objRow = this.m_arRowList[i];
		
		if (this._isValidRow(objRow))
		{
			nValidRow = i + 1;
		}
	}
	
	return nValidRow;
}

////////////////////////////////////////////////////////////
// static field

WebScrollAtom.MOVEUP = -1; 
WebScrollAtom.MOVEDOWN = 1; 

WebScrollAtom.stopWebDisplay = function (strVarName)
{
	var objWebScrollAtom = ScrollAtom.getAtom(strVarName);
	if (null != objWebScrollAtom)
	{
		objWebScrollAtom.stopWebDisplay();
	}
}

WebScrollAtom.resumeWebDisplay = function (strVarName)
{
	var objWebScrollAtom = ScrollAtom.getAtom(strVarName);
	if (null != objWebScrollAtom)
	{
		objWebScrollAtom.resumeWebDisplay();
	}
}

/**
 * 디스플레이 아톰의 움직임 효과를 담당한다.
 */
WebScrollAtom.moveEffect = function (strVarName, nEffectType)
{
	var heAtom = g_htWebDisplayAtom[strVarName];
	
		var nStopKey = Utils.parseInt(g_htWebDisplayMoveCount[strVarName] / g_htWebDisplayOriginSize[strVarName]);
		
		// 움직여야 할때
		if (nStopKey % 2 == 0)
		{	
			// 상하 스크롤일 때
			if (0 == nEffectType)
			{
				heAtom.style.top = Utils.parseInt(heAtom.style.top) - 1 + "px";
				if (0 > Utils.parseInt(heAtom.style.top) + heAtom.offsetHeight)
				{
					heAtom.style.top = g_htWebDisplayOriginSize[strVarName] + "px";
					g_htWebDisplayMoveCount[strVarName] = 0;
				}
			}
			// 좌우 스크롤일 때
			else if (1 == nEffectType)
			{
				heAtom.style.left = heAtom.offsetLeft - 1 + "px";
				if (0 > heAtom.offsetLeft + heAtom.offsetWidth)
				{
					heAtom.style.left = g_htWebDisplayOriginSize[strVarName] + "px";
					g_htWebDisplayMoveCount[strVarName] = 0;
				}
			}
			// 상하 슬라이드
			else if (2 == nEffectType)
			{
				heAtom.style.top = heAtom.offsetTop - g_htWebDisplayOriginSize[strVarName] + "px";
				if (0 >= heAtom.offsetTop + heAtom.offsetHeight)
				{
					heAtom.style.top = 0 + "px";
					g_htWebDisplayMoveCount[strVarName] = 0;
				}
			}
			// 좌우 슬라이드
			else if (3 == nEffectType)
			{
				heAtom.style.left = heAtom.offsetLeft - g_htWebDisplayOriginSize[strVarName] + "px";
				if (0 >= heAtom.offsetLeft + heAtom.offsetWidth)
				{
					heAtom.style.left = 0 + "px";
					g_htWebDisplayMoveCount[strVarName] = 0;
				}
			}
			
			// MoveCount가 overflow날 수 있기 때문에 2배가 될때 마다 초기화 한다.
			if (2 == nStopKey)
			{
				g_htWebDisplayMoveCount[strVarName] = 0;
			}
			
			// MoveCount를 누적한다.
			g_htWebDisplayMoveCount[strVarName] += 1;
		}
		
		// 멈춰야 할때
		else
		{
			g_htWebDisplayMoveCount[strVarName] += 1;
		}
}

function WebScrollButton (strVarName, // 1
						nPageUnit, // 2
						bShowButtun, // 3
						strFilePrev, // 4
						strFilePrevOver, // 5
						strFileNext, // 6
						strFileNextOver) // 7
{
	this.m_strVarName = strVarName;
	this.m_nPageUnit = nPageUnit;
	this.m_bShowButtun = bShowButtun;
	this.m_strFilePrev = strFilePrev;
	this.m_strFilePrevOver = strFilePrevOver;
	this.m_strFileNext = strFileNext;
	this.m_strFileNextOver = strFileNextOver;
	
	this.m_hePreButton = document.getElementById("__WEBSCROLL_BUTTON_PREV_" + strVarName);
	this.m_heNextButton = document.getElementById("__WEBSCROLL_BUTTON_NEXT_" + strVarName);
	
	this.m_nTotalPageCount = 0;
	this.m_nCurrentPage = 0;
	this.m_objAppliedAtom = null;
	
	this.m_nCurrentVisibleRowCount = 1;
}

WebScrollButton.prototype.init = function ()
{
	this._initButtonEvent();
	this.m_nCurrentPage = 0;
}

/**
 * 해당 버튼 컨트롤을 포함하는 웹아톰을 설정한다
 */
WebScrollButton.prototype.setAppliedAtom = function (objWebAtom)
{
	this.m_objAppliedAtom = objWebAtom;
}

WebScrollButton.prototype.makeRequest = function (xnWebBoardAtom)
{
	var xnWebBoardPager = XmlLib.createChild(xnWebBoardAtom, "WebAtomPager");
	
	XmlLib.setAttribute(xnWebBoardPager, "PageUnit", this.m_nPageUnit);
	XmlLib.setAttribute(xnWebBoardPager, "ShowPager", this.m_bShowButtun ? "Y" : "N");
	XmlLib.setAttribute(xnWebBoardPager, "CurrentPage", this.m_nCurrentPage);
	XmlLib.setAttribute(xnWebBoardPager, "TotalPageCount", this.m_nTotalPageCount);
}

WebScrollButton.prototype.handleResult = function (strTotalPageCount)
{
	try
	{
		var nTotalPageCount = Utils.parseInt(strTotalPageCount);
		
		if (0 < nTotalPageCount)
		{
			this.m_nTotalPageCount = nTotalPageCount;
			this.m_nCurrentPage = 1;
		}
	}
	catch (e)
	{
		e.message = "웹페이지의 전체 페이지 수 결과가 맞지 않습니다 - WebScrollButton";
		alert(e.message);
	}
}

WebScrollButton.prototype.replacePosition = function (nRowWidth, nVisibleRowCount)
{
	var nOffset = nRowWidth * (nVisibleRowCount - this.m_nCurrentVisibleRowCount);
	
	this.m_heNextButton.style.left = this.m_heNextButton.offsetLeft + nOffset + "px";
	
	this.m_nCurrentVisibleRowCount = nVisibleRowCount
}

WebScrollButton.prototype.getFilePrev = function ()
{
	return this.m_strFilePrev;
}

WebScrollButton.prototype.getFilePrevOver = function ()
{
	return this.m_strFilePrevOver;
}

WebScrollButton.prototype.getFileNext = function ()
{
	return this.m_strFileNext;
}

WebScrollButton.prototype.getFileNextOver = function ()
{
	return this.m_strFileNextOver;
}

WebScrollButton.prototype.onclickPrev = function ()
{
	if (this.m_nCurrentPage <= 1)
	{
		return;
	}
	else
	{
		this.m_nCurrentPage -= 1;
	}
	
	// 자신을 포함한 웹아톰으로 이벤트를 넘긴다
	this.m_objAppliedAtom.onclickIndex(true);
}

WebScrollButton.prototype.onclickNext = function ()
{
	if (this.m_nCurrentPage >= this.m_nTotalPageCount)
	{
		return;
	}
	else
	{
		this.m_nCurrentPage	+= 1;
	}
	
	// 자신을 포함한 웹아톰으로 이벤트를 넘긴다
	this.m_objAppliedAtom.onclickIndex(true);
}

WebScrollButton.prototype._initButtonEvent = function ()
{
	var objThis = this;
	
	// 앞페이지 버튼 이벤트
	this.m_hePreButton.onclick = function ()
	{
		objThis.onclickPrev();
	}
	// 다음 버튼 이벤트
	this.m_heNextButton.onclick = function ()
	{
		objThis.onclickNext();
	}
}


/**
 * 페이지 변환 컨트롤러의 스타일 및 인덱스를 관리 한다
 */
function WebAtomPager (strVarName, // 1
					nPageUnit, // 2
					bShowPager, // 3
					strFontColor) // 4
{
	this.m_strVarName = strVarName;
	this.m_nPageUnit = nPageUnit;
	this.m_bShowPager = bShowPager;
	
	// 전체 페이지 행수
	this.m_nTotalPageCount = 0;
	
	// 현재 페이지 인덱스 -- 최초에만 0 이다
	this.m_nCurrentPage = 0;
	
	// 참조 페이지 인덱스, 
	this.m_nRefPage = 0;
	
	this.m_nStartPage = 1;
	
	// 글자 색깔
	this.m_strFontColor = strFontColor;
	
	this.m_objAppliedAtom = null;
	this.insideAtomLayout = true;
	
	// 이동 버튼 활성화 상태
	this.m_bEnableFirst = false;
	this.m_bEnablePrev = false;
	this.m_bEnableNext = false;
	this.m_bEnableLast = false;
	
	this.m_objWebAtomPageQuery = null;
	if (this.m_bShowPager && (is_android || is_iphone))
	{
		document.getElementById("__WEBATOM_PAGECONTROL_PREPAGE_INDEX_" + strVarName).style.fontSize = "12pt";
	}
}

WebAtomPager.prototype.getCurrentPage = function ()
{
	return this.m_nCurrentPage;
}

WebAtomPager.prototype.init = function ()
{
	this.m_nCurrentPage = 0;
	this.m_nStartPage = 1;
	
	if (this.m_bShowPager) // 엘리먼트가 있을 때에만
	{
		this._initButtonFunction();
		this._drawPageIndex();
	}
}

WebAtomPager.prototype.initCurrentPage = function ()
{
	this.m_nCurrentPage = 0;
	this.m_nStartPage = 1;
}

WebAtomPager.prototype.isShowPager = function ()
{
	return this.m_bShowPager;
}

WebAtomPager.prototype.setRefPage = function (nPage)
{
	this.m_nRefPage = nPage;
}

WebAtomPager.prototype.setAtomPageQuery = function (objAtomPageQuery)
{
	this.m_objWebAtomPageQuery = objAtomPageQuery;
}

WebAtomPager.prototype.makeRequest = function (xnWebBoardAtom)
{
	var xnWebBoardPager = XmlLib.createChild(xnWebBoardAtom, "WebAtomPager");
	
	XmlLib.setAttribute(xnWebBoardPager, "PageUnit", this.m_nPageUnit);
	XmlLib.setAttribute(xnWebBoardPager, "CurrentPage", this.m_nCurrentPage);
	XmlLib.setAttribute(xnWebBoardPager, "TotalPageCount", this.m_nTotalPageCount);
	XmlLib.setAttribute(xnWebBoardPager, "RefPage", this.m_nRefPage);
	XmlLib.setAttribute(xnWebBoardPager, "ShowPager", this.m_bShowPager ? "Y" : "N");
	
	if (0 != this.m_nRefPage)
	{
		this.m_nRefPage = 0;
	}
}

WebAtomPager.prototype.handleResult = function (xnPager)
{
	var nTotalPageCount = Utils.parseInt(xnPager.getAttribute("TotalPageCount"));
	var nCurrentPage = Utils.parseInt(xnPager.getAttribute("CurrentPage"));
	
	this.setValue(nTotalPageCount, nCurrentPage);
}

WebAtomPager.prototype.handleDataResult = function ()
{
	this.setValue(this.m_nTotalPageCount, this.m_nCurrentPage);
}

WebAtomPager.prototype.setValue = function (nTotalPageCount, nCurrentPage)
{
	try
	{
		if (nTotalPageCount)
		{
			this.m_nTotalPageCount = nTotalPageCount;
		}
		
		if (nCurrentPage)
		{
			this.m_nCurrentPage = nCurrentPage;
		}
	}
	catch (e)
	{
		e.message = "웹페이지의 전체 페이지 수 결과가 맞지 않습니다 - WebAtomPager.js - handleResult";
		alert(e.message);
	}
	
	if (this.m_bShowPager)
	{
		this._refreshPageIndex();
	}
}

/**
 * 컨트롤의 위치를 다시 지정 합니다
 */
WebAtomPager.prototype.replacePosition = function (nListBottom)
{
	var hePager = document.getElementById("__WEBATOM_PAGECONTROL_" + this.m_strVarName);
	if (null != hePager)
	{
		hePager.style.position = "absolute";
		hePager.style.top = nListBottom + "px";
	}
}

/**
 * 해당 페이지 컨트롤을 포함하는 웹아톰을 설정한다
 */
WebAtomPager.prototype.setAppliedAtom = function (objWebAtom)
{
	this.m_objAppliedAtom = objWebAtom;
}

WebAtomPager.prototype.onclickFirstPage = function()
{
	if (this.m_bEnableFirst)
	{
		this.m_nStartPage = 1;		
		this.m_nCurrentPage = 1;
		
		this.disableButton(WebAtomPager.FIRSTPAGE);
		this.disableButton(WebAtomPager.PREVPAGE);
		this.enableButton(WebAtomPager.NEXTPAGE);
		this.enableButton(WebAtomPager.LASTPAGE);
		
		if (this.m_bShowPager)
		{
			this._refreshPageIndex();
		}
		
		// 자신을 포함한 웹아톰으로 이벤트를 넘긴다
		this.m_objAppliedAtom.onclickFirstPage();
	}
}

WebAtomPager.prototype.onclickPrePage = function ()
{
	if (this.m_bEnablePrev)
	{
		if (0 < this.m_nStartPage - (2 * this.m_nPageUnit))
		{
			this.m_nStartPage -= this.m_nPageUnit;
			this.m_nCurrentPage = this.m_nStartPage;
			
			this.enableButton(WebAtomPager.FIRSTPAGE);
			this.enableButton(WebAtomPager.PREVPAGE);
			this.enableButton(WebAtomPager.NEXTPAGE);
			this.enableButton(WebAtomPager.LASTPAGE);
			
			if (this.m_bShowPager)
			{
				this._refreshPageIndex();
			}
			
			// 자신을 포함한 웹아톰으로 이벤트를 넘긴다
			this.m_objAppliedAtom.onclickPrePage();
		}
		else
		{
			this.onclickFirstPage();
		}
	}
}

WebAtomPager.prototype.onclickNextPage = function ()
{
	if (this.m_bEnableNext)
	{
		if (this.m_nStartPage + (2 * this.m_nPageUnit) <= this.m_nTotalPageCount)
		{
			this.m_nStartPage += this.m_nPageUnit;
			this.m_nCurrentPage = this.m_nStartPage;
			
			this.enableButton(WebAtomPager.FIRSTPAGE);
			this.enableButton(WebAtomPager.PREVPAGE);
			this.enableButton(WebAtomPager.NEXTPAGE);
			this.enableButton(WebAtomPager.LASTPAGE);
			
			if (this.m_bShowPager)
			{
				this._refreshPageIndex();
			}
			
			// 자신을 포함한 웹아톰으로 이벤트를 넘긴다
			this.m_objAppliedAtom.onclickNextPage();
		}
		else
		{
			this.onclickLastPage();
		}
	}
}

WebAtomPager.prototype.onclickLastPage = function ()
{
	if (this.m_bEnableLast)
	{
		var nLastUnit = Math.floor(this.m_nTotalPageCount / this.m_nPageUnit);
		
		this.m_nStartPage = this.m_nPageUnit * nLastUnit + 1;
		this.m_nCurrentPage = this.m_nStartPage;
		
		this.enableButton(WebAtomPager.FIRSTPAGE);
		this.enableButton(WebAtomPager.PREVPAGE);
		this.disableButton(WebAtomPager.NEXTPAGE);
		this.disableButton(WebAtomPager.LASTPAGE);
		
		if (this.m_bShowPager)
		{
			this._refreshPageIndex();
		}
		
		// 자신을 포함한 웹아톰으로 이벤트를 넘긴다
		this.m_objAppliedAtom.onclickLastPage();
	}
}

/**
 * 인덱스 마우스 오버 이벤트
 */
WebAtomPager.prototype.onmouseoverIndex = function (objEvent)
{
	var heIndex = null;
	
	if(is_firefox)
	{
		heIndex = objEvent.target;	
	}
	else
	{ 
		heIndex = window.event.srcElement;
	}
	
	if (!this._isCurrentPage(this._extractIndexFormElement(heIndex)))
	{
		heIndex.style.textDecoration = "underline";
		heIndex.style.color = "blue";
	}
}

/**
 * 인덱스 마우스 아웃 이벤트
 */
WebAtomPager.prototype.onmouseoutIndex = function (objEvent)
{
	var heIndex = null;
	
	if(is_firefox)
	{
		heIndex = objEvent.target;	
	}
	else
	{ 
		heIndex = window.event.srcElement;
	}
	
	if (heIndex)
	{
		heIndex.style.textDecoration = "";
		heIndex.style.color = this.m_strFontColor;
	}
}

/**
 * 인덱스 클릭 이벤트
 * @param objEvent 클릭 이벤트 객체
 * @return bExecute 검색을 실행 할지의 여부
 */
WebAtomPager.prototype.onClickIndex = function (objEvent)
{
	// 선택된 인덱스의 스타일을 변경한다
	var heIndex = null;
	
	if(is_firefox)
	{
		heIndex = objEvent.target;	
	}
	else
	{ 
		heIndex = window.event.srcElement;
	}
	var bExecuteSearch = false;
	
	// 클릭된 인덱스가 현재 인덱스가 다를 경우만 게시판 내용 검색을 실행한다
	if (this.m_nCurrentPage != this._extractIndexFormElement(heIndex))
	{
		if (null != heIndex)
		{
			if (null != this.m_heSelectedIndex)
			{
				this._setDefaultIndexStyle(this.m_heSelectedIndex);
			}
			
			this._setCurrentIndexStyle(heIndex);
			
			this.m_heSelectedIndex = heIndex;
		}
		
		// 선택된 인덱스를 현제 페이지로 설정 한다	
		this.m_nCurrentPage = this._extractIndexFormElement(heIndex);
		
		bExecuteSearch = true;
	}
	
	this.m_objAppliedAtom.onclickIndex(bExecuteSearch);
}

/**
 * index html 요소로부터 인덱스 번호를 뽑아 반환한다
 * @param heIdex
 */
WebAtomPager.prototype._extractIndexFormElement = function (heIndex)
{
	if (null == heIndex)
	{
		return -1;
	}
	
	var strSelectedIndex = heIndex.id;
	
	strSelectedIndex = Utils.replace(strSelectedIndex, "__WEBATOM_PAGECONTROL_INDEX_", "");
	
	return Utils.parseInt(strSelectedIndex);
}

/**
 * 선택된 인덱스 스테알 지정
 * @param nIndex 인덱스 번호
 */
WebAtomPager.prototype._setCurrentIndexStyle = function (heIndex)
{
	if (null != heIndex)
	{
		heIndex.style.cursor = "default";
		heIndex.style.fontWeight = "bold";
		
		heIndex.disabled = true;
	}
}

/**
 * 선택 해재된  인덱스 스테알 지정
 * @param nIndex 인덱스 번호
 */
WebAtomPager.prototype._setDefaultIndexStyle = function (heIndex)
{
	if (null != heIndex)
	{
		heIndex.style.cursor = "hand";
		heIndex.style.fontWeight = "";
		
		heIndex.disabled = false;
	}
}

/**
 * 페이지 인덱스 영역을 새로 고친다
 */
WebAtomPager.prototype._refreshPageIndex = function ()
{
	if (0 == this.m_nCurrentPage)
	{
		this.m_nCurrentPage = 1;
	}

	this._drawPageIndex();
}

/**
 * 페이지 인덱스를 그린다.
 */
WebAtomPager.prototype._drawPageIndex = function ()
{
	var hePageIndex = document.getElementById("__WEBATOM_PAGECONTROL_PREPAGE_INDEX_" + this.m_strVarName);
	
	// 인덱스 삭제
	this._removePagerIndex(hePageIndex);
	
	// 인덱스 새로 생성
	for (var i = this.m_nStartPage; i < this.m_nStartPage + this.m_nPageUnit; i += 1)
	{
		if (this.m_nTotalPageCount < i)
		{
			break;
		}
		
		hePageIndex.appendChild(this._getNewIndexElement(i));	
	}
	
	// 버튼의 활성화/비활성화 세팅 : first, previous
	if (1 < this.m_nStartPage)
	{
		this.enableButton(WebAtomPager.FIRSTPAGE);
		this.enableButton(WebAtomPager.PREVPAGE);
	}
	else
	{
		this.disableButton(WebAtomPager.FIRSTPAGE);
		this.disableButton(WebAtomPager.PREVPAGE);
	}
	
	// 버튼의 활성화/비활성화 세팅 : next, last
	if (this.m_nStartPage + this.m_nPageUnit <= this.m_nTotalPageCount)
	{
		this.enableButton(WebAtomPager.NEXTPAGE);
		this.enableButton(WebAtomPager.LASTPAGE);
	}
	else
	{
		this.disableButton(WebAtomPager.NEXTPAGE);
		this.disableButton(WebAtomPager.LASTPAGE);
	}
}

WebAtomPager.prototype._initButtonFunction = function ()
{
	var objWebAtomPager = this;
	
	var heFirstButton = document.getElementById(WebAtomPager.FIRSTPAGE + this.m_strVarName);
	if (null == heFirstButton.onclick)
	{
		heFirstButton.onclick = function (){ objWebAtomPager.onclickFirstPage() };
	}
	
	var hePrevButton = document.getElementById(WebAtomPager.PREVPAGE + this.m_strVarName);
	if (null == hePrevButton.onclick)
	{
		hePrevButton.onclick = function (){ objWebAtomPager.onclickPrePage() };
	}
	
	var heNextButton = document.getElementById(WebAtomPager.NEXTPAGE + this.m_strVarName);
	if (null == heNextButton.onclick)
	{
		heNextButton.onclick = function (){ objWebAtomPager.onclickNextPage() };
	}
	
	var heLastButton = document.getElementById(WebAtomPager.LASTPAGE + this.m_strVarName);
	if (null == heLastButton.onclick)
	{
		heLastButton.onclick = function (){ objWebAtomPager.onclickLastPage() };
	}
}

/**
 * 페이지 인덱스 삭제
 */
WebAtomPager.prototype._removePagerIndex = function (hePageIndex)
{
	var nLen = hePageIndex.childNodes.length;
	
	for (var i = 0; i < nLen; i++)
	{
		var objLabel = hePageIndex.childNodes[0];
		
		HTMLLib.purge(objLabel);
		
		hePageIndex.removeChild(objLabel);
	}
}

/**
 * 페이지 인덱스 html을 생성하여 페이지 인덱스 표현 영역에 넣는다
 * @param nIndex
 */
WebAtomPager.prototype._getNewIndexElement = function (nIndex)
{
	var objThis = this;
	
	var heIndexElement = document.createElement("label");
	
	heIndexElement.id = "__WEBATOM_PAGECONTROL_INDEX_" + nIndex;
	heIndexElement.innerHTML = nIndex;
	heIndexElement.style.padding = "0px 5px 0px 5px";
	heIndexElement.style.cursor = "hand";
	
	heIndexElement.onmouseover = function (event)
	{
		objThis.onmouseoverIndex(event);
	}
	
	heIndexElement.onmouseout = function (event)
	{
		objThis.onmouseoutIndex(event);
	}
	
	heIndexElement.onclick = function (event)
	{
		objThis.onClickIndex(event);
	}
	
	// 현재 인덱스 선택 표시
	if (this.m_nCurrentPage == nIndex || (0 == this.m_nCurrentPage && 1 == nIndex))
	{
		this.m_heSelectedIndex = heIndexElement;
		this._setCurrentIndexStyle(heIndexElement);
	}
	
	try
	{
		return heIndexElement;
	}
	finally
	{
		heIndexElement = null;
	}
}

WebAtomPager.prototype._isCurrentPage = function (nPageIndex)
{
	if (0 == this.m_nCurrentPage)
	{
		return false;
	}
	
	if (this.m_nCurrentPage == nPageIndex)
	{
		return true;
	}
	
	return false;
}

WebAtomPager.prototype.disableButton = function (strPrefix)
{
	var heButton = document.getElementById(strPrefix + this.m_strVarName);
	heButton.style.cursor = "default";
	
	switch (strPrefix)
	{
		case WebAtomPager.FIRSTPAGE:
			this.m_bEnableFirst = false;
			break;
		case WebAtomPager.PREVPAGE:
			this.m_bEnablePrev = false;
			break;
		case WebAtomPager.NEXTPAGE:
			this.m_bEnableNext = false;
			break;
		case WebAtomPager.LASTPAGE:
			this.m_bEnableLast = false;
			break;
	}
}

WebAtomPager.prototype.enableButton = function (strPrefix)
{
	var heButton = document.getElementById(strPrefix + this.m_strVarName);
	heButton.style.cursor = "pointer";
	
	switch (strPrefix)
	{
		case WebAtomPager.FIRSTPAGE:
			this.m_bEnableFirst = true;
			break;
		case WebAtomPager.PREVPAGE:
			this.m_bEnablePrev = true;
			break;
		case WebAtomPager.NEXTPAGE:
			this.m_bEnableNext = true;
			break;
		case WebAtomPager.LASTPAGE:
			this.m_bEnableLast = true;
			break;
	}
}

WebAtomPager.prototype.searchEnablePageBoard = function (strQuery, nDBIndex, strModuleKey, nPageRow)
{
	var strPageQuery = "";

	var nCurrentPage = this.m_nCurrentPage;
	var nVisibleLineCount = nPageRow;

	if (0 == nCurrentPage)  // 최초검색시
	{
		var nRecordCount = this.m_objWebAtomPageQuery.getRecordCount(strQuery, nDBIndex, strModuleKey);

		var nPageCount = nRecordCount / nVisibleLineCount;
		if (0 < (nRecordCount % nVisibleLineCount))
		{
			nPageCount++;
		}
		
		this.m_nTotalPageCount = nPageCount;
	}

	// 참조 페이지가 0이 아니면 이전폼에서 현재페이지에 대한 참조 값이 넘어온 것이다.
	// 그래서 현재페이지를 변경해준다.
	if (0 != this.m_nRefPage)
	{
		nCurrentPage = this.m_nRefPage;
		this.m_nCurrentPage = nCurrentPage;
	}

	strPageQuery = this.m_objWebAtomPageQuery.getRecordPageQuery(strQuery, nVisibleLineCount, nCurrentPage); // 레코드단위의 쿼리로 변환
	
	return strPageQuery;
}

/**
 * 전체 페이지 숫자를 결과 파람에 저장한다
 */
WebAtomPager.prototype.searchEnablePage = function (strQuery, nDBIndex, strModuleKey, nPageRow) 
{
	var strPageQuery = "";
	var nVisibleLineCount = nPageRow;
	var nCurrentPage = this.m_nCurrentPage;
	
	if (0 == nCurrentPage && this.m_bShowPager) // 최초검색시, 페이져 보일 경우
	{
		var nRecordCount = this.m_objWebAtomPageQuery.getRecordCount(strQuery, nDBIndex, strModuleKey);
		var nPageCount = nRecordCount / nVisibleLineCount;

		if (0 < (nRecordCount % nVisibleLineCount))
		{
			nPageCount++;
		}
		
		this.m_nTotalPageCount = nPageCount;
		this.m_nCurrentPage = 1;
	}

	strPageQuery = this.m_objWebAtomPageQuery.getRecordPageQuery(strQuery, nVisibleLineCount, nCurrentPage); // 레코드단위의 쿼리로 변환

	return strPageQuery;
}

WebAtomPager.FIRSTPAGE = "__WEBATOM_PAGECONTROL_FIRSTPAGE_";
WebAtomPager.PREVPAGE = "__WEBATOM_PAGECONTROL_PREPAGE_";
WebAtomPager.NEXTPAGE = "__WEBATOM_PAGECONTROL_NEXTPAGE_";
WebAtomPager.LASTPAGE = "__WEBATOM_PAGECONTROL_LASTPAGE_";


function WebAtomPageQuery (strPrimary, strReplyItem, arReplyFilter)
{
	this.m_strPrimary = strPrimary;
	this.m_strReplyItem = strReplyItem;
	this.m_arReplyFilter = arReplyFilter;
}

WebAtomPageQuery.prototype.getRecordPageQuery = function (strQueryStatement, nVisibleRow, nCurrentPage)
{
	var strPageSQL = "";
	
	if (DB_KIND._dbOracle == g_nDBKind)
	{
		strPageSQL = this._getRecordPageForOracle(strQueryStatement, nVisibleRow, nCurrentPage);
	}
	else
	{
		strPageSQL = this._getRecordPageForSQL(strQueryStatement, nVisibleRow, nCurrentPage);
	}

	return strPageSQL;
}

/**
 * RecordCount 만큼 값을 받기위한 쿼리를 생성하여 반환한다
 */
WebAtomPageQuery.prototype._getRecordPageQueryStmt = function (strQueryStatement, nRowCount, strOriginQuery)
{
	var strQuery = this._getRecordTopCountQuery(strQueryStatement, nRowCount);
    var strPrimary = this.m_strPrimary;
    
    if (0 < strQuery.length && 0 < strPrimary.length)
    {
        var strReply = this.m_strReplyItem;
        if (null != strReply && 0 < strReply.length)
        {
            strQuery = strQuery + " ORDER BY " + strReply + " DESC";

            var strReplyList = this._getReplyFieldList();
            if (0 < strReplyList.length)
            {
                strQuery = strQuery + ", " + strReplyList;
            }
        }
        else
        {
        	if (-1 == strOriginQuery.indexOf("ORDER BY")) // Order By절이 없을 대에만 붙인다.
        	{
        		strQuery = strQuery + " ORDER BY " + strPrimary + " DESC";
        	}
        }
    }

    return strQuery;
}

WebAtomPageQuery.prototype.getRecordCount = function (strQuery, nDBIndex, strModuleKey)
{
	var nRecordCount = 0;
	var strCountQuery = this._getRecordCountQuery(strQuery);
	
	if (false == Utils.isEmpty(strCountQuery))
	{
		var strCount = g_objDataService.executeOpenScalarX(strCountQuery, 13, nDBIndex, strModuleKey);
		
		if (Utils.isNumber(strCount))
		{
			nRecordCount = Utils.parseInt(strCount);
		}
	}

	return nRecordCount;
}

WebAtomPageQuery.prototype._getRecordCountQuery = function (strQuery)
{
	var strCountQuery = strQuery.replace("\n", " ");
	strCountQuery = strCountQuery.replace ("\r", " "); 
	strCountQuery = strCountQuery.replace ("\t", " ");
	
	// 1. Order By 절을 제거한다..
	strCountQuery = strCountQuery.replace("\\s(?i)ORDER\\s(?i)BY\\s", " ORDER BY ");
	
	var nRevPos = strCountQuery.lastIndexOf (" ORDER BY ");
	if (-1 < nRevPos)
	{
		strCountQuery = strCountQuery.substring(0, nRevPos);
	}

	// 2. 카운트를 구하기 위해서 sql 문장을 만든다...
	strCountQuery = "SELECT COUNT(*) AS RCount FROM (" + strCountQuery + ") tCount";
	strCountQuery = "SELECT SUM(RCount) FROM (" + strCountQuery + ") tSum";

	return strCountQuery;
}

WebAtomPageQuery.prototype._getRecordPageForOracle = function (strQueryStatement, nVisibleRow, nCurrentPage)
{
	if (0 == nCurrentPage)
	{
		nCurrentPage ++;
	}
	
	var strPageQuery = "SELECT * FROM (SELECT QUERY.*, ROWNUM RN FROM (" + strQueryStatement + ") QUERY WHERE ROWNUM <= " 
				+ nCurrentPage * nVisibleRow + ") WHERE RN >= " + (nCurrentPage - 1) * nVisibleRow;
	
	return strPageQuery;
}

WebAtomPageQuery.prototype._getRecordPageForSQL = function (strQueryStatement, nVisibleRow, nCurrentPage)
{
	var strQuery = strQueryStatement;
	var strPageQuery = strQueryStatement.toUpperCase();
	
	if (nCurrentPage <= 1)  // 첫페이지
	{
		strPageQuery = this._getRecordPageQueryStmt(strQuery, nVisibleRow, strQuery);
	}
	else	// 다음페이지
	{
		var strOrderBy = "";
		// 아톰의 정렬필드 속성에 의해 이미 ORDER BY절이 붙어 있다면, 차후에 서브쿼리를 붙이기 위해 떼어놨다가 나중에 다시 붙인다.
		if (-1 < strQuery.indexOf("ORDER BY"))
		{
			strOrderBy = strQuery.substring(strQuery.indexOf("ORDER BY"), strQuery.length);
			strQuery = strQuery.substring(0, strQuery.indexOf("ORDER BY"));
		}
		
		var nRowCount = nVisibleRow * (nCurrentPage - 1);
		
		var strSubQuery = this._getRecordPageSubQuery(strQuery + strOrderBy, nRowCount);
		var strPrimary = this.m_strPrimary;
		
		var strWhere = strPrimary + " NOT IN (" + strSubQuery + ")";
		
		var nFrom  = strQuery.lastIndexOf(" FROM ");
		var nWhere = strQuery.lastIndexOf(" WHERE ");
		if (nFrom < nWhere)
		{
			strWhere = " AND (" + strWhere + ")";
		}
		else
		{
			strWhere = " WHERE " + strWhere;
		}
		
		// Where절을 완성한다.
		strPageQuery = strQuery + strWhere;
		
		// 분리해놨던 ORDER BY절을 다시 붙인다.
		strQuery += strOrderBy;
		strPageQuery += strOrderBy;
		
		strPageQuery = this._getRecordPageQueryStmt(strPageQuery, nVisibleRow, strQuery);
	}
	
	return strPageQuery;
}

 /**
 * SubQuery 에 해당되는 부분 추출
 */
WebAtomPageQuery.prototype._getRecordPageSubQuery = function (strQueryStatement, nRowCount)
{
	var strQuery = strQueryStatement;
    var strTempQuery = strQuery.toUpperCase();

    var strPrimary = this.m_strPrimary;
    var strReplyItem = this.m_strReplyItem;
    var strFrom = "";

    var nFromIndex = strTempQuery.indexOf(" FROM ");
    
    if (0 < nFromIndex)
    {
        strFrom = strTempQuery.substring(nFromIndex + 1);
    }

    var strSubQuery  = "";
    
    if (null != strReplyItem && 0 < strReplyItem.length)
    {
        strSubQuery = "SELECT " + strPrimary + " " + strFrom;
        
        if (-1 == strQuery.indexOf("ORDER BY")) // Order By절이 없을 대에만 붙인다.
        {
        	strSubQuery = strSubQuery + " ORDER BY " + strReplyItem + " DESC";
        }
        
        var strReplyList = this._getReplyFieldList();
        if (0 < strReplyList.length)
        {
            strSubQuery = strSubQuery + ", " + strReplyList;
        }
    }
    else
    {
    	strSubQuery = "SELECT " + strPrimary + " " + strFrom;
        
        if (-1 == strQuery.indexOf("ORDER BY")) // Order By절이 없을 대에만 붙인다.
        {
        	strSubQuery = strSubQuery + " ORDER BY " + strPrimary + " DESC";
        }
    }

    strQuery = this._getRecordTopCountQuery(strSubQuery, nRowCount);

    return strQuery;
}

/**
 * 레코드 수를 받기위한 쿼리를 생성하여 반환한다
 */
WebAtomPageQuery.prototype._getRecordTopCountQuery = function (strQuery, nRowCount)
{
    var StringTopcountQuery = "";
    
    var strTempQuery = strQuery.toUpperCase();
    
    var nSelectIndex = strQuery.toUpperCase().indexOf("SELECT");
    
    if (nSelectIndex == 0)
    {
        strTempQuery = strTempQuery.substring(7); 

        StringTopcountQuery = "SELECT TOP " + nRowCount + " " + strTempQuery;
    }

    return StringTopcountQuery;
}

/***
 * 단계필드
 * @return 단계1 asc, 단계2 asc, 단계3 asc, 단계4 asc, 단계5 asc
 */
WebAtomPageQuery.prototype._getReplyFieldList = function ()
{
    var strReplyItem = "";

    for (var i = 0; i < this.m_arReplyFilter.length; i++)
    {
    	var strReplyField = this.m_arReplyFilter[i]
        if (Utils.isEmpty(strReplyItem))
        {
            strReplyItem = strReplyField + " ASC";
        }
        else
        {
            strReplyItem += ", " + strReplyField + " ASC";
        }
    }

    return strReplyItem;
}


function WebAtomPageQueryEx (strPrimary, strReplyItem, arReplyFilter)
{
	this.m_strPrimary = strPrimary;
	this.m_strReplyItem = strReplyItem;
	this.m_arReplyFilter = arReplyFilter;
	this.m_strDepthItem = arReplyFilter[0];
}

WebAtomPageQueryEx.prototype = new WebAtomPageQuery();
WebAtomPageQueryEx.prototype.constructor = WebAtomPageQueryEx;

WebAtomPageQueryEx.prototype._getRecordPageQueryStmt = function (strQueryStatement, nRowCount, strOriginQuery)
{
	var strQuery = this._getRecordTopCountQuery(strQueryStatement, nRowCount);
    var strPrimary = this.m_strPrimary;
    
    if (0 < strQuery.length && 0 < strPrimary.length)
    {
    	if (0 < this.m_strReplyItem.length && 0 < this.m_strDepthItem.length)
		{
			strQuery += " ORDER BY " + this.m_strReplyItem + " DESC, " + this.m_strDepthItem + " ASC";
		}
		else
		{
			if (-1 == strOriginQuery.indexOf("ORDER BY")) // Order By절이 없을 대에만 붙인다.
        	{
        		strQuery = strQuery + " ORDER BY " + strPrimary + " DESC";
        	}
		}
    }
    
    return strQuery;
}

WebAtomPageQueryEx.prototype._getRecordPageSubQuery = function (strQueryStatement, nRowCount)
{
	var strQuery = strQueryStatement;
    var strTempQuery = strQuery.toUpperCase();
    var strFrom = "";

    var nFromIndex = strTempQuery.indexOf(" FROM ");
    
    if (0 < nFromIndex)
    {
        strFrom = strTempQuery.substring(nFromIndex + 1);
    }

    var strSubQuery  = "";
    
    if (0 < this.m_strReplyItem.length && 0 < this.m_strDepthItem.length)
	{
		strSubQuery = "SELECT " + this.m_strPrimary + " " + strFrom + " ORDER BY " + this.m_strReplyItem + " DESC, " + this.m_strDepthItem + " ASC";
	}
	else
	{
		strSubQuery = "SELECT " + this.m_strPrimary + " " + strFrom;
        
        if (-1 == strQuery.indexOf("ORDER BY")) // Order By절이 없을 대에만 붙인다.
        {
        	strSubQuery = strSubQuery + " ORDER BY " + this.m_strPrimary + " DESC";
        }
	}
	
    strQuery = this._getRecordTopCountQuery(strSubQuery, nRowCount);

    return strQuery;
}


/**
 * 아톰리스트
 */
WebRssAtom._atoms = new Object();

/**
 * @return 아톰명에 해당되는 아톰
 */
WebRssAtom.getAtom = function (strVarName)
{
	return WebRssAtom._atoms[strVarName];
}

/**
 * @param heAtom 발생한 이벤트의 해당 html 객체
 * @return WebRssAtom에 묶인 아톰 아톰
 */
WebRssAtom.getBindedAtom = function (strWebRssAtomVarName, strVarName, heAtom)
{
	if (null == heAtom)
	{
		return null;
	}
	
	var strRowID = heAtom.parentNode.id;
	var nLastIndex = strRowID.lastIndexOf("_");
	var nRowIndex = Utils.parseInt(strRowID.substring(nLastIndex + 1));
	
	var objWebRssAtom = WebRssAtom.getAtom(strWebRssAtomVarName);
	
	return objWebRssAtom.getBindedAtom(strVarName, nRowIndex);
}

/**
 * 초기화
 */
WebRssAtom.init = function ()
{
	for (var strVarName in WebRssAtom._atoms)
	{
		var objAtom = WebRssAtom._atoms[strVarName];
		
		objAtom.init();
	}
}

/**
 * 요청정보 만들기
 */
WebRssAtom.makeRequest = function (xnRequest)
{
	for (var strVarName in WebRssAtom._atoms)
	{
		var objAtom = WebRssAtom._atoms[strVarName];
		
		objAtom.makeRequest(xnRequest);
	}
}

/**
 * RSS reader 객체
 */
function WebRssAtom (strVarName, // 1
					strURL, // 2
					nPageRow, // 3
					bShowPager, // 4
					objPager, // 5
					objResizableObject) // 6
{
	this.m_strVarName = strVarName;
	this.m_strURL = strURL;
	this.m_nPageRow = nPageRow;
	this.m_bShowPager = bShowPager;
	this.m_objPager = objPager;
	this.m_objResizableObject = objResizableObject;
	
	this.m_arRow = new Array(); // 행 목록
	this.m_heAtom = document.getElementById(strVarName);
	this.m_strLastPubDate = ""; // rss 문서가 만들어진 시간
	this.m_xlValue;
	
	// 첫 행 설정
	this.m_arRow.push(new WebRssRow(strVarName, 0));
	
	this.m_nCurrentHeight = this.m_heAtom.offsetHeight;
}

/**
 * 묶인 아톰목록 추가
 */
WebRssAtom.prototype.addBindedAtom = function (objAtom)
{
	this.m_arRow[0].addBindedAtom(objAtom);
}

WebRssAtom.prototype.getBindedAtom = function (strVarName, nRowIndex)
{
	return this.m_arRow[nRowIndex].getBindedAtom(strVarName);
}

/**
 * rss 를 불러온다.
 * RSS 데이터를 서블릿으로 로드하는 이유 : 동일 출처 보안 정책 때문
 * JavaScript 의 보안정책 : 자신이 사용되는 문서를 다운로드한 서버에 대해서만 HTTP 요청을 보낼 수 있다.
 */
WebRssAtom.prototype.getRSS = function ()
{
	var strURL = "/ups/GetFeed.do?ServiceName=WebRssAtom&URL=" + Utils.replace(Utils.encodeBase64(this.m_strURL), "\\+", "-");
	var strRSS = "";
	
	try
	{
		strRSS = PQAjax.post(strURL, "");
	}
	catch (e)
	{
		alert("rss load failed");
	}
	
	return XmlLib.loadXMLFromString(strRSS);
}

/**
 * 초기화
 */
WebRssAtom.prototype.init = function ()
{
	this.m_arRow.length = 1;
	this.m_arRow[0].clear();
	this.m_objPager.init();
}

/**
 * 요청정보 만들기
 */
WebRssAtom.prototype.handleResult = function (xnAtom, nOccurEventType)
{
	// 결과처리는 setValue () 전에 한다.
	
	var xnRSS = this.getRSS();
	var xnChannel = XmlLib.selectSingleNode(xnRSS, "rss/channel");
	var strPubDate = XmlLib.getTextValue(XmlLib.selectSingleNode(xnChannel, "pubDate"));
	
	// 최신버전인지를 알아내서 비교하는 기능 필요
	// if (최신버전이면)
	//{
		// RSS 출판 날짜 변경
		this.m_strLastPubDate = strPubDate;
		
		// 값을 바꾼다.
		this.m_xlValue = XmlLib.selectNodeList(xnChannel, "item");
		
		// 페이저 갱신
		var nTotalPageCount = Utils.parseInt(this.m_xlValue.length / this.m_nPageRow);
		if (0 < this.m_xlValue.length % this.m_nPageRow)
		{
			nTotalPageCount += 1;
		}
		
		this.m_objPager.setValue(nTotalPageCount);
		
		// 새로 고침
		this.refreshPage(nOccurEventType);
	//}
	
	this.setBoundsStatus();	// 연계효과
}

/**
 * 요청정보 만들기
 */
WebRssAtom.prototype.makeRequest = function (xnRequest)
{
	var xnWebRssAtom = XmlLib.createChild(xnRequest, "WebRssAtom");
	
	xnWebRssAtom.setAttribute("VarName", this.m_strVarName);
	xnWebRssAtom.setAttribute("URI", this.m_strURL);
	xnWebRssAtom.setAttribute("MaxRow", this.m_nPageRow);
}

/**
 * 아톰리스트에 추가
 */
WebRssAtom.prototype.putAtom = function ()
{
	WebRssAtom._atoms[this.m_strVarName] = this;
}

WebRssAtom.prototype.setBoundsStatus = function ()  
{  
	var nResizeHeight = this.m_heAtom.offsetHeight - this.m_nCurrentHeight;  
	this.m_objResizableObject.commitBoundsStatus(nResizeHeight, 0);  
	this.m_nCurrentHeight = this.m_heAtom.offsetHeight;  
}

WebRssAtom.prototype.onclickIndex = function (bChange)
{
	if (bChange)
	{
		this.refreshPage();
	}
}

WebRssAtom.prototype.onclickFirstPage = function ()
{
	this.refreshPage();
}

WebRssAtom.prototype.onclickPrePage = function ()
{
	this.refreshPage();
}

WebRssAtom.prototype.onclickNextPage = function ()
{
	this.refreshPage();
}

WebRssAtom.prototype.onclickLastPage = function ()
{
	this.refreshPage();
}

/**
 * 화면 갱신
 */
WebRssAtom.prototype.refreshPage = function (nOccurEventType)
{
	// display 할 값 추출
	var nCurrentPage = this.m_objPager.getCurrentPage();
	var beginIndex = (nCurrentPage - 1) * this.m_nPageRow;
	var endIndex = nCurrentPage * this.m_nPageRow;
	var arDisplay = new Array();
	
	for (var i = beginIndex; i < endIndex && i < this.m_xlValue.length; i += 1)
	{
		arDisplay.push(this.m_xlValue[i]);
	}
	
	// display 할 값이 있으면
	if (arDisplay.length)
	{
		// display 할 데이터의 개수가 현재 생성되어 있는 엘리먼트 수보다 적으면
		if (arDisplay.length < this.m_arRow.length)
		{
			for (var i = 0; i < this.m_arRow.length - arDisplay.length; i += 1)
			{
				var objRow = this.m_arRow.pop();
				this.m_heAtom.removeChild(objRow.getHTMLElement());
			}
		}
		// display 할 데이터의 개수가 현재 생성되어 있는 엘리먼트 수보다 많으면
		else if (arDisplay.length > this.m_arRow.length)
		{
			for (var i = this.m_arRow.length; i < arDisplay.length; i += 1)
			{
				var objRow = this.m_arRow[0].clone(i);
				this.m_arRow.push(objRow);
			}
		}
		
		// 값 display
		for (var i = 0; i < this.m_arRow.length; i += 1)
		{
			this.m_arRow[i].setValue(arDisplay[i], nOccurEventType);
		}
	}
}

WebRssRow.ID = "__WEBRSSATOM_ROW_";

/**
 * RSS 행
 */
function WebRssRow (strRSSName, nIndex)
{
	this.m_strRSSName = strRSSName;
	this.m_nIndex = nIndex;
	
	this.m_htBindedAtomList = new Object(); // 묶인 아톰 목록
	this.m_heRow = document.getElementById(strRSSName + WebRssRow.ID + nIndex);
}

/**
 * 묶인 아톰 추가
 */
WebRssRow.prototype.addBindedAtom = function (objAtom)
{
	var heAtom = objAtom.getHTML();
	if (heAtom)
	{
		this.m_heRow.appendChild(heAtom);
	}
	
	this.m_htBindedAtomList[objAtom.getVarName()] = objAtom;
}

/**
 * 묶인 아톰들의 값 clear
 */
WebRssRow.prototype.clear = function ()
{
	for (var strVarName in this.m_htBindedAtomList)
	{
		var objAtom = this.m_htBindedAtomList[strVarName];
		var strAtomType = objAtom.getAtomType();
		
		if ("RectangleAtom" == strAtomType)
		{
			continue;
		}
		
		this.m_htBindedAtomList[strVarName].clear();
	}
}

/**
 * clone
 */
WebRssRow.prototype.clone = function (nIndex)
{
	var strAtomVarName = this.m_heRow.id.substring(0, this.m_heRow.id.indexOf("__"));
	var heRow = this.m_heRow.cloneNode(false);
	heRow.id = strAtomVarName + WebRssRow.ID + (nIndex);
	this.m_heRow.parentNode.insertBefore(heRow, this.m_heRow.parentNode.lastChild);
	
	var objRow = new WebRssRow(strAtomVarName, nIndex);
	
	for (var strBindedAtomVarName in this.m_htBindedAtomList)
	{
		var objBindedAtom = this.m_htBindedAtomList[strBindedAtomVarName].clone(true);
		
		objBindedAtom.init();
		objRow.addBindedAtom(objBindedAtom);
	}
	
	return objRow;
}

WebRssRow.prototype.getBindedAtom = function (strVarName)
{
	if (strVarName in this.m_htBindedAtomList)
	{
		return this.m_htBindedAtomList[strVarName];
	}
}

/**
 * @param strVarName 찾을 엘리먼틔 id
 * @param objRow 찾을 범위
 * @return strVarName에 해당되는 Element
 */
WebRssRow.prototype.getElementByVarName = function (strVarName, objRow)
{
	for (var i = 0; i < objRow.childNodes.length; i += 1)
	{
		var heNode = objRow.childNodes[i];
		
		if (heNode.id == strVarName)
		{
			return heNode;
		}
	}
}

/**
 * @return 행에 바인딩 되어 있는 엘리먼트
 */
WebRssRow.prototype.getHTMLElement = function ()
{
	return this.m_heRow;
}

/**
 * @return 행에 바인딩 되어 있는 엘리먼트
 */
WebRssRow.prototype.setValue = function (xnValue, nOccurEventType)
{
	this.clear();
	
	for (var strVarName in this.m_htBindedAtomList)
	{
		var objAtom = this.m_htBindedAtomList[strVarName];
		var strAtomType = objAtom.getAtomType();
		
		if ("RectangleAtom" == strAtomType)
		{
			continue;
		}
		
		var strValue = XmlLib.getTextValue(XmlLib.selectSingleNode(xnValue, strVarName));
		this.m_htBindedAtomList[strVarName].setValue(strValue, nOccurEventType);
	}
}

