#include "StdAfx.h"
#include "ChatWindow.h"
#include "ChatManager.h"
#include "UISkin.h"
#include "UINodeData.h"

#include "TextBox.h"
#include "EditBox.h"
#include "Button.h"
#include "CheckBox.h"
#include "UIImage.h"
#include "PlaneObject.h"
#include "ItemManager.h"
#include "GameResourceManager.h"
#include "GameUIManager.h"
#include "ItemIcon.h"
#include "DragWindow.h"
#include "TipWindow.h"

cChatWindow::cChatWindow()
: mpOptionImage(0)
, mpChatBoxImage(0)
, mpChatBox(0)
, mpChatEdit(0)
, mpOptionSkin(0)
, mDefalutRowNum(0)
, mCount(0)
, mpChatBoxImageUp(0)
, mpChatBoxImageDown(0)
, mpUpSkin(0)
, mpChatEditWhisper(0)
, mSelectType( eCHAT_MAX )
, mpSelectImage(0)
, mpSelectSkin(0)
, mpButtonWindow(0)
, mpLinkItemIcon(0)
, mItemSlotIndex( UINT_MAX )
{
}

cChatWindow::~cChatWindow()
{
	SAFE_DELETE( mpSelectImage );
	SAFE_DELETE( mpChatBoxImageDown );
	SAFE_DELETE( mpChatBoxImageUp );
	SAFE_DELETE( mpOptionImage );
	SAFE_DELETE( mpChatBoxImage );
}

void cChatWindow::OnShow()
{
	if( mpChatEdit )
		mpChatEdit->Show();

	cUIWindow::OnShow();
}

