#include "StdAfx.h"
#include ".\skillsheetwindow.h"

#include "Skill_Common.h"
#include "SkillScript.h"
#include "CommunityScript.h"
#include "ResourceManager.h"
#include "UIImage.h"
#include "SkillExecuter.h"

#include "GameResourceManager.h"
#include "ChatManager.h"
#include "PartyManager.h"
#include "ItemManager.h"
#include "SkillManager.h"
#include "ObjectManager.h"
#include "TarotManager.h"
#include "Hero.h"

#include "UserSellWindow.h"
#include "SkillIcon.h"
#include "GameUIManager.h"
#include "UIMsgboxEvent.h"
#include "GuildManager.h"
#include "ItemMixManager.h"


cSkillSheetWindow::cSkillSheetWindow( eUINodeType type )
: cUIWindow( type )
, mpTreeInfo(0)
, mBackTex(0)
{
}

cSkillSheetWindow::~cSkillSheetWindow()
{
	mManagedIcon.Clear();
}

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

	if( mBackTex )
	{
		if( mpImage == 0 )
			mpImage = new cUIImage;

		mpImage->SetTexture( mBackTex );
		mpImage->SetTextureRect( 0, 0, mBackTex->GetWidth(), mBackTex->GetHeight() );
		mpImage->SetScreenRect( mAbsoluteRect );
	}

	UpdateTree();
}

void cSkillSheetWindow::InitSkillSheetInfo( unsigned long jobIdx, cSkillTree* pTree )
{
	mJobIdx = jobIdx;

	assert( pTree );

	mpTreeInfo = pTree;

	cString pathName;
	pathName.Format( "./Data/2DData/%s", pTree->mImageName.Cstr() );
	mBackTex = RESOURCEMAN->LoadTexture( pathName, false );
	if( mpImage == 0 )
		mpImage = new cUIImage;

	mpImage->SetTexture( mBackTex );
	mpImage->SetTextureRect( 0, 0, mBackTex->GetWidth(), mBackTex->GetHeight() );
	mpImage->SetScreenRect( mAbsoluteRect );

	for( unsigned int i=0; i<pTree->mIconCount; ++i )
	{
		sPlayerSkillBaseInfo* info = SKILLSCRIPT->GetPlayerSkillInfo( pTree->mIconList[i].skillIdx );
		if( info )
		{
			cIconParam* param = UIMAN->GetIconParam( info->mIconIdx );
			if( param )
			{
				cSkillIcon* pIcon = new cSkillIcon;
				if( pIcon->CreateBySkinName( "SkillIcon", this, i + 1 ) == false )
				{
					assert(0);
					continue;
				}
				pIcon->SetRelativePos( cUIPos(pTree->mIconList[i].uiPosX, pTree->mIconList[i].uiPosY) );
				pIcon->ChangeImage( param );

				/// 스킬 관련 정보 셋팅
				pIcon->SetSkillInfo( pTree->mIconList[i].skillIdx, -1 );

				if( pIcon->IsBaseSkill() )
					pIcon->SetUsedFlag( true );
				else
				{
					/// 보유 스킬 여부 체크
					if( SKILLMAN->GetKeepInfo( pTree->mIconList[i].skillIdx ) )
						pIcon->SetUsedFlag( true );
					else
						pIcon->SetUsedFlag( false );
				}

				if( mManagedIcon.Insert( pTree->mIconList[i].skillIdx ,pIcon ) == false )
				{
					assert(0);
				}
			}
		}
		else
		{
			assert(0);
			return;
		}
	}
	///
}

void cSkillSheetWindow::OnIconDragged( cUINode* pcaller, unsigned int id, const cUIPos& /*pos*/, bool shift )
{
	cSkillIcon* icon = (cSkillIcon*)pcaller;
	if( icon->IsActiveSkill() )
		SendEvent( mpParent, eUIEVENT_ICON_DRAGGED, pcaller, id, shift );
}

void cSkillSheetWindow::OnIconDoubleClicked( cUINode* pcaller, unsigned int /*id*/ )
{
	cSkillIcon* p = (cSkillIcon*)pcaller;
	unsigned long skillIdx = p->GetSkillIdx();

	HERO->SetWaitMoveFlag( false );
	if( skillIdx < NORMAL_ATTACK_SKILL_MAX )
	{
		if( HERO->GetState() != eOBJECT_STATE_ATTACK )
			SKILLEXECUTER->ExecuteAttack( HERO->GetTargetObject() );
	}
	else
	{
		if( SKILLMAN->IsUsedKeepSkill( skillIdx ) == true )
			SKILLEXECUTER->ExecuteSkill( skillIdx );
	}
}

