#include "StdAfx.h"
#include "QuestSimpleWindow.h"
#include "PlaneObject.h"

#include "QuestManager.h"
#include "GameResourceManager.h"
#include "ItemManager.h"
#include "FontAgent.h"

#include "PVPManager.h"

cQuestSimpleWindow::cQuestSimpleWindow()
: mpHighImage(0)
, mpLowImage(0)
, mHighCheckPos(0, 0)
, mHighNoCheckPos(0, 0)
, mLowCheckPos(0, 0)
, mImageSize(0, 0)
, mInitWidth(0)
, mInitX(0)
{
	memset( mpBackImage, 0, sizeof(mpBackImage) );
	memset( mpBackSkin, 0, sizeof(mpBackSkin) );
}

cQuestSimpleWindow::~cQuestSimpleWindow()
{
	for( int i = 0; i < eBACKIMAGE_MAX; ++i )
		SAFE_DELETE( mpBackImage[i] );

	SAFE_DELETE( mpLowImage );
	SAFE_DELETE( mpHighImage );

	Clear();
}

void cQuestSimpleWindow::Clear()
{
	/// 클리어
	typedef tPointerList<void*> cProgressList;

	cQuestMap::cIterator i = mQuestMap.Begin();
	cQuestMap::cIterator end = mQuestMap.End();
	for( ; i != end; ++i )
	{
		sQuestHaveData* data = (sQuestHaveData*)(i->mSecond);
		if( data )
		{
			cProgressList::cIterator b = data->mQuestProgressList.Begin();
			cProgressList::cIterator bend = data->mQuestProgressList.End();
			for( ; b != bend; ++b )
			{
				sQuestProgress* progress = (sQuestProgress*)(*b);
				SAFE_DELETE( progress );
			}
			data->mQuestProgressList.Clear();
		}

		SAFE_DELETE( data );
	}
	mQuestMap.Clear();
}

void cQuestSimpleWindow::ShowTop(bool hideOthers , bool onsound )
{
	if( PVPMAN->IsEnableBattle() == true )
		return;

	cUIWindow::ShowTop( hideOthers, onsound );
}

void cQuestSimpleWindow::UpdateSkin()
{
	cUIWindow::UpdateSkin();

	int x = GetScreenWidth() - GetAbsoluteRect().GetWidth() - mInitX;
	int y = GetAbsoluteRect().mTop;
	SetRelativePos( cUIPos(x, y) );

	UpdateSize();
}