void cChatWindow::OnHide()
{
	cUIWindow::OnHide();

	if( mpChatEdit )
	{
		mpChatEdit->Hide();
		mpChatEdit->Clear();
	}
}

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

	mpChatBox = (cTextBox*)GetChild( eUIID_CHATWINDOW_CHATBOX );
	mpChatEdit = (cEditBox*)GetChild( eUIID_CHATWINDOW_CHATBOX_EDITBOX );
	mpChatEditWhisper = (cEditBox*)GetChild( eUIID_CHATWINDOW_CHATBOX_EDIT_WHISPER );
	if( !mpChatBox || !mpChatEdit || !mpChatEditWhisper )
		return false;

	/// 채팅윈도우 등록
	CHATMANAGER->SetChatWindow( this );

	/// 에디트 등록
	CHATMANAGER->AddFocusNode( mpChatEdit );

	///
	cUISkin* skin = UIMAN->GetSkin();
	if( !skin )
	{
		assert(0);
		return false;
	}

	/// 채팅박스 배경이미지
	cUINodeSkin* pplaneSkin = skin->GetNodeSkin( "ChatBoxImage" );
	if( pplaneSkin && pplaneSkin->mpTexture )
	{
		/// 텍스처 영역 설정
		unsigned short tx = (unsigned short)pplaneSkin->mSkinInfo->mTexX;
		unsigned short ty = (unsigned short)pplaneSkin->mSkinInfo->mTexY;
		unsigned short tw = (unsigned short)pplaneSkin->mSkinInfo->mTexWidth;
		unsigned short th = (unsigned short)pplaneSkin->mSkinInfo->mTexHeight;
		unsigned short x = mpChatBox->GetAbsoluteRect().mLeft;
		unsigned short y = mpChatBox->GetAbsoluteRect().mTop;
		unsigned short w = mpChatBox->GetAbsoluteRect().GetWidth();
		unsigned short h = mpChatBox->GetAbsoluteRect().GetHeight();

		mpChatBoxImage = new cPlaneObject;
		if( mpChatBoxImage->Create( pplaneSkin->mpTexture, x, y, w, h,
									tx, ty, tx + tw, ty + th ) == false )
		{
			assert( 0 && "failed to create chat box image");
			return false;
		}
	}
	else
	{
		assert(0);
		return false;
	}

	/// 채팅박스 이미지 틀 
	mpUpSkin = skin->GetNodeSkin( "ChatBoxImage_Up" );
	if( mpUpSkin && mpUpSkin->mpTexture )
	{
		/// 텍스처 영역 설정
		unsigned short tx = (unsigned short)mpUpSkin->mSkinInfo->mTexX;
		unsigned short ty = (unsigned short)mpUpSkin->mSkinInfo->mTexY;
		unsigned short tw = (unsigned short)mpUpSkin->mSkinInfo->mTexWidth;
		unsigned short th = (unsigned short)mpUpSkin->mSkinInfo->mTexHeight;
		unsigned short x = mpChatBox->GetAbsoluteRect().mLeft;
		unsigned short y = mpChatBox->GetAbsoluteRect().mTop - th;
		unsigned short w = mpChatBox->GetAbsoluteRect().GetWidth();

		mpChatBoxImageUp = new cPlaneObject;
		if( mpChatBoxImageUp->Create( mpUpSkin->mpTexture, x, y, w, th,
										tx, ty, tx + tw, ty + th ) == false )
		{
			assert( 0 && "failed to create chat box up image");
			return false;
		}
	}

	cUINodeSkin* downSkin = skin->GetNodeSkin( "ChatBoxImage_Down" );
	if( downSkin && downSkin->mpTexture )
	{
		/// 텍스처 영역 설정
		unsigned short tx = (unsigned short)downSkin->mSkinInfo->mTexX;
		unsigned short ty = (unsigned short)downSkin->mSkinInfo->mTexY;
		unsigned short tw = (unsigned short)downSkin->mSkinInfo->mTexWidth;
		unsigned short th = (unsigned short)downSkin->mSkinInfo->mTexHeight;
		unsigned short x = mpChatBox->GetAbsoluteRect().mLeft;
		unsigned short y = mpChatBox->GetAbsoluteRect().mBottom;
		unsigned short w = mpChatBox->GetAbsoluteRect().GetWidth();

		mpChatBoxImageDown = new cPlaneObject;
		if( mpChatBoxImageDown->Create( downSkin->mpTexture, x, y, w, th,
			tx, ty, tx + tw, ty + th ) == false )
		{
			assert( 0 && "failed to create chat box down image");
			return false;
		}
	}

	/// 채팅 옵션 스킨 로드
	mpOptionSkin = skin->GetNodeSkin( "OptionImage" );
	if( mpOptionSkin && mpOptionSkin->mpTexture )
	{
		mpOptionImage = new cUIImage( mpOptionSkin->mpTexture );
		unsigned int tx = mpOptionSkin->mSkinInfo->mTexX;
		unsigned int ty = mpOptionSkin->mSkinInfo->mTexY;
		unsigned int tw = mpOptionSkin->mSkinInfo->mTexWidth;
		unsigned int th = mpOptionSkin->mSkinInfo->mTexHeight;
		mpOptionImage->SetTextureRect( tx, ty, tx + tw, ty + th );

		unsigned int x = GetAbsoluteRect().mLeft;
		unsigned int y = mpChatBox->GetAbsoluteRect().mTop + mpChatBox->GetAbsoluteRect().GetHeight() + HEIGHT_GAP;
		
		cUIRect desc( x, y, x+tw, y+th );
		mpOptionImage->SetScreenRect( desc );
	}
	else
	{
		assert( 0 && "failed to find optionSkin skin" );
		return false;
	}

	/// 선택 버튼 이미지
	mpSelectSkin = skin->GetNodeSkin( "Chat_SelectImage" );
	if( mpSelectSkin && mpSelectSkin->mpTexture )
	{
		mpSelectImage = new cUIImage( mpSelectSkin->mpTexture );
		unsigned int tx = mpSelectSkin->mSkinInfo->mTexX;
		unsigned int ty = mpSelectSkin->mSkinInfo->mTexY;
		unsigned int tw = mpSelectSkin->mSkinInfo->mTexWidth;
		unsigned int th = mpSelectSkin->mSkinInfo->mTexHeight;
		unsigned int x = mpSelectSkin->mSkinInfo->mX + GetAbsoluteRect().mLeft;
		unsigned int y = mpSelectSkin->mSkinInfo->mY + mpChatBox->GetAbsoluteRect().mBottom;
		mpSelectImage->SetTextureRect( tx, ty, tx + tw, ty + th );

		cUIRect desc( x, y, x+tw, y+th );
		mpSelectImage->SetScreenRect( desc );
	}

	/// 링크 아이템 아이콘 생성
	mpLinkItemIcon = new cItemIcon;
	if( mpLinkItemIcon->CreateBySkinName( "Inven_LinkIcon", this, 100, true ) == false )
		return false;

	mpLinkItemIcon->SetLinked( true );	/// 인벤토리에서 참조함을 세팅

	/// 윈도우 사이즈 갱신
	if( mpOptionSkin )
	{
		int w = mpOptionSkin->mSkinInfo->mTexWidth;
		int h = mpOptionSkin->mSkinInfo->mTexHeight + mpChatBox->GetAbsoluteRect().GetHeight() + HEIGHT_GAP;
		SetRelativeSize( cUISize(w, h) );
	}

	///
	mpChatBox->SetScrollBottom( true );

	if( mpChatEditWhisper )
		mpChatEditWhisper->SetTextColor( eCOLOR_PINK );

	///
	mDefalutRowNum = mpChatBox->GetMaxRowInPage();

	/// 기본세팅
	cUINode* pNormal = GetChild( eUIID_CHATWINDOW_NORMAL );
	if( pNormal )
		pNormal->SetPress( true );

	cUINode* pParty = GetChild( eUIID_CHATWINDOW_PARTY );
	if( pParty )
		pParty->SetPress( true );

	cUINode* pGuild = GetChild( eUIID_CHATWINDOW_GUILD );
	if( pGuild )
		pGuild->SetPress( true );

	cUINode* pShout = GetChild( eUIID_CHATWINDOW_SHOUT );
	if( pShout )
		pShout->SetPress( true );

	cUINode* pTrade = GetChild( eUIID_CHATWINDOW_TRADE );
	if( pTrade )
		pTrade->SetPress( true );

	cUINode* pWhisper = GetChild( eUIID_CHATWINDOW_WHISPER );
	if( pWhisper )
		pWhisper->SetPress( true );

	mpButtonWindow = GAMEUI->GetChatButtonWindow();
	if( !mpButtonWindow )
	{
		assert(0);
		return false;
	}
	
	/// 선택된 타입
	UpdateChatType( eCHAT_NORMAL );
	return true;
}

///
bool cChatWindow::HandleEvent( const cUIEvent& event )
{
	if( event.mType == eUIEVENT_KEY_DOWN )
	if( event.mCode == eKEY_UP || event.mCode == eKEY_DOWN )
	{
		KeyEvent( event.mCode );
	}

	return cUIWindow::HandleEvent( event );
}

