#include "StdAfx.h"
#include "SkillWindow.h"

#include "Skillscript.h"
#include "GameResourceManager.h"

#include "TabButton.h"
#include "Label.h"

#include "SkillManager.h"
#include "skillicon.h"
#include "SkillSheetWindow.h"
#include "DragWindow.h"

#include "QuickManager.h"
#include "GameUIManager.h"

#include "ObjectManager.h"
#include "Hero.h"

#include "UIManager.h"
#include "UIRootNode.h"

cSkillWindow::cSkillWindow()
: mpSkillPoint(0)
{
	mpCommuButton = 0;
	mpCommuSheetWindow = 0;

	mJobTabCount = 0;
}

cSkillWindow::~cSkillWindow()
{
}

void cSkillWindow::Clear()
{
	for( unsigned int i=0; i<mTabSheetArray.GetSize(); i++ )
	{
		if( mTabSheetArray[i] == mpCommuSheetWindow )
			continue;

		cSkillSheetWindow* p = (cSkillSheetWindow*)mTabSheetArray[i];
		if( p == 0 ) continue;

		p->Clear();
		RemoveChildComplete( p );
	}
	mTabSheetArray.Clear();

	for( unsigned int i=0; i<mTabButtonArray.GetSize(); i++ )
	{
		if( mTabButtonArray[i] == mpCommuButton )
			continue;

		cTabButton* p = (cTabButton*)mTabButtonArray[i];
		if( p == 0 ) continue;

		RemoveChildComplete( p );
	}
	mTabButtonArray.Clear();

	mJobTabCount = 0;

	UpdateCommuButtonPos();
	AddTab( mpCommuButton );
	AddSheet( mpCommuSheetWindow );
}

void cSkillWindow::UpdateSkin()
{
	cTabWindow::UpdateSkin();
	
	int size = mTabButtonArray.GetSize();
	if( size > 0)
		SetCurrent( size-1 );
}

void cSkillWindow::OnShow()
{
	cTabWindow::OnShow();

	int size = mTabButtonArray.GetSize();
	if( size > 0)
		SetCurrent( size-1 );
}

void cSkillWindow::OnHide()
{
	cTabWindow::OnHide();

	UIMAN->HideTip();
	UIMAN->HideDrag( this );

	/// npc 상점창이 열려있으면 닫기
	if( UIMAN->IsShowNpcBack() == true )
		UIMAN->HideNpcBack();
}

unsigned int cSkillWindow::AddJobTab( unsigned long jobIdx )
{
	cString str = "JobTabbutton";
//	str.Format("JobTabbutton%d", mTabButtonArray.GetSize()+1 );
	cTabButton* btn = new cTabButton;
	if( btn->CreateBySkinName( str, this, 1 ) == false )
	{
		assert(0);
		return 0;
	}

	///
	mCommuBtnBaseRect = btn->GetRelativeRect();
	btn->SetRelativePos( cUIPos( mCommuBtnBaseRect.mLeft + mCommuBtnBaseRect.GetWidth() * mJobTabCount, mCommuBtnBaseRect.mTop) );

	btn->SetText( GAMERESOURCEMAN->GetJobName( jobIdx ) );
	AddTab( btn );
	UIMAN->GetRootNode()->AddProcessChild( btn );

	mJobTabCount++;

	UpdateCommuButtonPos();


	///
	cSkillSheetWindow* sheet = new cSkillSheetWindow;
	if( sheet->CreateBySkinName( "skillSheet", this, (unsigned int)jobIdx ) == false )
	{
		assert(0);
		return 0;
	}

	cSkillTree* pTree = SKILLSCRIPT->GetSkillTree( jobIdx );
	assert(pTree);
	if( pTree )
	{
		sheet->InitSkillSheetInfo( jobIdx, pTree );
	}

	AddSheet( sheet );
	UIMAN->GetRootNode()->AddProcessChild( sheet );

	return mTabButtonArray.GetSize();
}