bool cQuestSimpleWindow::OnCreate( cUINodeProperty* pproperty )
{
	if( cUIWindow::OnCreate( pproperty ) == false )
		return false;

	/// 다른윈도우와 스냅 적용 안하도록 함
	SetExceptSnap( true );

	/// 이미지 생성
	cUISkin* pSkin = UIMAN->GetSkin();
	if( !pSkin )
	{
		assert(0);
		return false;
	}

	cUINodeSkin* pHighSkin = pSkin->GetNodeSkin( "Quest_FolderHigh" );
	cUINodeSkin* pHighNoSkin = pSkin->GetNodeSkin( "Quest_FolderHighNoCheck" );
	if( pHighSkin && pHighNoSkin )
	{
		mpHighImage = new cUIImage( pHighSkin->mpTexture );

		mHighNoCheckPos.mX = pHighSkin->mSkinInfo->mTexX;
		mHighNoCheckPos.mY = pHighSkin->mSkinInfo->mTexY;
		unsigned int w = pHighSkin->mSkinInfo->mWidth;
		unsigned int h = pHighSkin->mSkinInfo->mHeight;
		unsigned int x = pHighSkin->mSkinInfo->mX;
		unsigned int y = pHighSkin->mSkinInfo->mY;

		mpHighImage->SetTextureRect( mHighCheckPos.mX, mHighCheckPos.mY, mHighCheckPos.mX + w, mHighCheckPos.mY + h );
		mpHighImage->SetScreenRect( cUIRect( x, y, x + w, y + h ) );

		mHighCheckPos.mX = pHighNoSkin->mSkinInfo->mTexX;
		mHighCheckPos.mY = pHighNoSkin->mSkinInfo->mTexY;

		mImageSize.mWidth = w;
		mImageSize.mHeight = h;
	}

	cUINodeSkin* pLowSkin = pSkin->GetNodeSkin( "Quest_FolderLow" );
	if( pLowSkin )
	{
		mpLowImage = new cUIImage( pLowSkin->mpTexture );

		mLowCheckPos.mX = pLowSkin->mSkinInfo->mTexX;
		mLowCheckPos.mY = pLowSkin->mSkinInfo->mTexY;
		unsigned int w = pLowSkin->mSkinInfo->mWidth;
		unsigned int h = pLowSkin->mSkinInfo->mHeight;
		unsigned int x = pLowSkin->mSkinInfo->mX;
		unsigned int y = pLowSkin->mSkinInfo->mY;

		mpLowImage->SetTextureRect( mLowCheckPos.mX, mLowCheckPos.mY, mLowCheckPos.mX + w, mLowCheckPos.mY + h );
		mpLowImage->SetScreenRect( cUIRect( x, y, x + w, y + h ) );
	}
	
	/// 배경 이미지 생성
	mpBackSkin[eBACKIMAGE_TOP] = pSkin->GetNodeSkin( "QuestSimple_Top" );
	mpBackSkin[eBACKIMAGE_BOTTOM] = pSkin->GetNodeSkin( "QuestSimple_Bottom" );
	mpBackSkin[eBACKIMAGE_CENTER] = pSkin->GetNodeSkin( "QuestSimple_Back" );
	mpBackSkin[eBACKIMAGE_LEFT] = pSkin->GetNodeSkin( "QuestSimple_Left" );
	mpBackSkin[eBACKIMAGE_RIGHT] = pSkin->GetNodeSkin( "QuestSimple_Right" );

	for( int i = 0; i < eBACKIMAGE_MAX; ++i )
	{
		if( mpBackSkin[i] && mpBackSkin[i]->mpTexture )
		{
			/// 텍스처 영역 설정
			unsigned short tx = (unsigned short)mpBackSkin[i]->mSkinInfo->mTexX;
			unsigned short ty = (unsigned short)mpBackSkin[i]->mSkinInfo->mTexY;
			unsigned short tw = (unsigned short)mpBackSkin[i]->mSkinInfo->mTexWidth;
			unsigned short th = (unsigned short)mpBackSkin[i]->mSkinInfo->mTexHeight;
			unsigned int x = GetAbsoluteRect().mLeft;
			unsigned int y = GetAbsoluteRect().mTop;

			mpBackImage[i] = new cPlaneObject;

			if( mpBackImage[i]->Create( mpBackSkin[i]->mpTexture, x, y, x+1, y+1, tx, ty, tx + tw, ty + th ) == false )
			{
				assert( 0 && "failed to create back image");
				return false;
			}
		}
	}

	mInitWidth = mAbsoluteRect.GetWidth();
	cUINodeSkin* winSkin = pSkin->GetNodeSkin( mSkinName );
	if( winSkin )
		mInitX = winSkin->mSkinInfo->mX;

	int x = GetScreenWidth() - GetAbsoluteRect().GetWidth() - mInitX;
	int y = GetAbsoluteRect().mTop;
	SetRelativePos( cUIPos(x, y) );
	return true;
}