/// 주의사항 : 윈도우 Move 시에만 호출 
void cChatWindow::UpdateRect()
{
	cUIWindow::UpdateRect();

	if( !mpChatBox )
		return;

	/// 채팅박스 배경이미지
	if( mpChatBoxImage )
	{
		unsigned short x = mpChatBox->GetAbsoluteRect().mLeft;
		unsigned short y = mpChatBox->GetAbsoluteRect().mTop;
		unsigned short w = mpChatBox->GetAbsoluteRect().GetWidth();
		unsigned short h = mpChatBox->GetAbsoluteRect().GetHeight();
		mpChatBoxImage->SetScreenRect( x, y, w, h );
	}

	/// 채팅 옵션 스킨 로드
	if( mpOptionImage )
	{
		unsigned int x = GetAbsoluteRect().mLeft;
		unsigned int y = mpChatBox->GetAbsoluteRect().mTop + mpChatBox->GetAbsoluteRect().GetHeight() + HEIGHT_GAP;
		mpOptionImage->SetPos( x, y );
	}

	/// 위아래 이미지
	if( mpChatBoxImageUp && mpUpSkin )
	{
		unsigned short x = mpChatBox->GetAbsoluteRect().mLeft;
		unsigned short y = mpChatBox->GetAbsoluteRect().mTop - mpUpSkin->mSkinInfo->mTexHeight;
		mpChatBoxImageUp->SetScreenXY( x, y );
	}

	if( mpChatBoxImageDown )
	{
		unsigned short x = mpChatBox->GetAbsoluteRect().mLeft;
		unsigned short y = mpChatBox->GetAbsoluteRect().mBottom;
		mpChatBoxImageDown->SetScreenXY( x, y );
	}

	if( mpSelectImage && mpSelectSkin && mpChatBox )
	{
		unsigned short x = mpSelectSkin->mSkinInfo->mX + GetAbsoluteRect().mLeft;
		unsigned short y = mpSelectSkin->mSkinInfo->mY + mpChatBox->GetAbsoluteRect().mBottom;
		mpSelectImage->SetPos( x, y );
	}

	if( mpButtonWindow && mpSelectSkin && mpChatBox )
	{
		unsigned short x = mpSelectSkin->mSkinInfo->mX + GetAbsoluteRect().mLeft;
		unsigned short y = (mpSelectSkin->mSkinInfo->mY + mpChatBox->GetAbsoluteRect().mBottom) - mpButtonWindow->GetAbsoluteRect().GetHeight();
		mpButtonWindow->SetRelativePos( cUIPos(x, y) );
	}
}

/// 주의사항 : 해상도 변경시에 호출 
void cChatWindow::UpdateSkin()
{
	cUIWindow::UpdateSkin();

	if( mpOptionSkin )
	{
		/// 윈도우 사이즈 갱신이 되므로 자동으로 UpdateRect 호출
		int w = mpOptionSkin->mSkinInfo->mTexWidth;
		int h = mpOptionSkin->mSkinInfo->mTexHeight + mpChatBox->GetAbsoluteRect().GetHeight() + HEIGHT_GAP;
		SetRelativeSize( cUISize(w, h) );
	}
}

///
void cChatWindow::OnRender( cUIFontItemKeeper* pKeeper )
{
	/// 이미지 렌더링
	if( mpChatBoxImage )
		mpChatBoxImage->Draw();

	if( mpOptionImage )
		mpOptionImage->Draw();

	if( mpChatBoxImageUp )
		mpChatBoxImageUp->Draw();

	if( mpChatBoxImageDown )
		mpChatBoxImageDown->Draw();

	if( mpSelectImage )
		mpSelectImage->Draw();

	cUIWindow::OnRender( pKeeper );
}

/// 주의사항 : 
void cChatWindow::OnEditBoxEntered( cUINode*, unsigned int id )
{
	if( !mpChatEdit )
	{
		assert(0);
		return;
	}

	if( id == eUIID_CHATWINDOW_CHATBOX_EDITBOX )
	{
		CHATMANAGER->SendChatMsg( mSelectType, mpChatEdit->GetText() );

		mpChatEdit->Clear();
		mpChatEdit->ReleaseFocus();

		///
		DeleteLinkItem();
	}
	else if( id == eUIID_CHATWINDOW_CHATBOX_EDIT_WHISPER )
	{
		mpChatEdit->SetFocus();
	}
}

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

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

	if( mpSelectSkin && mpButtonWindow && mpChatBox )
	{
		cUIRect rect;
		rect.mLeft = GetAbsoluteRect().mLeft + mpSelectSkin->mSkinInfo->mX;
		rect.mTop = mpChatBox->GetAbsoluteRect().mBottom + mpSelectSkin->mSkinInfo->mY;
		rect.mRight = rect.mLeft + mpSelectSkin->mSkinInfo->mWidth;
		rect.mBottom = rect.mTop + mpSelectSkin->mSkinInfo->mHeight;

		/// 이미지를 클릭하였으면
		if( rect.ContainPoint( pos ) == true )
		{
			if( mpButtonWindow->IsVisible() == true )
				mpButtonWindow->Hide();
			else
				mpButtonWindow->ShowTop();
		}
	}
}

/// 주의사항 : 
void cChatWindow::OnButtonDowned(cUINode*, unsigned int id)
{
	switch( id )
	{
	case eUIID_CHATWINDOW_SIZE_PLUS_BUTTON:
		{
			/// 한페이지에 수용하는 최대 행수 
			unsigned int maxNum = mpChatBox->GetMaxRowInPage();
			if( maxNum < MAXROWNUM )
			{
				/// 채팅창 확대 
				int rowHeight = mpChatBox->GetRowHeight();
				UpdateSize( rowHeight );
			}	
		}	
		break;
	case eUIID_CHATWINDOW_SIZE_MINUS_BUTTON:
		{
			unsigned int maxNum = mpChatBox->GetMaxRowInPage();
			if( maxNum > mDefalutRowNum )
			{
				/// 채팅창 축소 
				int rowHeight = mpChatBox->GetRowHeight();
				UpdateSize( -rowHeight );
			}			
		}
		break;
	}
}

