#include "StdAfx.h"
#include "TargetWindow.h"

#include "Label.h"
#include "Gauge.h"
#include "ObjectManager.h"
#include "Hero.h"
#include "UIImage.h"

#include "PVPManager.h"
#include "SceneManager.h"
#include "EffectSceneNode.h"
#include "GameUIManager.h"
#include "DuelWindow.h"
#include "RButtonMenuWindow.h"

cTargetWindow::cTargetWindow()
: mpTargetNameLabel(0)
, mpTargetLevelLabel(0)
, mpHPGauge(0)
, mpTargetBuff(0)
, mpTargetEffect(0)
, mTargetEffectIdx((unsigned long)-1)
, mpNodeSkin(0)
, mpBack(0)
, mShowHPImage( true )
{
}

cTargetWindow::~cTargetWindow()
{
	SAFE_DELETE( mpBack );
}

void cTargetWindow::OnShow()
{
	cUIWindow::OnShow();

	if( mpTargetBuff )
		mpTargetBuff->ShowTop();
}

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

	if( mTargetEffectIdx != (unsigned long)-1 )
	{
		cEffectSceneNode* node = SCENEMAN->GetEffectSceneNode( mTargetEffectIdx );
		if( node )
		{
			assert( node == mpTargetEffect );
			node->Remove();
		}
		mpTargetEffect = 0;
		mTargetEffectIdx = (unsigned long)-1;
	}

	if( mpTargetBuff )
		mpTargetBuff->Hide();

	HERO->SetTargetObject( eOBJECTTYPE_NONE, 0 );
}

void cTargetWindow::UIStageIn()
{
	if( mTargetEffectIdx != (unsigned long)-1 )
	{
		cEffectSceneNode* node = SCENEMAN->GetEffectSceneNode( mTargetEffectIdx );
		if( node )
		{
			assert( node == mpTargetEffect );
			node->Remove();
		}
		mpTargetEffect = 0;
		mTargetEffectIdx = (unsigned long)-1;
	}
}

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

	mpHPGauge = (cGauge*)GetChild( eUIID_GAME_TARGET_HP_GAUGE_BAR );
	mpTargetNameLabel = (cLabel*)GetChild( eUIID_GAME_TARGET_NAME_LABEL );
	mpTargetLevelLabel = (cLabel*)GetChild( eUIID_GAME_TARGET_LEVEL_LABEL );
	mpTargetBuff = (cTargetBuff*)GetChild( eUIID_GAME_TARGET_BUFFWINDOW );

	cUISkin* pSkin = UIMAN->GetSkin();
	if( !pSkin )
		return false;

	mpNodeSkin = pSkin->GetNodeSkin( mSkinName );
	if( !mpNodeSkin )
		return false;

	/// 이미지 생성
	cUINodeSkin* imageSkin = pSkin->GetNodeSkin( "Target_Back" );
	if( imageSkin && imageSkin->mpTexture )
	{
		mpBack = new cUIImage( imageSkin->mpTexture );

		/// 텍스처 영역 설정
		unsigned int tx = imageSkin->mSkinInfo->mTexX;
		unsigned int ty = imageSkin->mSkinInfo->mTexY;
		unsigned int tw = imageSkin->mSkinInfo->mWidth;
		unsigned int th = imageSkin->mSkinInfo->mHeight;
		mpBack->SetTextureRect( tx, ty, tx + tw, ty + th );
		/// 이미지 영역을 갱신
		mpBack->SetScreenRect( mAbsoluteRect );
	}
	return true;
}

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

	if( mpBack && mpNodeSkin )
	{
		cUIRect rc;
		rc.mLeft = GetAbsoluteRect().mLeft;
		rc.mTop = GetAbsoluteRect().mTop;
		rc.mRight = mpNodeSkin->mSkinInfo->mWidth + rc.mLeft;
		rc.mBottom = mpNodeSkin->mSkinInfo->mHeight + rc.mTop;
		mpBack->SetScreenRect( rc );
	}
}