void cQuestSimpleWindow::UpdateRect()
{
	cUIWindow::UpdateRect();

	if( mQuestMap.GetSize() > 0 )
	{
		/// 윈도우 사이즈 설정
		int x = GetAbsoluteRect().mLeft;
		int y = GetAbsoluteRect().mTop;

		/// 이미지 설정
		if( mpBackImage[eBACKIMAGE_TOP] )
		{
			int skinHeight = mpBackSkin[eBACKIMAGE_TOP]->mSkinInfo->mHeight;
			mpBackImage[eBACKIMAGE_TOP]->SetScreenXY( x, y );
		}
		if( mpBackImage[eBACKIMAGE_CENTER] )
		{
			mpBackImage[eBACKIMAGE_CENTER]->SetScreenXY( x + START_GAPX, y + START_GAPY );
		}
		if( mpBackImage[eBACKIMAGE_BOTTOM] )
		{
			int backHeight = GetAbsoluteRect().GetHeight() - ( 2 * START_GAPY );
			mpBackImage[eBACKIMAGE_BOTTOM]->SetScreenXY( x, y + backHeight + START_GAPY );
		}
		if( mpBackImage[eBACKIMAGE_LEFT] )
		{
			mpBackImage[eBACKIMAGE_LEFT]->SetScreenXY( x, y + START_GAPY );
		}
		if( mpBackImage[eBACKIMAGE_RIGHT] )
		{
			mpBackImage[eBACKIMAGE_RIGHT]->SetScreenXY( x + START_GAPX + mInitWidth, y + START_GAPY );
		}
	}
}