/// 주의사항 : 
void cChatWindow::OnCommand( cUINode*, unsigned int id )
{
	if( !mpChatBox )
	{
		assert(0);
		return;
	}

	switch( id )
	{
	case eUIID_CHATWINDOW_EXTEND_BUTTON:
		{
			cExtraList::cIterator b = mExtraList.Begin();
			cExtraList::cIterator end = mExtraList.End();
			for( ; b != end; ++b )
			{
				cUIWindow* w = (cUIWindow*)(*b);
				if( w && w->IsVisible() == false )
				{
					w->ShowTop();
					break;
				}
			}
		}	
		break;
	case eUIID_CHATWINDOW_SIZE_PLUS_BUTTON:
		{
			/// 한페이지에 수용하는 최대 행수 
			unsigned int maxNum = mpChatBox->GetMaxRowInPage();
			if( maxNum < MAXROWNUM )
			{
				/// 채팅창 확대 
				int rowHeight = mpChatBox->GetRowHeight();
				UpdateSize( rowHeight );
			}	
		}	
		break;
	case eUIID_CHATWINDOW_SIZE_MINUS_BUTTON:
		{
			unsigned int maxNum = mpChatBox->GetMaxRowInPage();
			if( maxNum > mDefalutRowNum )
			{
				/// 채팅창 축소 
				int rowHeight = mpChatBox->GetRowHeight();
				UpdateSize( -rowHeight );
			}			
		}
		break;
	}
}

/// 주의사항 : 사이즈 확대 / 축소 
void cChatWindow::UpdateSize( int height )
{
	if( height == 0 )
	{
		assert(0);
		return;
	}

	if( !mpChatBox )
	{
		assert(0);
		return;
	}

	/// 채팅박스 갱신 
	cUISize boxsize;
	boxsize.mWidth = mpChatBox->GetAbsoluteRect().GetWidth();
	boxsize.mHeight = mpChatBox->GetAbsoluteRect().GetHeight() + height;
	mpChatBox->SetRelativeSize( boxsize );

	/// 채팅윈도우 갱신
	cUIRect winRc = GetAbsoluteRect();
	winRc.mTop -= height;
	SetRelativeRect( winRc );

	/// 채팅윈도우 자식 컨트롤 업데이트 
	cChildList::cIterator i = mChildList.Begin();
	cChildList::cIterator end = mChildList.End();
	for( ; i != end; ++i )
	{
		cUINode* child = (cUINode*)(*i);
		if( child != mpChatBox )
		{
			cUIRect childRc = child->GetRelativeRect();
			childRc.mTop += height;
			childRc.mBottom += height;
			child->SetRelativeRect( childRc );
		}
	}

	if( mpChatBoxImage )
	{
		unsigned short x = mpChatBox->GetAbsoluteRect().mLeft;
		unsigned short y = mpChatBox->GetAbsoluteRect().mTop;
		unsigned short w = mpChatBox->GetAbsoluteRect().GetWidth();
		unsigned short h = mpChatBox->GetAbsoluteRect().GetHeight();
		mpChatBoxImage->SetScreenRect( x, y, w, h );
	}

	/// 채팅 옵션 스킨 로드
	if( mpOptionImage )
	{
		unsigned int x = GetAbsoluteRect().mLeft;
		unsigned int y = mpChatBox->GetAbsoluteRect().mTop + mpChatBox->GetAbsoluteRect().GetHeight() + HEIGHT_GAP;
		mpOptionImage->SetPos( x, y );
	}

	/// 사이즈 변경에 따른 채팅박스 데이터 갱신 
	bool sizeAdd = (height > 0 ) ? true : false;
	mpChatBox->UpdateTextBox( sizeAdd );
}

void cChatWindow::UpdateChatType( eChatMsgKind type )
{
	if( mSelectType == type )
		return;

	cUISkin* skin = UIMAN->GetSkin();
	if( !skin )
	{
		assert(0);
		return;
	}

	/// 이미지 세팅
	cUINodeSkin* nodeSkin = 0;
	switch( type )
	{
	case eCHAT_NORMAL:
		nodeSkin = skin->GetNodeSkin( "ChatButton_Normal" );
		break;
	case eCHAT_PARTY:
		nodeSkin = skin->GetNodeSkin( "ChatButton_Party" );
		break;
	case eCHAT_GUILD:
		nodeSkin = skin->GetNodeSkin( "ChatButton_Guild" );
		break;
	case eCHAT_SHOUT:
		nodeSkin = skin->GetNodeSkin( "ChatButton_Shout" );
		break;
	case eCHAT_TRADE:
		nodeSkin = skin->GetNodeSkin( "ChatButton_Trade" );
		break;
	case eCHAT_WHISPER:
		nodeSkin = skin->GetNodeSkin( "ChatButton_Whisper" );
		break;
	}
	
	/// 선택된 이미지 적용
	if( nodeSkin && mpSelectImage )
	{
		mSelectType = type;

		unsigned int tx = nodeSkin->mSkinInfo->mTexX;
		unsigned int ty = nodeSkin->mSkinInfo->mTexY;
		unsigned int tw = nodeSkin->mSkinInfo->mTexWidth;
		unsigned int th = nodeSkin->mSkinInfo->mTexHeight;
		mpSelectImage->SetTextureRect( tx, ty, tx + tw, ty + th );

		/// 그외 정보 갱신
		if( mpChatEditWhisper )
		{
			if( mSelectType == eCHAT_WHISPER )
				mpChatEditWhisper->Show();
			else
				mpChatEditWhisper->Hide();
		}
	}
}