void cTargetWindow::UpdateSkin()
{
	if( GAMEUI->IsDuelMode() == false )
	{
		cUIWindow::UpdateSkin();
	}
}

///
void cTargetWindow::OnProcess( unsigned long deltaTime, unsigned long accumTime )
{
	if( mVisible == false )
		return;

	assert( HERO );
	cBaseObject* pTarget = HERO->GetTargetObject();
	if( pTarget )
	{
		if( mpHPGauge )
		{
			mpHPGauge->SetMaxValue( (float)pTarget->GetMaxHP() );
			mpHPGauge->SetGaugeNoAni( (float)pTarget->GetHP() );
		}

		if( pTarget->IsDie() )
		{
			if( mTargetEffectIdx != (unsigned long)-1 )
			{
				cEffectSceneNode* node = SCENEMAN->GetEffectSceneNode( mTargetEffectIdx );
				if( node )
				{
					assert( node == mpTargetEffect );
					node->Remove();
				}
				mpTargetEffect = 0;
				mTargetEffectIdx = (unsigned long)-1;
			}
		}
	}

	cUIWindow::OnProcess( deltaTime, accumTime );
}

void cTargetWindow::OnRender( cUIFontItemKeeper* pKeeper )
{
	if( mpBack )
		mpBack->Draw();

	cUIWindow::OnRender( pKeeper );
}

void cTargetWindow::UpdateWindow()
{
	assert( HERO );
	cBaseObject* pTarget = HERO->GetTargetObject();
	if( pTarget == 0 )
	{
		Hide();
		return;
	}

	/// 상황에 따라 게이지를 보인다
	if( mpHPGauge )
		mpHPGauge->Hide();

	mShowHPImage = false;

	///////////////////////////////////
	switch( pTarget->GetObjectType() )
	{
	case eOBJECTTYPE_PLAYER:
		{
			if( PVPMAN->IsEnableBattle() && PVPMAN->IsMyTeam( (cPlayer*)pTarget) == false ) 
			{
				int textIdx = 0;
				switch( ((cPlayer*)pTarget)->GetForceType() )
				{
				case eFORCETYPE_NONE:	textIdx = 119;	break;
				case eFORCETYPE_FIRE:	textIdx = 120;	break;
				case eFORCETYPE_WATER:  textIdx = 121;	break;
				case eFORCETYPE_WIND:	textIdx = 122;	break;
				case eFORCETYPE_EARTH:	textIdx = 123;	break;
				}
				SetTargetInfo( pTarget->GetLevel(), (LPTSTR)UIMAN->GetUIText( textIdx ) );
			}
			else
			{
				SetTargetInfo( pTarget->GetLevel(), pTarget->GetName() );
			}

			if( mpHPGauge )
				mpHPGauge->Show();

			mShowHPImage = true;
		}
		break;
	case eOBJECTTYPE_HERO:
	case eOBJECTTYPE_MONSTER:
		{
			SetTargetInfo( pTarget->GetLevel(), pTarget->GetName() );

			if( mpHPGauge )
				mpHPGauge->Show();

			mShowHPImage = true;
		}
		break;
	case eOBJECTTYPE_NPC:
		{
			if( mpTargetLevelLabel )
				mpTargetLevelLabel->Clear();

			if( mpTargetNameLabel )
			{
				mpTargetNameLabel->SetTextColor( eCOLOR_WHITE );
				mpTargetNameLabel->SetText( pTarget->GetName() );
			}
		}
		break;
	default:
		Hide();
		return;
	}

	/// 위치 갱신
	if( GAMEUI->IsDuelMode() == true )
	{
		cDuelWindow* win = GAMEUI->GetDuelWindow();
		if( win )
		{
			cUIPos pos = win->GetAbsoluteRect().GetCenter();
			SetRelativePos( cUIPos( pos.mX - GetAbsoluteRect().GetWidth()/2, win->GetAbsoluteRect().mBottom + 5 ) );
		}
	}
	else
	{
		int x = (int)(( GetScreenWidth() - GetAbsoluteRect().GetWidth() ) * 0.5f);
		SetRelativePos( cUIPos( x, 0 ) );
	}

	if( UIMAN->IsShowNpcBack() == false )
		ShowTop();

	SetTargetEffect( pTarget );
	UpdateSize();
}