void cQuestSimpleWindow::OnRender( cUIFontItemKeeper* pKeeper )
{
	if( mVisible == false )
		return;

	/// 데이터 출력
	if( mQuestMap.GetSize() == 0 )
		return;

	/// 이미지 렌더링
	for( int i = 0; i < eBACKIMAGE_MAX; ++i )
	{
		if( mpBackImage[i] )
			mpBackImage[i]->Draw();
	}

	int textposX = GetAbsoluteRect().mLeft + START_GAPX;
	int textPosY = GetAbsoluteRect().mTop + START_GAPY;
	int rowHeight = FONTAGENT->GetTextHeight( cFontAgent::eFont_UI );
	
	typedef tPointerList<void*> cProgressList;

	/// 출력
	cQuestMap::cIterator b = mQuestMap.Begin();
	cQuestMap::cIterator end = mQuestMap.End();
	for( ; b != end; ++b )
	{
		sQuestHaveData* data = (sQuestHaveData*)(b->mSecond);
		if( !data )
		{
			assert(0);
			return;
		}

		int addX = 0;
		if( data->mCloseImage )
		{
			/// 이미지 텍스쳐 좌표 세팅
			cUIPos texPos = ( data->mClose == false ) ? mHighCheckPos : mHighNoCheckPos;
			data->mCloseImage->SetTextureRect( cUIRect( texPos.mX, texPos.mY,texPos.mX + data->mCloseImage->GetWidth(), texPos.mY + data->mCloseImage->GetHeight() ) );
			data->mCloseImage->SetPos( textposX, textPosY );
			data->mCloseImage->Draw();

			addX = (data->mCloseImage->GetWidth() + 2);
		}

		/// 현재 가진갯수 / 총 갯수 출력
		int have = data->mQuestProgressList.GetSize();

		TCHAR temp[128] = {0,};
		::_stprintf( temp, GAMERESOURCEMAN->GetGameText(446), (LPTSTR)data->mMapName.Cstr(), have, data->mTotalCount );

		/// 맵 이름 출력
		pKeeper->AddFontItem( cFontAgent::eFont_UI, temp, textposX + addX, textPosY, eCOLOR_YELLOW );
		textPosY += rowHeight;

		/// 펼쳐져 있으면 퀘스트 리스트 출력
		if( data->mClose == false )
		{
			addX = 0;

			cProgressList::cIterator b = data->mQuestProgressList.Begin();
			cProgressList::cIterator bend = data->mQuestProgressList.End();
			for( ; b != bend; ++b )
			{
				sQuestProgress* progress = (sQuestProgress*)(*b);
				if( !progress )
				{
					assert(0);
					return;
				}
				
				/// 체크 안되있으면 리스트에 출력 자체를 안함
				if( progress->mCloseImage && progress->mClose == false )
				{
					/// 이미지 텍스쳐 좌표 세팅
					cUIPos texPos = mLowCheckPos;
					progress->mCloseImage->SetTextureRect( cUIRect( texPos.mX, texPos.mY,texPos.mX + progress->mCloseImage->GetWidth(), texPos.mY + progress->mCloseImage->GetHeight() ) );
					progress->mCloseImage->SetPos( textposX, textPosY );
					progress->mCloseImage->Draw();

					addX = (progress->mCloseImage->GetWidth() + 2);
				}

				/// 퀘스트 이름 출력
				pKeeper->AddFontItem( cFontAgent::eFont_UI, (LPTSTR)progress->mQuestName.Cstr(), textposX + addX, textPosY, eCOLOR_GREEN );
				textPosY += rowHeight;

				/// 퀘스트 의무조건출력
				if( progress->mClose == false && progress->mDefine )
				{
					/// 1. 시간 제한 출력
					cQuestDefine* define = progress->mDefine;
					cQuestLimit* limit = define->mQuestLimit;
					if( limit && limit->mTime > 0 )
					{
						long restTime = QUESTMAN->GetQuestRestTime( progress->mIndex );
						int time = (int)(restTime*0.001);
						if( time >= 0 )
						{
							int h = time / 3600;
							int m = time / 60;
							int s = time % 60;

							cStringT th,tm,ts;
							if( h != 0 )
								th.Format(_T("%d시"), h );

							if( m != 0 )
								tm.Format(_T("%d분"), m );
							ts.Format(_T("%d초"), s );

							th = (th+tm+ts);

							cStringT timeStr;
							timeStr.Format( GAMERESOURCEMAN->GetGameText( 471 ), (LPCTSTR)th.Cstr() );

							pKeeper->AddFontItem( cFontAgent::eFont_UI, (LPCTSTR)timeStr.Cstr(), textposX + addX, textPosY, eCOLOR_ORANGE );
							textPosY += rowHeight;
						}
					}

					/// 2. 의무조건 상세 표현
					cQuestDuty* duty = define->mQuestDuty;
					if( duty )
					{
						cStringT str;

						__int64 end = 0xFF;
						__int64 check = *progress->mCheck;	/// 참조

						for( unsigned int i = 0; i < MAX_DUTY; ++i )
						{
							eDutyType type = duty->mDuty[i].dutyType;
							unsigned long targetIdx = duty->mDuty[i].targetIdx;
							unsigned int count = duty->mDuty[i].count;

							if( type == eDUTY_NONE )
								break;

							/// 정보 출력
							switch( type )
							{
							case eDUTY_HUNT:		/// 사냥
								{
									LPCTSTR monName = GAMERESOURCEMAN->GetMonsterName( targetIdx );
									str.Format( GAMERESOURCEMAN->GetGameText( 451 ), monName, count );

									/// 완료
									if( (check & end) >= (define->mComplete & end) )
										str.Append( GAMERESOURCEMAN->GetGameText( 445 ) );
									/// 진행중
									else
									{
										__int64 cnt = check & end;
										for( unsigned int b = 0; b < i; ++b)
											cnt = cnt >> 8;

										cStringT str1;
										str1.Format( GAMERESOURCEMAN->GetGameText( 459 ), (unsigned int)cnt, count );

										str += str1;
									}

									pKeeper->AddFontItem( cFontAgent::eFont_UI, (LPCTSTR)str.Cstr(), textposX + addX, textPosY, mDefaultColor );
									textPosY += rowHeight;
								}
								break;
							case eDUTY_COLLECT:		/// 수집
								{
									LPCTSTR itemName = ITEMMAN->GetItemName( targetIdx );
									str.Format( GAMERESOURCEMAN->GetGameText( 453 ), itemName, count );

									/// 완료
									if( (check & end) >= (define->mComplete & end) )
										str.Append( GAMERESOURCEMAN->GetGameText( 445 ) );
									/// 진행중
									else
									{
										__int64 cnt = check & end;
										for( unsigned int b = 0; b < i; ++b)
											cnt = cnt >> 8;

										cStringT str1;
										str1.Format( GAMERESOURCEMAN->GetGameText( 459 ), (unsigned int)cnt, count );

										str += str1;
									}

									pKeeper->AddFontItem( cFontAgent::eFont_UI, (LPCTSTR)str.Cstr(), textposX + addX, textPosY, mDefaultColor );
									textPosY += rowHeight;
								}
								break;
							case eDUTY_MEET:		/// npc 만나기
								{
									LPCTSTR npcName = GAMERESOURCEMAN->GetNpcName( targetIdx );
									str.Format( GAMERESOURCEMAN->GetGameText( 455 ), npcName );

									/// 완료
									if( (check & end) >= (define->mComplete & end) )
										str.Append( GAMERESOURCEMAN->GetGameText( 445 ) );

									pKeeper->AddFontItem( cFontAgent::eFont_UI, (LPCTSTR)str.Cstr(), textposX + addX, textPosY, mDefaultColor );
									textPosY += rowHeight;
								}
								break;
							}

							/// 완료 체크용
							end = end << 8;
						}
					} /// 상세표현 완료
				}/// 의무조건 표현 완료
			}
		}
	}

	///
	pKeeper->DrawAll();
}