/// 주의사항 : 
void cChatWindow::InsertText( eChatMsgKind msgkind, LPCTSTR text )
{
	if( !mpChatBox )
	{
		assert(0);
		return;
	}

	TCHAR temp[256]={0,};

	switch( msgkind )
	{
	case eCHAT_NORMAL:
		{
			cUINode* pNormal = GetChild( eUIID_CHATWINDOW_NORMAL );
			if( pNormal && pNormal->IsPress() == true )
			{
				::_stprintf( temp, GAMERESOURCEMAN->GetGameText( 86 ), text );
				mpChatBox->AddNewRow( temp, eCOLOR_WHITE );
			}
		}
		break;
	case eCHAT_PARTY:
		{
			cUINode* pParty = GetChild( eUIID_CHATWINDOW_PARTY );
			if( pParty && pParty->IsPress() == true )
			{
				::_stprintf( temp, GAMERESOURCEMAN->GetGameText( 87 ), text );
				mpChatBox->AddNewRow( temp, eCOLOR_PARTY );
			}
		}
		break;
	case eCHAT_GUILD:
		{
			cUINode* pGuild = GetChild( eUIID_CHATWINDOW_GUILD );
			if( pGuild && pGuild->IsPress() == true )
			{
				::_stprintf( temp, GAMERESOURCEMAN->GetGameText( 88 ), text );
				mpChatBox->AddNewRow( temp, eCOLOR_GUILD );
			}
		}
		break;
	case eCHAT_SHOUT:
		{
			cUINode* pShout = GetChild( eUIID_CHATWINDOW_SHOUT );
			if( pShout && pShout->IsPress() == true )
			{
				::_stprintf( temp, GAMERESOURCEMAN->GetGameText( 89 ), text );
				mpChatBox->AddNewRow( temp, eCOLOR_SHOUT );
			}
		}
		break;
	case eCHAT_TRADE:
		{
			cUINode* pTrade = GetChild( eUIID_CHATWINDOW_TRADE );
			if( pTrade && pTrade->IsPress() == true )
			{
				::_stprintf( temp, GAMERESOURCEMAN->GetGameText( 90 ), text );
				mpChatBox->AddNewRow( temp, eCOLOR_TRADE );
			}
		}
		break;
	case eCHAT_WHISPER:
		{
			cUINode* pWhisper = GetChild( eUIID_CHATWINDOW_WHISPER );
			if( pWhisper && pWhisper->IsPress() == true )
			{
				mpChatBox->AddNewRow( text, eCOLOR_WHISPER );
			}
		}
		break;
	case eCHAT_NOTICE:
		{
			/// 공지
			::_stprintf( temp, GAMERESOURCEMAN->GetGameText( 92 ), text );
			mpChatBox->AddNewRow( temp, eCOLOR_RED );
		}
		break;
	case eCHAT_GM:
		{
			/// GM의 일반 채팅
			cUINode* pNormal = GetChild( eUIID_CHATWINDOW_NORMAL );
			if( pNormal && pNormal->IsPress() == true )
			{
				::_stprintf( temp, GAMERESOURCEMAN->GetGameText( 180 ), text );
				mpChatBox->AddNewRow( temp, eCOLOR_GM );
			}
		}
		break;
	}
}

/// 주의사항 : 
void cChatWindow::InsertTextSystem( eSystemMsgKind kind, LPCTSTR chatmsg )
{
	if( !mpChatBox )
	{
		assert(0);
		return;
	}

	unsigned long color = eCOLOR_WHITE;

	switch( kind )
	{
	case eSYSTEM_NORMAL:	color = 0xFFFFFFFF;		break;
	case eSYSTEM_GETMONEY:	color = 0xFFFFFF0A;		break;
	case eSYSTEM_GETITEM:	color = 0xFF02FFA3;		break;
	case eSYSTEM_QUEST:		color = 0xFF00FFFF;		break;
	case eSYSTEM_DOITEM:	color = 0xFFA6B27D;		break;
	case eSYSTEM_CASH:		color = 0xFF643264;		break;
	case eSYSTEM_NPCSTORE:  color = 0xFFE9A921;		break;
	case eSYSTEM_PVP:		color = eCOLOR_RED;		break;
	case eSYSTEM_GM:		color = eCOLOR_RED;		break;
	default:				assert(0);				break;
	}

	cUINode* pSystem = GetChild( eUIID_CHATWINDOW_SYSTEM );
	if( pSystem && pSystem->IsPress() == true )
	{
		TCHAR temp[256]={0,};
		::_stprintf( temp, GAMERESOURCEMAN->GetGameText( 91 ), chatmsg );
		mpChatBox->AddNewRow( temp, color );
	}
}

///
void cChatWindow::InsertTextTip( LPCTSTR chatmsg )
{
	if( mpChatBox )
		mpChatBox->AddNewRow( chatmsg, eCOLOR_TIP );
}

void cChatWindow::InsertItemText( unsigned long itemIndex, unsigned int slotIndex, LPCTSTR msg1, LPCTSTR msg2, bool IsQuest )
{
	if( !mpChatBox )
	{
		assert(0);
		return;
	}

	/// 시스템 메세지 보이기 설정되어 있으면 출력
	cUINode* pSystem = GetChild( eUIID_CHATWINDOW_SYSTEM );
	if( pSystem && pSystem->IsPress() == true )
	{
		cItemDefine* itemDefine = ITEMMAN->GetItemDefine( itemIndex );
		if( !itemDefine )
			return;
		
		/// 글씨 컬러 정하기
		unsigned long itemColor = eCOLOR_WHITE;
		unsigned long textColor = (IsQuest == false) ? eCOLOR_WHITE : 0xFF00FFFF;	/// 퀘스트 색
		ITEMMAN->GetTooltipColor( itemDefine->GetTipType(), itemColor );
		
		/// 새로운줄에 삽입할지 결정
		TCHAR itemName[256] = {0,};
		::_stprintf( itemName, GAMERESOURCEMAN->GetGameText( 241 ), itemDefine->GetName() );

		TCHAR temp[256]={0,};
		if( msg1 )
			::_stprintf( temp, GAMERESOURCEMAN->GetGameText( 91 ), msg1 );
		else
			::_stprintf( temp, GAMERESOURCEMAN->GetGameText( 93 ) );

		mpChatBox->AddNewRow( temp, textColor );
		mpChatBox->AddItemRow( false, itemIndex, slotIndex, itemName, itemColor );
		mpChatBox->AddPasteRow( msg2, textColor );
	}
}