void cSkillSheetWindow::OnLButtonDown( const cUIPos& pos, bool /*ctrl*/, bool /*alt*/, bool /*shift*/ )
{
	if( GetCapture() != this )
	{
		SetCapture();
	}

	/// 상대영역을 절대영역으로 바꾼다 
	cUIRect captionRc = GetAbsoluteRect();
	captionRc.mLeft = GetAbsoluteRect().mLeft + mCaptionRect.mLeft;
	captionRc.mRight = captionRc.mLeft + mCaptionRect.GetWidth();
	captionRc.mTop = GetAbsoluteRect().mTop + mCaptionRect.mTop;
	captionRc.mBottom = captionRc.mTop + mCaptionRect.GetHeight();

	/// 캡션영역 안에 포인터가 있어야먄 드래그한다 
	if( mpParent == (cUIContainer*)GetRoot() && captionRc.ContainPoint( pos ) )
	{
		mDragStart.mX = pos.mX;
		mDragStart.mY = pos.mY;

		mDragging = true;
	}
}

void cSkillSheetWindow::DisableAllIcon()
{
	cSkillIconList::cIterator i = mManagedIcon.Begin();
	cSkillIconList::cIterator iend = mManagedIcon.End();

	for( ; i != iend; ++i )
	{
		cSkillIcon* icon = (cSkillIcon*)(*i).mSecond;
		if( icon->IsBaseSkill() == false )
			icon->SetUsedFlag( false );
	}
}

void cSkillSheetWindow::UpdateTree()
{
	if( mpTreeInfo == 0 )
		return;

	for( unsigned int i=0; i<mpTreeInfo->mIconCount; ++i )
	{
		sPlayerSkillBaseInfo* info = SKILLSCRIPT->GetPlayerSkillInfo( mpTreeInfo->mIconList[i].skillIdx );
		if( info == 0 )
		{
			assert(0);
			return;
		}

		cIconParam* param = UIMAN->GetIconParam( info->mIconIdx );
		if( param == 0 ) continue;

		cSkillIcon* p = (cSkillIcon*)mManagedIcon.GetAt( mpTreeInfo->mIconList[i].skillIdx );
		if( p == 0 ) continue;

		p->SetRelativePos( cUIPos(mpTreeInfo->mIconList[i].uiPosX, mpTreeInfo->mIconList[i].uiPosY) );
		p->ChangeImage( param );

		if( p->IsBaseSkill() )
			p->SetUsedFlag( true );
		else
		{
			/// 보유 스킬 여부 체크
			if( SKILLMAN->GetKeepInfo( mpTreeInfo->mIconList[i].skillIdx ) )
				p->SetUsedFlag( true );
			else
				p->SetUsedFlag( false );
		}
	}
}

void cSkillSheetWindow::Clear()
{
	cSkillIconList::cIterator i = mManagedIcon.Begin();
	cSkillIconList::cIterator iend = mManagedIcon.End();

	for( ; i != iend; ++i )
	{
		cSkillIcon* icon = (cSkillIcon*)(*i).mSecond;
		if( icon == 0 ) continue;

		RemoveChildComplete( icon );
	}
	mManagedIcon.Clear();
}


////////////////////////////////////////////////////////////////////////
/// 생활관련 시트
cCommuSheetWindow::cCommuSheetWindow( eUINodeType type )
: cUIWindow( type )
{

}

cCommuSheetWindow::~cCommuSheetWindow()
{
	//cCommuIconList::cIterator i = mManagedIcon.Begin();
	//cCommuIconList::cIterator iend = mManagedIcon.End();
	//for( ; i != iend; ++i )
	//{
	//	cCommunityIcon* icon = (cCommunityIcon*)(*i).mSecond;
	//	if( icon )
	//		RemoveChildComplete( icon );
	//}
	mManagedIcon.Clear();
}