void cQuestSimpleWindow::OnLButtonDoubleClick( const cUIPos& pos )
{
	OnLButtonDown( pos, false, false, false );
}

void cQuestSimpleWindow::OnLButtonDown( const cUIPos& pos, bool ctrl, bool alt, bool )
{
	cUIWindow::OnLButtonDown( pos, ctrl, alt, false );

	/// 이미지 영역 체크
	if( pos.mX < GetAbsoluteRect().mLeft + START_GAPX || pos.mX > GetAbsoluteRect().mLeft + START_GAPX + mImageSize.mWidth )
		return;

	if( pos.mY < GetAbsoluteRect().mTop + START_GAPY )
		return;

	int rowHeight = FONTAGENT->GetTextHeight( cFontAgent::eFont_UI );
	unsigned int selectRow = (pos.mY - (GetAbsoluteRect().mTop + START_GAPY) ) / rowHeight;
	int row = 0;

	/// 선택된 이미지 찾기
	typedef tPointerList<void*> cProgressList;

	cQuestMap::cIterator i = mQuestMap.Begin();
	cQuestMap::cIterator end = mQuestMap.End();
	for( ; i != end; ++i )
	{
		sQuestHaveData* data = (sQuestHaveData*)(i->mSecond);
		if( !data )
		{
			assert(0);
			return;
		}
		
		/// 선택된 이미지 
		if( selectRow == row && data->mCloseImage )
		{
			data->mClose = !data->mClose;

			/// 맵 라인은 닫히거나 열리니까 재계산하고,
			/// 의무조건 라인은 닫히면 무조건 삭제므로 재계산 안한다
			UpdateSize();
			return;
		}

		row++;

		/// 펼쳐져 있을 경우
		if( data->mClose == false )
		{
			cProgressList::cIterator b = data->mQuestProgressList.Begin();
			cProgressList::cIterator bend = data->mQuestProgressList.End();
			for( ; b != bend; ++b )
			{
				sQuestProgress* progress = (sQuestProgress*)(*b);
				if( !progress )
				{
					assert(0);
					return;
				}

				/// 선택된 이미지 인지 검사
				if( selectRow == row && progress->mCloseImage )
				{
					QUESTMAN->DeleteQuestSelect( progress->mIndex, true );
					return;
				}

				row++;

				/// 의무조건 갯수 추가
				if( progress->mClose == false )
				{
					cQuestDefine* define = progress->mDefine;
					cQuestDuty* duty = define->mQuestDuty;
					cQuestLimit* limit = define->mQuestLimit;
					if( limit && limit->mTime > 0 )
						row++;

					if( duty )
					{
						for( unsigned int i = 0; i < MAX_DUTY; ++i )
						{
							eDutyType type = duty->mDuty[i].dutyType;
							if( type != eDUTY_NONE )
								row++;
						}
					}
				}
			}
		}
	}
}