/// 아이템 거래 메세지 출력
void cChatWindow::InsertItemText( sInventory inventory, LPCTSTR name, LPCTSTR msg, eChatMsgKind kind )
{
	if( !mpChatBox )
	{
		assert(0);
		return;
	}

	TCHAR temp[256] = {0,};

	cItemDefine* define = ITEMMAN->GetItemDefine( inventory.ItemIndex );
	if( !define )
	{
		/// 링크된 아이템이 없으면 그냥 출력
		if( kind != eCHAT_WHISPER )
		{
			::_stprintf( temp, UIMAN->GetUIText( 10000 ), name, msg );
			InsertText( kind, temp );
		}
		else
		{
			::_stprintf( temp, _T("%s%s"), name, msg );
			InsertText( kind, temp );
		}
	}
	else
	{
		/// 링크된 아이템이 있으면 연결정보 출력
		unsigned long itemColor = eCOLOR_WHITE;
		ITEMMAN->GetTooltipColor( define->GetTipType(), itemColor );

		TCHAR itemName[256] = {0,};

		/// 강화단계 + 이름 출력
		if( inventory.enhanced > 0 )
		{
			::_stprintf( itemName, GAMERESOURCEMAN->GetGameText(249), inventory.enhanced, define->GetName() );
		}
		else
		{
			::_stprintf( itemName, GAMERESOURCEMAN->GetGameText(241), define->GetName() );
		}

		switch( kind )
		{
		case eCHAT_NORMAL:
			{	
				cUINode* pNormal = GetChild( eUIID_CHATWINDOW_NORMAL );
				if( pNormal && pNormal->IsPress() == true )
				{
					::_stprintf( temp, GAMERESOURCEMAN->GetGameText( 94 ), name );

					mpChatBox->AddNewRow( temp, eCOLOR_WHITE );
					mpChatBox->AddItemRow( inventory, itemName, itemColor );
					mpChatBox->AddPasteRow( msg, eCOLOR_WHITE );
				}
			}
			break;
		case eCHAT_PARTY:
			{
				cUINode* pParty = GetChild( eUIID_CHATWINDOW_PARTY );
				if( pParty && pParty->IsPress() == true )
				{
					::_stprintf( temp, GAMERESOURCEMAN->GetGameText( 95 ), name );

					mpChatBox->AddNewRow( temp, eCOLOR_PARTY );
					mpChatBox->AddItemRow( inventory, itemName, itemColor );
					mpChatBox->AddPasteRow( msg, eCOLOR_PARTY );
				}
			}
			break;
		case eCHAT_GUILD:
			{
				cUINode* pGuild = GetChild( eUIID_CHATWINDOW_GUILD );
				if( pGuild && pGuild->IsPress() == true )
				{
					::_stprintf( temp, GAMERESOURCEMAN->GetGameText( 96 ), name );

					mpChatBox->AddNewRow( temp, eCOLOR_GUILD );
					mpChatBox->AddItemRow( inventory, itemName, itemColor );
					mpChatBox->AddPasteRow( msg, eCOLOR_GUILD );
				}
			}
			break;
		case eCHAT_TRADE:
			{
				cUINode* pTrade = GetChild( eUIID_CHATWINDOW_TRADE );
				if( pTrade && pTrade->IsPress() == true )
				{
					::_stprintf( temp, GAMERESOURCEMAN->GetGameText( 97 ), name );

					mpChatBox->AddNewRow( temp, eCOLOR_TRADE );
					mpChatBox->AddItemRow( inventory, itemName, itemColor );
					mpChatBox->AddPasteRow( msg, eCOLOR_TRADE );
				}
			}
			break;
		case eCHAT_WHISPER:
			{
				cUINode* pWhisper = GetChild( eUIID_CHATWINDOW_WHISPER );
				if( pWhisper && pWhisper->IsPress() == true )
				{
					mpChatBox->AddNewRow( name, eCOLOR_WHISPER );
					mpChatBox->AddItemRow( inventory, itemName, itemColor );
					mpChatBox->AddPasteRow( msg, eCOLOR_WHISPER );
				}
			}
			break;
		case eCHAT_GM:
			{	
				cUINode* pNormal = GetChild( eUIID_CHATWINDOW_NORMAL );
				if( pNormal && pNormal->IsPress() == true )
				{
					::_stprintf( temp, GAMERESOURCEMAN->GetGameText( 181 ), name );

					mpChatBox->AddNewRow( temp, eCOLOR_GM );
					mpChatBox->AddItemRow( inventory, itemName, itemColor );
					mpChatBox->AddPasteRow( msg, eCOLOR_GM );
				}
			}
			break;
		default: 
			assert(0);
			break;
		}
	}
}

void cChatWindow::Clear()
{
	if( mpChatBox )
		mpChatBox->Clear();

	if( mpChatEdit )
		mpChatEdit->Clear();
}

/// 주의사항 : 
void cChatWindow::SetFocusToEdit()
{
	if( mpChatEdit )
		mpChatEdit->SetFocusBook();
}

/// 주의사항 :
void cChatWindow::SetChatText( LPCTSTR text )
{
	if( mpChatEdit )
		mpChatEdit->SetText( text );
}

void cChatWindow::AddExtraWindow( cUIWindow* w )
{
	if( w )
		mExtraList.PushBack( w );
}

///
void cChatWindow::AddWhisperUser( const cStringT& name )
{
	/// 기존의 등록된 유저가 있는지 찾기
	cWhisperList::cIterator i = mWhisperList.Begin();
	cWhisperList::cIterator end = mWhisperList.End();

	for( ; i != end; ++i )
	{
		/// 동일한 아디가 있으면, 갱신
		if( name == (*i) )
		{
			mWhisperList.Erase(i);
			break;
		}
	}

	/// 5명이 이미 등록되어있고 동일한 아이디없으면 새로 삽입
	if( mWhisperList.GetSize() >= 5 && i == end )
	{
		mWhisperList.PopFront();
	}

	mWhisperList.PushBack( name );
	mCount = -1;
}