void cTargetWindow::SetTargetEffect( cBaseObject* pObj )
{
	if( !pObj )
	{
		assert(0);
		return;
	}

	if( mTargetEffectIdx != (unsigned long)-1 )
	{
		cEffectSceneNode* node = SCENEMAN->GetEffectSceneNode( mTargetEffectIdx );
		if( node )
		{
			assert( node == mpTargetEffect );
			node->Remove();
		}
		mpTargetEffect = 0;
		mTargetEffectIdx = (unsigned long)-1;
	}

	NiTransform trans;
	trans.MakeIdentity();
	trans.m_Translate = NiPoint3( 0.0f, 0.0f, 10.0f );

	switch( pObj->GetObjectType() )
	{
	case eOBJECTTYPE_HERO:
	case eOBJECTTYPE_PLAYER:
		{
			mpTargetEffect = pObj->SetLinkdEffect( eLINK_FOOT, "./Data/Effect/Eff_PC_Target_01.nif", &trans, true, true );
		}
		break;
	case eOBJECTTYPE_NPC:
		{
			mpTargetEffect = pObj->SetLinkdEffect( eLINK_FOOT, "./Data/Effect/Eff_PC_Target_01.nif", &trans, true, true );
		}
		break;
	case eOBJECTTYPE_MONSTER:
		{
			mpTargetEffect = pObj->SetLinkdEffect( eLINK_FOOT, "./Data/Effect/Eff_PC_Target_02.nif", &trans, true, true );
		}
		break;
	default:
		break;
	}

	if( mpTargetEffect )
		mTargetEffectIdx = mpTargetEffect->GetIndexByManger();
}

void cTargetWindow::ClearBuff()
{
	if( mpTargetBuff )
		mpTargetBuff->Clear();
}

void cTargetWindow::AddBuff(unsigned long uniqueIdx, unsigned long influenceIdx )
{
	if( mpTargetBuff )
	{
		mpTargetBuff->AddBuff( uniqueIdx, influenceIdx );

		if( IsVisible() == true )
			mpTargetBuff->ShowTop();
	}
}

void cTargetWindow::DelBuff( unsigned long uniqueIdx )
{
	if( mpTargetBuff )
		mpTargetBuff->DelBuff( uniqueIdx );
}

void cTargetWindow::DelDeBuff( unsigned long uniqueIdx )
{
	if( mpTargetBuff )
		mpTargetBuff->DelDeBuff( uniqueIdx );
}

///
void cTargetWindow::SetHPGaugeSpeed( float s )
{
	if( mpHPGauge )
		mpHPGauge->SetGaugeSpeed( s );
}

///
void cTargetWindow::SetTargetInfo( char level, LPCTSTR name )
{
	char heroLv = HERO->GetLevel();
	char gap = level - heroLv;

	eText_Color color = eCOLOR_WHITE;

	/// 몬스터가 HERO보다 6레벨 이상일떄,
	if( gap >= 6 )
		color = eCOLOR_RED;
	/// 몬스터가 HERO보다 3 ~ 5레벨 이상일떄,
	else if( gap >= 3 )
		color = eCOLOR_PINK;
	else if( gap >= -2 )
		color = eCOLOR_GREEN;
	else if( gap >= -5 )
		color = eCOLOR_YELLOW;
	else
		color = eCOLOR_WHITE;

	if( mpTargetLevelLabel )
		mpTargetLevelLabel->SetValue( level );

	if( mpTargetNameLabel )
	{
		mpTargetNameLabel->SetTextColor( color );
		mpTargetNameLabel->SetText( name );
	}
}