/// 퀘스트정보 삽입
void cQuestSimpleWindow::AddQuestInfo( unsigned long questIndex, __int64* check )
{
	cQuestDefine* define = QUESTMAN->GetQuestDefine( questIndex );
	if( !define )
	{
		assert(0);
		return;
	}

	/// 데이터가 없으면 새로생성
	sQuestHaveData* data = (sQuestHaveData*)mQuestMap.GetAt( define->mTakeMapIndex );
	if( !data )
	{
		data = new sQuestHaveData;
		data->mMapName = GAMERESOURCEMAN->GetMapName( define->mTakeMapIndex );
		data->mClose = false;
		data->mCloseImage = mpHighImage;

		if( mQuestMap.Insert( define->mTakeMapIndex, data ) == false )
		{
			assert(0);
			SAFE_DELETE( data );
			return;
		}
	}

	/// 퀘스트 갯수 갱신
	data->mTotalCount = QUESTMAN->GetCount( define->mTakeMapIndex );

	/// 상세 정보 세팅
	sQuestProgress* progress = new sQuestProgress;
	progress->mIndex = questIndex;
	progress->mDefine = define;
	progress->mCheck = check;
	progress->mClose = false;
	progress->mCloseImage = mpLowImage;
	progress->mTime = 0;
		
	TCHAR temp[128]={0,};
	::_stprintf( temp, _T( "[%d] %s" ), define->mLevel, GAMERESOURCEMAN->GetQuestTitle( define->mTitleIndex ) );
	progress->mQuestName = temp;
	
	data->mQuestProgressList.PushBack( progress );

	/// 윈도우 사이즈 재계산
	UpdateSize();

	///
	if( mQuestMap.GetSize() > 0 && mVisible == false )
	{
		/// npc 윈도우가 보이면 우선 예약
		if( UIMAN->IsShowNpcBack() == false )
			ShowTop();
		else
			UIMAN->SetRestoreShow( this );
	}
}

/// 삭제
void cQuestSimpleWindow::DeleteQuestInfo( unsigned long questIndex )
{
	cQuestDefine* define = QUESTMAN->GetQuestDefine( questIndex );
	if( !define )
	{
		assert(0);
		return;
	}

	/// 데이터가 없으면 새로생성
	sQuestHaveData* data = (sQuestHaveData*)mQuestMap.GetAt( define->mTakeMapIndex );
	if( !data )
	{
		assert(0);
		return;
	}

	typedef tPointerList<void*> cProgressList;
	cProgressList::cIterator b = data->mQuestProgressList.Begin();
	cProgressList::cIterator bend = data->mQuestProgressList.End();
	for( ; b != bend; ++b )
	{
		sQuestProgress* progress = (sQuestProgress*)(*b);
		if( progress && progress->mIndex == questIndex )
		{
			SAFE_DELETE( progress );
			data->mQuestProgressList.Erase( b );
			break;
		}
	}

	/// 하위 데이터가 남아있지 않으면 맵 정보 삭제
	if( data->mQuestProgressList.GetSize() == 0 )
	{
		mQuestMap.Erase( define->mTakeMapIndex );
	}

	/// 윈도우 사이즈 재계산
	if( mQuestMap.GetSize() == 0 )
		Hide();
	else
		UpdateSize();
}	