void cChatWindow::ApplyLastWhisperUser()
{
	if( mpChatEdit == 0 )
		return;
	if( mWhisperList.GetSize() == 0 )
		return;

	cStringT name = mWhisperList.Back();

	cStringT str;
	str.Format( UIMAN->GetUIText(10005), (LPCTSTR)name.Cstr() );
	mpChatEdit->SetText( (LPCTSTR)str.Cstr() );

	SetFocusToEdit();
}

///
void cChatWindow::KeyEvent( eKeyCode code )
{
	int len = ::_tcslen( mpChatEdit->GetText() );
	if( len <= 0 )
		return;

	/// 귓속말 명령어가 입력되어있지 않으면 리턴 
	/// "/w", "/W", "/ㅈ"
	if( ::_tcsncmp( mpChatEdit->GetText(), UIMAN->GetUIText(10002), 2 ) != 0 &&
		::_tcsncmp( mpChatEdit->GetText(), UIMAN->GetUIText(10003), 2 ) != 0 && 
		::_tcsncmp( mpChatEdit->GetText(), UIMAN->GetUIText(10004), 2 ) != 0 )
		return; 

	if( code == eKEY_UP )
	{
		mCount++;

		if( mCount >= (int)mWhisperList.GetSize() )
		{
			mCount = 0;
		}
	}
	else if( code == eKEY_DOWN )
	{
		mCount--;

		if( mCount < 0 )
		{
			mCount = (int)mWhisperList.GetSize() - 1;
		}
	}
	else
	{
		assert(0);
		return;
	}

	///
	cWhisperList::cIterator b = (--mWhisperList.End());
	cWhisperList::cIterator end = (--mWhisperList.Begin());

	int index = 0;
	cStringT name;

	for( ; b != end; --b )
	{
		if( mCount == index )
		{
			name = (*b);
			break;
		}

		index++;
	}

	if( mpChatEdit )
	{
		/// "/w %s "
		cStringT str;
		str.Format( UIMAN->GetUIText(10005), (LPCTSTR)name.Cstr() );
		mpChatEdit->SetText( (LPCTSTR)str.Cstr() );
	}
	else
	{
		assert(0);
	}
}

void cChatWindow::OnIconDragged( cUINode* caller, unsigned int , const cUIPos& pos, bool shift )
{
	cIcon* icon = (cIcon*)caller;
	if( icon )
		UIMAN->ShowDrag( this, DRAG_FROM_CHATLINK, icon, pos, shift );
}

void cChatWindow::OnIconHovered( cUINode* caller, unsigned int , const cUIPos& pos )
{
	cIcon* hoverIcon = (cIcon*)caller;
	if( hoverIcon == mpLinkItemIcon && mItemSlotIndex <= MAX_INVENTORY )
	{
		cItem& item = ITEMMAN->GetItem( mItemSlotIndex );
		UIMAN->ShowItemTip( eTIP_ITEM, pos, item.GetIndex(), mItemSlotIndex, 0 );
	}
}

/// 아이템 링크
bool cChatWindow::AddLinkItem( unsigned int slotIndex )
{
	if( slotIndex > MAX_INVENTORY )
		return false;

	cItem& item = ITEMMAN->GetItem( slotIndex );
	cItemDefine* define = item.GetDefine();
	if( !define )
	{
		assert(0);
		return false;
	}

	/// 기존 등록 아이템 삭제
	if( mItemSlotIndex <= MAX_INVENTORY && mItemSlotIndex != slotIndex )
	{
		cItem& oldItem = ITEMMAN->GetItem( mItemSlotIndex );
		oldItem.SetLock( false );
	}

	/// 참조 슬롯 인덱스
	mItemSlotIndex = slotIndex;
	item.SetLock( true );

	/// 아이템 이미지 체인지
	mpLinkItemIcon->SetItemIndex( item.GetIndex() );
	mpLinkItemIcon->ChangeImage( define->GetIconParam(), LINKICON_SIZE, LINKICON_SIZE );
	return true;
}

void cChatWindow::DeleteLinkItem()
{
	if( mItemSlotIndex == UINT_MAX )
		return;

	mpLinkItemIcon->ChangeImage( 0 );
	mpLinkItemIcon->SetItemIndex( 0 );
	mpLinkItemIcon->SetTipType( eTOOLTIP_NONE );

	/// 아이템 락 초기화
	if( mItemSlotIndex <= MAX_INVENTORY )
	{
		cItem& oldItem = ITEMMAN->GetItem( mItemSlotIndex );
		oldItem.SetLock( false );
		mItemSlotIndex = UINT_MAX;
	}
}

cUIRect cChatWindow::GetSelectButtonRect()
{
	cUIRect rc(0, 0, 0, 0);
	if( mpSelectSkin && mpChatBox )
	{
		rc.mLeft = GetAbsoluteRect().mLeft + mpSelectSkin->mSkinInfo->mX;
		rc.mTop = mpChatBox->GetAbsoluteRect().mBottom + mpSelectSkin->mSkinInfo->mY;
		rc.mRight = rc.mLeft + mpSelectSkin->mSkinInfo->mWidth;
		rc.mBottom = rc.mTop + mpSelectSkin->mSkinInfo->mHeight;
	}
	return rc;
}

LPCTSTR cChatWindow::GetWhisperName()
{
	return ( mpChatEditWhisper ) ? mpChatEditWhisper->GetText() : 0;
}

unsigned int cChatWindow::GetMaxRowInPage()
{
	return ( mpChatBox ) ? mpChatBox->GetMaxRowInPage() : 0;
}

void cChatWindow::InitBoxSize( unsigned int size )
{
	if( size == 0 )
		return;

	if( size > mpChatBox->GetMaxRowInPage() )
	{
		int row = size - mpChatBox->GetMaxRowInPage();
		int rowHeight = mpChatBox->GetRowHeight() * row;
		UpdateSize( rowHeight );
	}
	else if( size < mpChatBox->GetMaxRowInPage() )
	{
		int row = mpChatBox->GetMaxRowInPage() - size;
		int rowHeight = mpChatBox->GetRowHeight() * row;
		UpdateSize( -rowHeight );
	}
}