/// 주의사항 : 
bool cSkillWindow::OnCreate( cUINodeProperty* pproperty )
{
	if( cTabWindow::OnCreate( pproperty ) == false )
		return false;
	
	mpSkillPoint = (cLabel*)GetChild( eUIID_GAME_SKILL_POINT );
	mpSkillUsePoint = (cLabel*)GetChild( eUIID_GAME_SKILL_USEPOINT );

	cUINode* img = GetChild( eUIID_GAME_SKILL_USEPOINTIMG );
	if( img )
		img->SetEnabled( false );

	cString str = "JobTabbutton";
	mpCommuButton = new cTabButton;
	if( mpCommuButton->CreateBySkinName( str, this, 1 ) == false )
	{
		assert(0);
		return false;
	}
	mpCommuButton->SetText( UIMAN->GetUIText(24) );
	UpdateCommuButtonPos();
	AddTab(mpCommuButton);

	mpCommuSheetWindow = new cCommuSheetWindow;
	if( mpCommuSheetWindow->CreateBySkinName( "communitySheet", this, 2 ) == false )
	{
		assert(0);
		return false;
	}
	AddSheet( mpCommuSheetWindow );

	return true;
}

/// 주의사항 : 
void cSkillWindow::OnCommand( cUINode*, unsigned int id )
{
	/// 클로즈버튼누르면 안보임.
	switch(id)
	{
	case eUIID_GAME_SKILL_CLOSE_BUTTON:
		{
			Hide();
		}
		break;
	}
}

void cSkillWindow::OnIconDragged( cUINode* caller, unsigned int /*id*/, const cUIPos& pos, bool shift )
{
	cIcon* icon = (cIcon*)caller;
	if( icon == 0 )
		return;

	if( icon->GetIconType() == eICON_SKILL )
	{
		UIMAN->ShowDrag( this, DRAG_FROM_SKILLWINDOW, icon, pos, shift );
	}
	else if( icon->GetIconType() == eICON_COMMUNITY )
	{
		UIMAN->ShowDrag( this, DRAG_FROM_COMMUNITYWINDOW, icon, pos, shift );
	}
	else
	{
		assert(0);
	}
}

void cSkillWindow::UpdateSkillStep( unsigned long idx, unsigned char step )
{
	for( unsigned int i=0; i<mTabSheetArray.GetSize(); i++ )
	{
		if( mTabSheetArray[i] == mpCommuSheetWindow )
			continue;

		cSkillSheetWindow* p = (cSkillSheetWindow*)mTabSheetArray[i];
		if( p == 0 ) continue;

		cSkillIcon* icon = p->GetSkillIcon( idx );
		if( icon == 0 ) continue;

		assert( icon->GetSkillIdx() == idx );

		icon->SetSkillInfo( idx, step );
		icon->SetUsedFlag( true );
	}
}

/// 오라스킬 세팅용
void cSkillWindow::SetOnAura( unsigned long skillIdx, unsigned long AuraUniqueIdx, bool on )
{
	for( unsigned int i=0; i<mTabSheetArray.GetSize(); i++ )
	{
		if( mTabSheetArray[i] == mpCommuSheetWindow )
			continue;

		cSkillSheetWindow* p = (cSkillSheetWindow*)mTabSheetArray[i];
		if( p == 0 ) continue;

		cSkillIcon* icon = p->GetSkillIcon( skillIdx );
		if( icon == 0 ) continue;

		/// 오라스킬 세팅
		icon->SetAuraUniqueIdx( AuraUniqueIdx );
		icon->SetAuraOn( on );
		QUICKMAN->SetSkillAniAura( skillIdx, icon->GetAniParam() );
	}
}

unsigned long cSkillWindow::GetAuraUniqueIdx( unsigned long idx )
{
	for( unsigned int i=0; i<mTabSheetArray.GetSize(); i++ )
	{
		if( mTabSheetArray[i] == mpCommuSheetWindow )
			continue;

		cSkillSheetWindow* p = (cSkillSheetWindow*)mTabSheetArray[i];
		if( p == 0 ) continue;

		cSkillIcon* icon = p->GetSkillIcon( idx );
		if( icon == 0 ) continue;

		if( icon->IsAuraOn() == false )
			return 0;

		return icon->GetAuraUniqueIdx();
	}
	return 0;
}


void cSkillWindow::StartCoolTime( unsigned long idx, unsigned long restTime, unsigned long totalTime )
{
	for( unsigned int i=0; i<mTabSheetArray.GetSize(); i++ )
	{
		if( mTabSheetArray[i] == mpCommuSheetWindow )
			continue;

		cSkillSheetWindow* p = (cSkillSheetWindow*)mTabSheetArray[i];
		if( p == 0 ) continue;

		cSkillIcon* icon = p->GetSkillIcon( idx );
		if( icon == 0 ) continue;

		if( restTime == 0 || totalTime == 0 )
			continue;

        icon->StartDelay( totalTime );

		if( totalTime < restTime )
			icon->SetElapsedTime( 0 );
		else
			icon->SetElapsedTime( totalTime - restTime );

		
		if( restTime == totalTime )
			QUICKMAN->StartSkillCoolTime( idx, totalTime );
		else
			QUICKMAN->InitSkillCooltime( idx, restTime, totalTime );
	}
}