bool cCommuSheetWindow::OnCreate( cUINodeProperty* property )
{
	if( cUIWindow::OnCreate( property ) == false )
		return false;

	/// apply community script 
	cCommunityScript::cComHashMap* pCom = COMMUNITYSCRIPT->GetComSkillMap();
	if( pCom == 0 )
		return false;

	cCommunityScript::cComHashMap::cIterator iter = pCom->Begin();
	unsigned int i=0;
	for( ;iter != pCom->End() ; ++iter )
	{
		sCommunitySkillInfo* info = (sCommunitySkillInfo*)(*iter).mSecond;
		if( !info )
		{
			assert(0);
			return false;
		}

		cIconParam* param = UIMAN->GetIconParam( info->mIconIndex );
		if( param == 0 )
			continue;

		cCommunityIcon* pIcon = new cCommunityIcon;
		if( pIcon->CreateBySkinName( "SkillIcon", this, i + 100 ) == false )
		{
			assert(0);
			continue;
		}	
		pIcon->SetRelativePos( cUIPos(info->mPosX, info->mPosY) );
		pIcon->ChangeImage( param );
		pIcon->SetUsedFlag( true );

		pIcon->InitInfo( info->mIndex, (info->mType == 0)? false:true );

		if( mManagedIcon.Insert( info->mIndex ,pIcon ) == false )
		{
			assert(0);
		}

		i++;
	}

	return true;
}

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

	/// 세팅
	cCommunityScript::cComHashMap* pCom = COMMUNITYSCRIPT->GetComSkillMap();
	if( pCom )
	{
		cCommunityScript::cComHashMap::cIterator iter = pCom->Begin();
		for( ;iter != pCom->End() ; ++iter )
		{
			sCommunitySkillInfo* info = (sCommunitySkillInfo*)(*iter).mSecond;
			if( info )
			{
				cCommunityIcon* pIcon = (cCommunityIcon*)mManagedIcon.GetAt( info->mIndex );
				if( pIcon )
					pIcon->SetRelativePos( cUIPos(info->mPosX, info->mPosY) );
			}
		}
	}
}

void cCommuSheetWindow::OnIconDoubleClicked( cUINode* caller, unsigned int /*id*/ )
{
	cCommunityIcon* p = (cCommunityIcon*)caller;

	unsigned long comIdx = p->GetCommunityIndex();

	if( p->IsEmoting() )
	{
		///
		sCommunitySkillInfo* pInfo = COMMUNITYSCRIPT->GetCommunityInfo( comIdx );
		if( pInfo == 0 )
			return;

		if( HERO->GetState() == eOBJECT_STATE_IDLE )
		{
			RequestCommuSkill( comIdx );
		}
	}
	else
	{
		RequestLifeCommand( comIdx, 0, 0 );
	}
}

void cCommuSheetWindow::OnIconDragged( cUINode* caller, unsigned int id, const cUIPos& /*pos*/, bool shift )
{
//	cCommunityIcon* icon = (cCommunityIcon*)caller;
	SendEvent( mpParent, eUIEVENT_ICON_DRAGGED, caller, id, shift );
}

void cCommuSheetWindow::OnLButtonDown( const cUIPos& pos, bool /*ctrl*/, bool /*alt*/, bool /*shift*/ )
{
	if( GetCapture() != this )
	{
		SetCapture();
	}

	/// 상대영역을 절대영역으로 바꾼다 
	cUIRect captionRc = GetAbsoluteRect();
	captionRc.mLeft = GetAbsoluteRect().mLeft + mCaptionRect.mLeft;
	captionRc.mRight = captionRc.mLeft + mCaptionRect.GetWidth();
	captionRc.mTop = GetAbsoluteRect().mTop + mCaptionRect.mTop;
	captionRc.mBottom = captionRc.mTop + mCaptionRect.GetHeight();

	/// 캡션영역 안에 포인터가 있어야먄 드래그한다 
	if( mpParent == (cUIContainer*)GetRoot() && captionRc.ContainPoint( pos ) )
	{
		mDragStart.mX = pos.mX;
		mDragStart.mY = pos.mY;

		mDragging = true;
	}
}

void cCommuSheetWindow::RequestCommuSkill( unsigned long skillIndex )
{
	if( IsNetLock() == true )
		return;

	if( HERO->IsRideVehicle() == true )
		return;

	/// network msg
	MSG_REQ_PLAYER_COMMUNITYSKILL Msg;
	Msg.Category = NM_PLAYER;
	Msg.Protocol = NM_PLAYER_COMMUNITYSKILL_REQ;
	Msg.mCommunitySkillIdx = skillIndex;
	NETWORK->SendNetworkMsg( (char*)&Msg, sizeof(Msg) );

	/// 
	NetLock();
}