void cChatWindow::SetPress( bool normal, bool party, bool guild, bool shout, bool trade, bool whisper, bool system )
{
	cUINode* pNormal = GetChild( eUIID_CHATWINDOW_NORMAL );
	if( pNormal )
		pNormal->SetPress( normal );

	cUINode* pParty = GetChild( eUIID_CHATWINDOW_PARTY );
	if( pParty )
		pParty->SetPress( party );

	cUINode* pGuild = GetChild( eUIID_CHATWINDOW_GUILD );
	if( pGuild )
		pGuild->SetPress( guild );

	cUINode* pShout = GetChild( eUIID_CHATWINDOW_SHOUT );
	if( pShout )
		pShout->SetPress( shout );

	cUINode* pTrade = GetChild( eUIID_CHATWINDOW_TRADE );
	if( pTrade )
		pTrade->SetPress( shout );

	cUINode* pWhisper = GetChild( eUIID_CHATWINDOW_WHISPER );
	if( pWhisper )
		pWhisper->SetPress( whisper );

	cUINode* pSystem = GetChild( eUIID_CHATWINDOW_SYSTEM );
	if( pSystem )
		pSystem->SetPress( system );
}

bool cChatWindow::IsPressNormal()
{
	cUINode* pNormal = GetChild( eUIID_CHATWINDOW_NORMAL );
	if( pNormal && pNormal->IsPress() == true )
		return true;

	return false;
}

bool cChatWindow::IsPressParty()
{
	cUINode* pParty = GetChild( eUIID_CHATWINDOW_PARTY );
	if( pParty && pParty->IsPress() == true )
		return true;

	return false;
}

bool cChatWindow::IsPressGuild()
{
	cUINode* pGuild = GetChild( eUIID_CHATWINDOW_GUILD );
	if( pGuild && pGuild->IsPress() == true )
		return true;

	return false;
}

bool cChatWindow::IsPressShout()
{
	cUINode* pShout = GetChild( eUIID_CHATWINDOW_SHOUT );
	if( pShout && pShout->IsPress() == true )
		return true;

	return false;
}

bool cChatWindow::IsPressTrade()
{
	cUINode* pTrade = GetChild( eUIID_CHATWINDOW_TRADE );
	if( pTrade && pTrade->IsPress() == true )
		return true;

	return false;
}

bool cChatWindow::IsPressWhisper()
{
	cUINode* pWhisper = GetChild( eUIID_CHATWINDOW_WHISPER );
	if( pWhisper && pWhisper->IsPress() == true )
		return true;

	return false;
}

bool cChatWindow::IsPressSystem()
{
	cUINode* pSystem = GetChild( eUIID_CHATWINDOW_SYSTEM );
	if( pSystem && pSystem->IsPress() == true )
		return true;

	return false;
}


//////////////////////////////////////////////////////////////////
//// 버튼 윈도우
cChatButtonWindow::cChatButtonWindow()
{

}

cChatButtonWindow::~cChatButtonWindow()
{

}

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

	/// 기본세팅
	cUINode* pNormal = GetChild( eUIID_CHATBUTTON_NORMAL );
	if( pNormal )
		pNormal->SetPress( true );

	cUINode* pParty = GetChild( eUIID_CHATBUTTON_PARTY );
	if( pParty )
		pParty->SetPress( true );

	cUINode* pGuild = GetChild( eUIID_CHATBUTTON_GUILD );
	if( pGuild )
		pGuild->SetPress( true );

	cUINode* pShout = GetChild( eUIID_CHATBUTTON_SHOUT );
	if( pShout )
		pShout->SetPress( true );

	cUINode* pTrade = GetChild( eUIID_CHATBUTTON_TRADE );
	if( pTrade )
		pTrade->SetPress( true );

	cUINode* pWhisper = GetChild( eUIID_CHATBUTTON_WHISPER );
	if( pWhisper )
		pWhisper->SetPress( true );

	return true;
}

void cChatButtonWindow::OnCommand( cUINode* , unsigned int id )
{
	cChatWindow* win = GAMEUI->GetChatWindow();
	if( win )
	{
		switch( id )
		{	
		case eUIID_CHATBUTTON_NORMAL:
			win->UpdateChatType( eCHAT_NORMAL );
			break;
		case eUIID_CHATBUTTON_PARTY:
			win->UpdateChatType( eCHAT_PARTY );
			break;
		case eUIID_CHATBUTTON_GUILD:
			win->UpdateChatType( eCHAT_GUILD );
			break;
		case eUIID_CHATBUTTON_SHOUT:
			win->UpdateChatType( eCHAT_SHOUT );
			break;
		case eUIID_CHATBUTTON_TRADE:
			win->UpdateChatType( eCHAT_TRADE );
			break;
		case eUIID_CHATBUTTON_WHISPER:
			win->UpdateChatType( eCHAT_WHISPER );
			break;
		}

		Hide();
	}
}

void cChatButtonWindow::OnMouseOtherClick( const cUIPos& pos )
{
	cChatWindow* win = GAMEUI->GetChatWindow();
	if( win )
	{
		cUIRect& rect = win->GetSelectButtonRect();
		if( mAbsoluteRect.ContainPoint( pos ) == false && 
			rect.ContainPoint( pos ) == false )
		{
			Hide();
		}
	}
}

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

	cChatWindow* win = GAMEUI->GetChatWindow();
	if( win )
	{
		cUIRect& rect = win->GetSelectButtonRect();
		unsigned short x = rect.mLeft + mAbsoluteRect.mLeft;
		unsigned short y = rect.mTop - mAbsoluteRect.GetHeight();
		SetRelativePos( cUIPos(x, y) );
	}
}