void cTargetWindow::UpdateSize()
{
	if( mpTargetBuff && mpNodeSkin )
	{
		cUISize size;
		size.mWidth = mpNodeSkin->mSkinInfo->mWidth;
		size.mHeight = mpNodeSkin->mSkinInfo->mHeight;

		if( mpTargetBuff->IsHaveBuff() )
			size.mHeight += mpTargetBuff->GetAbsoluteRect().GetHeight();

		SetRelativeSize( size );
	}
}

void cTargetWindow::OnRButtonUp( const cUIPos& pos )
{
	cBaseObject* pTarget = HERO->GetTargetObject();
	if( pTarget && pTarget->GetObjectType() == eOBJECTTYPE_PLAYER )
	{
		cRButtonMenuWindow* win = GAMEUI->GetRButtonMenuWindow();
		if( win )
			win->PopUp( pos.mX, pos.mY, pTarget->GetObjectID(), pTarget->GetName(), ePopupPos_TargetWindow );
	}
}


///////////////////////////////////////////////////////////////
////// 타겟 버프

cTargetBuff::cTargetBuff()
{
	
}

cTargetBuff::~cTargetBuff()
{

}

bool cTargetBuff::SetSkin( const cUINodeSkin* pskin )
{
	if( pskin->IsKindof( eUINODE_WINDOW ) == false )
	{
		assert( 0 && "not window type" );
		return false;
	}

	cBuffWindowSkin* p = (cBuffWindowSkin*)pskin;
	if( !p )
		return false;

	/// 사이즈는 새로운 상대좌표 * 새로운 해상도 
	unsigned int x = pskin->mSkinInfo->mX;
	unsigned int y = pskin->mSkinInfo->mY;
	unsigned int w = pskin->mSkinInfo->mWidth;
	unsigned int h = pskin->mSkinInfo->mHeight;

	/// 적용
	SetRelativeRect( cUIRect( x, y, x + w, y + h) );

	SetAlpha( p->mAlpha );
	SetHoldView( p->mHoldView );

	mRow = p->mRow;
	mColumn = p->mColumn;
	mRowSpace = p->mRowSpace;
	mColumnSpace = p->mColumnSpace;
	mIconSize = p->mIconSize;

	mTimerEnabled = true;
	mTimeOut = 100;

	mpBuffSkin = p;
	return true;
}

void cTargetBuff::UpdateSkin()
{
	cPartyBuff::UpdateSkin();

	if( mpBuffSkin )
	{
		cUIRect rc;
		rc.mLeft = mRelativeRect.mLeft;
		rc.mTop = mpBuffSkin->mSkinInfo->mY;
		SetRelativePos( cUIPos( rc.mLeft, rc.mTop ) );
	}

	mUpdateList = true;
}

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

	mUpdatePos = true;
}

void cTargetBuff::UpdateWindowSize()
{
	/// window 재계산
	cUIRect rc;
	rc.mLeft = GetRelativeRect().mLeft;
	rc.mTop = GetRelativeRect().mTop;

	int buffCount = mBuffList.GetSize();
	int debuffCount = mDeBuffList.GetSize();

	if( buffCount > 0 )
		rc.mRight = rc.mLeft + (mIconSize+mColumnSpace) * buffCount - mColumnSpace;
	else
		rc.mRight = 0;

	if( debuffCount > 0 )
	{
		rc.mBottom = rc.mTop + (mIconSize+mRowSpace) * 2 - mRowSpace;

		/// 디버프가 더 만으면 디버프갯수로 재계싼
		if( buffCount < debuffCount )
			rc.mRight = rc.mLeft + (mIconSize+mColumnSpace) * debuffCount - mColumnSpace;
	}
	else
		rc.mBottom = rc.mTop + mIconSize;

	SetRelativeRect( rc );

	cTargetWindow* parent = (cTargetWindow*)mpParent;
	if( parent )
		parent->UpdateSize();
}