void cCommuSheetWindow::RequestLifeCommand( unsigned long comIdx, LPCTSTR value1, LPCSTR value2 )
{
	/// 상태검사
	if( GAMEUI->IsShowCardBook() == true )
	{
		UIMAN->CreateModal(	eStage_Game,
							eMBEVENT_NONE, 
							GAMERESOURCEMAN->GetGameText( 348 ),
							GAMERESOURCEMAN->GetGameText( 301 ), // 에러
							eSKIN_OK
							);
	}

	sCommunitySkillInfo* pInfo = COMMUNITYSCRIPT->GetCommunityInfo( comIdx );
	if( pInfo == 0 )
		return;

	switch( pInfo->mRoleIndex )
	{
	case eCOMMU_LIFE_REST:
		{
			HERO->ToggleSitDown();
		}
		break;
	case eCOMMU_LIFE_PARTY:
		{
			LPCTSTR targetName = value1;
			if( targetName == 0 )
			{
				cBaseObject* pTarget = HERO->GetTargetObject();
				if( pTarget == 0 )
				{
					CHATMANAGER->AddSystemMsg( eSYSTEM_NORMAL, GAMERESOURCEMAN->GetGameText( 121 ) );
					return;
				}
				targetName = pTarget->GetName();
			}
			PARTYMAN->RequestPartyAdd( targetName );
		}
		break;
	case eCOMMU_LIFE_TRADE:
		{
			LPCTSTR targetName = value1;
			if( targetName == 0 )
			{
				/// /거래 + 타겟팅 인지 검사
				cBaseObject* obj = HERO->GetTargetObject();
				if( obj )
				{
					if( obj->GetObjectType() == eOBJECTTYPE_PLAYER )
						ITEMMAN->TryToTradeAsk( (cPlayer*)obj );
					else
						CHATMANAGER->AddSystemMsg( eSYSTEM_NORMAL, GAMERESOURCEMAN->GetGameText( 142 ) );
				}
				else
				{
					CHATMANAGER->AddSystemMsg( eSYSTEM_NORMAL, GAMERESOURCEMAN->GetGameText( 121 ) );
				}
			}
			else
			{
				cPlayer* player = OBJECTMAN->GetPlayerByName( targetName );
				if( player )
					ITEMMAN->TryToTradeAsk( player );
				else
					CHATMANAGER->AddSystemMsg( eSYSTEM_NORMAL, GAMERESOURCEMAN->GetGameText( 142 ) );
			}
		}
		break;
	case eCOMMU_LIFE_TITLE:
		{
			cUIWindow* title = (cUIWindow*)GAMEUI->GetTitleWindow();
			if( title )
			{
				if( title->IsVisible() == false )
					title->ShowTop();
				else
					title->Hide();
			}
		}
		break;
	case eCOMMU_LIFE_ITEMMIX:
		{
			cUIWindow* pMix = (cUIWindow*)GAMEUI->GetItemMixWindow();
			if( pMix )
			{
				if( pMix->IsVisible() == false )
				{
					ITEMMIXMAN->ItemMixOpen();
				}
				else
				{
					ITEMMIXMAN->ItemMixCancel();
				}
			}
		}
		break;
	case eCOMMU_LIFE_STREETSTALL:
		{
			cUserSellWindow* pUserSell = GAMEUI->GetUserSellWindow();
			if( pUserSell && pUserSell->IsVisible() == false )
				ITEMMAN->TryToUserSellOpen();
		}
		break;
	case eCOMMU_LIFE_DUEL:
		{
			HERO->DuelRequest();
		}
		break;
	case eCOMMU_LIFE_ENHANCED:
		{
			/// 아이템 강화창 열기
			cUIWindow* pEnhan = (cUIWindow*)GAMEUI->GetEnhancedWindow();
			if( pEnhan )
			{
				if( pEnhan->IsVisible() == false )
					pEnhan->ShowTop();
				else
					pEnhan->Hide();
			}

			cUIWindow* inven = (cUIWindow*)GAMEUI->GetInventoryWindow();
			if( pEnhan->IsVisible() == true )
			{
				if( inven && inven->IsVisible() == false )
					inven->ShowTop(false, false);
			}
		}
		break;
	case eCOMMU_LIFE_PUTCARD:
		{
			cUIWindow* putcard = (cUIWindow*)GAMEUI->GetPutCardWindow();
			if( putcard )
			{
				if( putcard->IsVisible() == false )
					putcard->ShowTop();
				else
					putcard->Hide();
			}

			cUIWindow* inven = (cUIWindow*)GAMEUI->GetInventoryWindow();
			if( putcard->IsVisible() == true )
			{
				if( inven && inven->IsVisible() == false )
					inven->ShowTop(false, false);
			}
		}
		break;
	case eCOMMU_LIFE_TAROT:
		{
			/// 타롯열기
			TAROTMAN->ReadyReaderTarotNet();
		}
		break;
	case eCOMMU_LIFE_STREETSTALL_FIND:
		{
			/// 노점 검색
			cUIWindow* search = (cUIWindow*)GAMEUI->GetUserSellSearchWindow();
			if( search )
			{
				if( search->IsVisible() == false )
					search->ShowTop();
				else
					search->Hide();
			}
		}
		break;
	}
}