void cSkillWindow::DisableAllSkill()
{
	for( unsigned int i=0; i<mTabSheetArray.GetSize(); i++ )
	{
		if( mTabSheetArray[i] == mpCommuSheetWindow )
			continue;

		cSkillSheetWindow* p = (cSkillSheetWindow*)mTabSheetArray[i];
		if( p == 0 ) continue;

		p->DisableAllIcon();
	}
}

void cSkillWindow::UpdateSkillInfo()
{
	for( unsigned int i=0; i<mTabSheetArray.GetSize(); i++ )
	{
		if( mTabSheetArray[i] == mpCommuSheetWindow )
			continue;

		cSkillSheetWindow* p = (cSkillSheetWindow*)mTabSheetArray[i];
		if( p == 0 ) continue;
	}
}

void cSkillWindow::UpdateSkillPoint()
{
	if( mpSkillPoint )
		mpSkillPoint->SetValue( HERO->GetSkillPointRemain() );
}

void cSkillWindow::UpdateSkillUsePoint()
{
	if( mpSkillUsePoint )
	{
		if( mCurrentSheet == 0 )
			return;
		if( mCurrentSheet == mpCommuSheetWindow )
		{
			mpSkillUsePoint->Clear();
			return;
		}

		unsigned long totalUsSP = 0;
		unsigned long jobIdx = ((cSkillSheetWindow*)mCurrentSheet)->GetJobIdx();
		unsigned int jobLevel = GAMERESOURCEMAN->GetJobLevel( jobIdx );

		/// 직업 변환시 사용 스킬포인트 재계산..
		tPointerHashMap<unsigned long, void*>* keepSkillMap = SKILLMAN->GetKeepSkillMap();
		if( keepSkillMap )
		{
			tPointerHashMap<unsigned long, void*>::cIterator iter = keepSkillMap->Begin();
			while( iter != keepSkillMap->End() )
			{
				unsigned long skillIdx = (*iter).mFirst;
				sKeepSkill* pKeepSkill = (sKeepSkill*)((*iter).mSecond);
				if( pKeepSkill == 0 )
				{
					assert(0);
					return;
				}
				++iter;

				sPlayerSkillBaseInfo* pSkillInfo = SKILLSCRIPT->GetPlayerSkillInfo( skillIdx );
				if( pSkillInfo == 0 )
					continue;
				if( pSkillInfo->mJobStep != jobLevel )
					continue;
				if( pSkillInfo->mStepCount <= pKeepSkill->mStep )
				{
					assert(0);
					continue;
				}

				for( unsigned int i=0;i<=pKeepSkill->mStep;i++ )
				{
					sPlayerSkillStepInfo* pSkillStep = &pSkillInfo->mpSetpInfoArray[i];
					if( pSkillStep->mPlayerLevel != 0 )
						totalUsSP += pSkillStep->mRequireSP;
				}
			}
		}
		mpSkillUsePoint->SetValue( totalUsSP );
	}
}

void cSkillWindow::UpdateCommuButtonPos()
{
	if( mpCommuButton == 0 )
		return;

	mpCommuButton->SetRelativePos( cUIPos( mCommuBtnBaseRect.mLeft + mCommuBtnBaseRect.GetWidth() * mJobTabCount, mCommuBtnBaseRect.mTop) );
}

void cSkillWindow::RequestCommuSkill( unsigned long skillIndex )
{
	if( mpCommuSheetWindow )
		mpCommuSheetWindow->RequestCommuSkill( skillIndex );
}

void cSkillWindow::RequestLifeCommand( unsigned long comIdx, LPCTSTR value1, LPCSTR value2 )
{
	if( mpCommuSheetWindow )
		mpCommuSheetWindow->RequestLifeCommand( comIdx, value1, value2 );
}


void cSkillWindow::NetUnLockCommu()
{
	if( mpCommuSheetWindow )
		mpCommuSheetWindow->NetUnLock();
}

void cSkillWindow::SetCurrent( unsigned int index )
{
	cTabWindow::SetCurrent( index );

	UpdateSkillUsePoint();
}