void cQuestSimpleWindow::UpdateSize()
{
	int totalLine = 0;
	int rowHeight = FONTAGENT->GetTextHeight( cFontAgent::eFont_UI );

	typedef tPointerList<void*> cProgressList;

	/// 출력
	cQuestMap::cIterator i = mQuestMap.Begin();
	cQuestMap::cIterator end = mQuestMap.End();
	for( ; i != end; ++i )
	{
		sQuestHaveData* data = (sQuestHaveData*)(i->mSecond);
		if( !data )
		{
			assert(0);
			return;
		}
	
		/// 1. 맵이름 출력 라인 추가
		totalLine++;

		/// 펼쳐져 있으면 퀘스트 리스트 출력
		if( data->mClose == false )
		{
			cProgressList::cIterator b = data->mQuestProgressList.Begin();
			cProgressList::cIterator bend = data->mQuestProgressList.End();
			for( ; b != bend; ++b )
			{
				sQuestProgress* progress = (sQuestProgress*)(*b);
				if( !progress )
				{
					assert(0);
					return;
				}	

				/// 1. 퀘스트 이름 출력 라인 추가
				totalLine++;

				/// 퀘스트 의무조건출력
				if( progress->mClose == false && progress->mDefine )
				{
					/// 1. 시간 제한 출력
					cQuestDefine* define = progress->mDefine;
					cQuestLimit* limit = define->mQuestLimit;
					if( limit && limit->mTime > 0 )
					{
						long restTime = QUESTMAN->GetQuestRestTime( progress->mIndex );
						int time = (int)(restTime*0.001);
						if( time >= 0 )
						{
							/// 3. 의무조건 - 시간 출력 라인 추가
							totalLine++;
						}
					}

					cQuestDuty* duty = define->mQuestDuty;
					if( duty )
					{
						__int64 end = 0xFF;
						__int64 check = *progress->mCheck;	/// 참조

						for( unsigned int i = 0; i < MAX_DUTY; ++i )
						{
							eDutyType type = duty->mDuty[i].dutyType;
							if( type == eDUTY_NONE )
								break;

							/// 4. 의무조건 출력 라인 추가
							switch( type )
							{
							case eDUTY_HUNT:	totalLine++; break;
							case eDUTY_COLLECT:	totalLine++; break;
							case eDUTY_MEET:	totalLine++; break;
							}

							/// 완료 체크용
							end = end << 8;
						}
					}
				}
			}
		}
	}

	/// 윈도우 사이즈 설정
	int w = mInitWidth + (START_GAPX * 2);
	int h = totalLine * rowHeight + (START_GAPY * 2);
	SetRelativeSize( cUISize(w, h) );
	
	int x = GetAbsoluteRect().mLeft;
	int y = GetAbsoluteRect().mTop;

	/// 이미지 설정
	if( mpBackImage[eBACKIMAGE_TOP] )
	{
		int skinHeight = mpBackSkin[eBACKIMAGE_TOP]->mSkinInfo->mHeight;
		mpBackImage[eBACKIMAGE_TOP]->SetScreenRect( x, y, w, skinHeight );
	}
	if( mpBackImage[eBACKIMAGE_CENTER] )
	{
		int backHeight = totalLine * rowHeight;
		mpBackImage[eBACKIMAGE_CENTER]->SetScreenRect( x + START_GAPX, y + START_GAPY, mInitWidth, backHeight );
	}
	if( mpBackImage[eBACKIMAGE_BOTTOM] )
	{
		int backHeight = totalLine * rowHeight;
		int skinHeight = mpBackSkin[eBACKIMAGE_BOTTOM]->mSkinInfo->mHeight;
		mpBackImage[eBACKIMAGE_BOTTOM]->SetScreenRect( x, y + backHeight + START_GAPY, w, skinHeight );
	}
	if( mpBackImage[eBACKIMAGE_LEFT] )
	{
		int backHeight = totalLine * rowHeight;
		int skinWidth = mpBackSkin[eBACKIMAGE_LEFT]->mSkinInfo->mWidth;
		mpBackImage[eBACKIMAGE_LEFT]->SetScreenRect( x, y + START_GAPY, skinWidth, backHeight );
	}
	if( mpBackImage[eBACKIMAGE_RIGHT] )
	{
		int backHeight = totalLine * rowHeight;
		int skinWidth = mpBackSkin[eBACKIMAGE_RIGHT]->mSkinInfo->mWidth;
		mpBackImage[eBACKIMAGE_RIGHT]->SetScreenRect( x + START_GAPX + mInitWidth, y + START_GAPY, skinWidth, backHeight );
	}

	/// 전체 캡션 지정
	mCaptionRect.Set( 0, 0, w, h );
}
