#include "StdAfx.h"
#include "SkillTipWindow.h"
#include "FontAgent.h"
#include "PlaneObject.h"
#include "Skill_Common.h"
#include "SkillScript.h"
#include "GameResourceManager.h"

#include "ObjectManager.h"
#include "Hero.h"
#include "StatusScript.h"
#include "SkillManager.h"
#include "ItemManager.h"
#include "TotemScript.h"

const unsigned int mSecondColWidth = 80;

cSkillTipWindow::cSkillTipWindow()
: mRightIndex(0)
, mRightMaxWidth(0)
, mRequireIndex(0)
, mSaveSkillIndex(0)
, mTimeTipIdx(0)
{
	mLimitMaxWidth = 230;

	mBottomIndex = 0;
	mBottomRightIndex = 0;
}

cSkillTipWindow::~cSkillTipWindow()
{

}
void cSkillTipWindow::Clear()
{
	cTipWindow::Clear();

	for( unsigned int i=0; i<MAX_RIGHT_TIP; i++ )
		mRightTip[i].mGapCount = 0;

	mRightIndex = 0;
	mRightMaxWidth = 0;

	/// 하단 표현을 위한 변수
	mBottomIndex = 0;
	mBottomRightIndex = 0;

	/// 조건 표현
	for( unsigned int i=0; i<MAX_RIGHT_TIP; i++ )
	{
		mRequireValue[i][0].mString.Clear();
		mRequireValue[i][1].mString.Clear();
		mRequireValue[i][2].mString.Clear();
		mRequireValue[i][3].mString.Clear();

		mRequireValue[i][0].mGapCount = 0;
		mRequireValue[i][1].mGapCount = 0;
		mRequireValue[i][2].mGapCount = 0;
		mRequireValue[i][3].mGapCount = 0;
	}
	mRequireIndex = 0;

	mSaveCoolTime.Clear();
	mSaveSkillIndex = 0;
	mTimeTipIdx = 0;
}

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

	mTimerEnabled = false;
	mSaveCoolTime.Clear();
	mSaveSkillIndex = 0;
	mTimeTipIdx = 0;
}

void cSkillTipWindow::OnRender( cUIFontItemKeeper* fontKeeper )
{
	if( mVisible == false )
		return;

	/// 배경
	mMiddleBack->Draw();

	int px = mX + GAP_SIZE;
	int py = mY;

	/// 데이터 출력
	unsigned int bottomStartY = 0;
	for( unsigned int row = 0; row < mIndex; ++row )
	{
		cStringT& str = mToolTip[row].mString;
		if( str.IsEmpty() )
			continue;

		py += mToolTip[row].mGapCount * GAP_SIZE;
		if( mBottomIndex != 0 &&row == mBottomIndex )
		{
			/// 하단 찍기
			unsigned int width = mMaxWidth + mRightMaxWidth + GAP_SIZE * 2 + 20;
			int x = px + width/2 - 6;

			fontKeeper->AddFontItem( cFontAgent::eFont_UI, _T("▽"), x, py, eCOLOR_WHITE );

			py += mToolTip[row].mGapCount * GAP_SIZE;
			bottomStartY = py;
		}

		/// 다음줄 출력 
		unsigned int color = mToolTip[row].mColor;
		fontKeeper->AddFontItem( cFontAgent::eFont_System, (LPCTSTR)str.Cstr(), px, py, color );

		py += mLineHeight;
	}

	///
	for( unsigned int row = 0; row < mRequireIndex; ++row )
	{
		unsigned int x = px;
		py += mRequireValue[row][0].mGapCount * GAP_SIZE;
		for( unsigned int i=0; i<4; i++ )
		{
			cStringT& str = mRequireValue[row][i].mString;
			if( str.IsEmpty() )
				continue;

			unsigned int color = mRequireValue[row][i].mColor;
			fontKeeper->AddFontItem( cFontAgent::eFont_System, (LPCTSTR)str.Cstr(), x, py, color );

			x += FONTAGENT->GetTextExtent( cFontAgent::eFont_System, (LPCTSTR)str.Cstr(), str.GetSize() );
		}
		py += mLineHeight;
	}

	///
	px = mX + GAP_SIZE + mMaxWidth + mRightMaxWidth + 20;
	py = mY;
	for( unsigned int row = 0; row < mRightIndex; ++row )
	{
		cStringT& str = mRightTip[row].mString;
		if( str.IsEmpty() )
			continue;

		/// 오른쪽 정렬 계산
		unsigned int width = FONTAGENT->GetTextExtent( cFontAgent::eFont_System, (LPCTSTR)str.Cstr(), str.GetSize() );
		unsigned int x = px - width;
		if( mSaveSkillIndex > 0 )
			x -= 4;

		py += mRightTip[row].mGapCount * GAP_SIZE;
		if( mBottomRightIndex != 0 && row == mBottomRightIndex )
		{
			py = bottomStartY;
		}

		unsigned int color = mRightTip[row].mColor;
		fontKeeper->AddFontItem( cFontAgent::eFont_System, (LPCTSTR)str.Cstr(), x, py, color );

		py += mLineHeight;
	}

	///
	fontKeeper->DrawAll();
}

void cSkillTipWindow::CalcRightMaxWidth( const cStringT& str )
{
	unsigned int width = FONTAGENT->GetTextExtent( cFontAgent::eFont_System, (LPCTSTR)str.Cstr(), str.GetSize() );
	if( width > mRightMaxWidth )
		mRightMaxWidth = width;

	if( mRightMaxWidth > mSecondColWidth )
		mRightMaxWidth = mSecondColWidth;
}

bool cSkillTipWindow::SetSkill( eTip_Kind tipkind, const cUIPos& pos, unsigned long skillIndex, char skillStep, bool store )
{
	/// 
	Clear();

	if( tipkind == eTIP_SKILL )
	{
		if( SetNormalTip( skillIndex, skillStep, store ) == false )
			return false;
	}
	else if( tipkind == eTIP_QUICK )
	{
		if( SetQuickTip( skillIndex, skillStep ) == false )
			return false;
	}

	/// 최소 너비 제한 설정
	if( mMaxWidth < mLimitMinWidth )
		mMaxWidth = mLimitMinWidth;

	/// 세팅
	mX = pos.mX + 25;
	mY = pos.mY + 25;
	unsigned int w = mMaxWidth + mRightMaxWidth + GAP_SIZE * 2 + 20; 
	unsigned int h = (mIndex+mRequireIndex)*mLineHeight + (mGapCount+1)*GAP_SIZE;
	if( mBottomIndex != 0 )
	{
		h += mToolTip[mBottomIndex].mGapCount * GAP_SIZE;
	}

	unsigned int count = 0;
	for( unsigned int i=0;i<mRequireIndex;i++ )
	{
		count += mRequireValue[i][0].mGapCount;
	}
	h += count * GAP_SIZE;

	/// 화면 안벗어나게 조정
	if( mX + w > GetScreenWidth() )
	{	
		mX -= ((mX + w) - GetScreenWidth());
	}

	if( mY + h > GetScreenHeight() )
	{
		mY -= ((mY + h) - GetScreenHeight());
	}

	/// 스킬재사용시간 출력시 여유분 추가
	if( mSaveSkillIndex > 0 )
	{
		if( w <= 280 )
			w = 280;
	}

	mMiddleBack->SetScreenRect( (short)mX, (short)mY, (unsigned short)w, (unsigned short)h );
	mMiddleBack->SetColorA( 0.6f, 0.6f, 0.6f, 0.6f );
	SetRelativePos( cUIPos( mX, mY ) );

	return true;
}

/// 습득하고자 하는 스킬 단계 인덱스 
bool cSkillTipWindow::SetNormalTip( unsigned long skillIdx, char skillStep, bool store )
{
	sPlayerSkillBaseInfo* pInfo = SKILLSCRIPT->GetPlayerSkillInfo( skillIdx );
	if( pInfo == 0 )
	{
		return false;
	}

	/// 이름
	AddGap( 1 );
	SetName( pInfo, eCOLOR_YELLOW );

	AddGap( 2 );
	if( skillStep > -1 )
	/// 현재 스텝 정보를 표현한다.
	{
		/// 시전 유형
		SetShotType( pInfo, eCOLOR_WHITE );

		unsigned int curStep = (unsigned int)skillStep;
		if( pInfo->mStepCount <= curStep )
		{
			assert(0);
		}

		sPlayerSkillStepInfo curStepInfo = pInfo->mpSetpInfoArray[curStep];

		/// 사용 장비
		SetEquip( pInfo, eCOLOR_WHITE );

		/// 시전시간
		SetCastingTime( pInfo, &curStepInfo, eCOLOR_WHITE );

		/// 재사용시간
		if( store == true )
			SetCoolTime( &curStepInfo, eCOLOR_WHITE, 0 );
		else
			SetCoolTime( &curStepInfo, eCOLOR_WHITE, skillIdx );

		/// 소모 비용
		SetUsedValue( pInfo, &curStepInfo, eCOLOR_WHITE );

		cStringT temp;
		if( curStepInfo.mApplyValue1 != 0 || curStepInfo.mApplyValue2 != 0 )
		{
			if( curStepInfo.mApplyValue1 != 0 && curStepInfo.mApplyValue2 != 0 )
			{
				AddGap( 1 );
				temp.Format( GAMERESOURCEMAN->GetSkillToolTipText( curStepInfo.mToolTipIdx ), curStepInfo.mApplyValue1, curStepInfo.mApplyValue2 );
				CheckText( (LPCTSTR)temp.Cstr(), eCOLOR_YELLOW );
			}
			else if( curStepInfo.mApplyValue1 != 0 )
			{
				AddGap( 1 );
				temp.Format( GAMERESOURCEMAN->GetSkillToolTipText( curStepInfo.mToolTipIdx ), curStepInfo.mApplyValue1 );
				CheckText( (LPCTSTR)temp.Cstr(), eCOLOR_YELLOW );
			}
		}
		else
		{
			/// 일반 툴팁 출력
			AddGap( 1 );
			CheckText( GAMERESOURCEMAN->GetSkillToolTipText( curStepInfo.mToolTipIdx ), eCOLOR_YELLOW );
		}

		/// 효과

		if( pInfo->mType == eSKILLTYPE_TOTEM )
		{
			sTotemScript* totem = TOTEMSCRIPT->GetTotemInfo( curStepInfo.mInfulenceIdx );
			if( totem )
				SetInfluence( totem->mInfluenceIdx );
		}
		else
			SetInfluence( curStepInfo.mInfulenceIdx );

		/// 오른쪽 툴팁
		AddRightGap( 2 );
		SetRightAttribute( pInfo, eCOLOR_WHITE ); 

		AddRightGap( 1 );
		SetRightStepInfo( pInfo, curStep, eCOLOR_WHITE ); 
		SetRightTargetDist( pInfo, &curStepInfo, eCOLOR_WHITE, skillIdx ); 
		SetRightBound( &curStepInfo, eCOLOR_WHITE ); 
		
		mBottomIndex = mIndex;
		mBottomRightIndex = mRightIndex;

		/// 라인 띄기 
		if( pInfo->mStepCount > (unsigned int)(skillStep + 1) )
			AddGap(2);
		else
			return true;
	}

	if( pInfo->mStepCount <= (unsigned int)skillStep+1 )
	{
		assert(0);
	}

	sPlayerSkillStepInfo trainStepInfo = pInfo->mpSetpInfoArray[skillStep+1];

	/// 시전 유형
	SetShotType( pInfo, eCOLOR_WHITE );

	/// 사용 장비
	SetEquip( pInfo, eCOLOR_WHITE );

	/// 시전시간
	SetCastingTime( pInfo, &trainStepInfo, eCOLOR_WHITE );

	/// 재사용시간
	SetCoolTime( &trainStepInfo, eCOLOR_WHITE, 0 );

	/// 소모 비용
	SetUsedValue( pInfo, &trainStepInfo, eCOLOR_WHITE );

	cStringT temp;
	if( trainStepInfo.mApplyValue1 != 0 || trainStepInfo.mApplyValue2 != 0 )
	{
		if( trainStepInfo.mApplyValue1 != 0 && trainStepInfo.mApplyValue2 != 0 )
		{
			AddGap( 1 );
			temp.Format( GAMERESOURCEMAN->GetSkillToolTipText( trainStepInfo.mToolTipIdx ), trainStepInfo.mApplyValue1, trainStepInfo.mApplyValue2 );
			CheckText( (LPCTSTR)temp.Cstr(), eCOLOR_YELLOW );
		}
		else if( trainStepInfo.mApplyValue1 != 0 )
		{
			AddGap( 1 );
			temp.Format( GAMERESOURCEMAN->GetSkillToolTipText( trainStepInfo.mToolTipIdx ), trainStepInfo.mApplyValue1 );
			CheckText( (LPCTSTR)temp.Cstr(), eCOLOR_YELLOW );
		}
	}
	else
	{
		/// 일반 툴팁 출력
		AddGap( 1 );
		CheckText( GAMERESOURCEMAN->GetSkillToolTipText( trainStepInfo.mToolTipIdx ), eCOLOR_YELLOW );
	}

	if( pInfo->mType == eSKILLTYPE_TOTEM )
	{
		sTotemScript* totem = TOTEMSCRIPT->GetTotemInfo( trainStepInfo.mInfulenceIdx );
		if( totem )
			SetInfluence( totem->mInfluenceIdx );
	}
	else
		SetInfluence( trainStepInfo.mInfulenceIdx );

	/// 오른쪽 툴팁
	AddRightGap( 2 );

	if( store == false && skillStep == -1 )		
	{
		/// 미습득 표현
		mRightTip[mRightIndex].mString = GAMERESOURCEMAN->GetSkillToolTipText( 100020 );
		mRightTip[mRightIndex].mColor = (unsigned long)eCOLOR_RED;
	}
	else
	{
		/// 다음 단계 표현
		mRightTip[mRightIndex].mString.Format( GAMERESOURCEMAN->GetSkillToolTipText( 100010 ), skillStep + 2, pInfo->mStepCount );
		mRightTip[mRightIndex].mColor = eCOLOR_WHITE;
	}

	CalcRightMaxWidth( mRightTip[mRightIndex].mString );
	mRightIndex++;
	if( mRightIndex> MAX_RIGHT_TIP )
	{
		assert( 0 && "error tip index" );
	}

	SetRightTargetDist( pInfo, &trainStepInfo, eCOLOR_WHITE, skillIdx ); 
	SetRightBound( &trainStepInfo, eCOLOR_WHITE ); 

	/// 조건 설명 표현
	{
		/// 1. 필요 레벨
		if( store == false )
		{
			if( trainStepInfo.mPlayerLevel > HERO->GetLevel() )
			{
				mRequireValue[mRequireIndex][0].mString.Format(GAMERESOURCEMAN->GetSkillToolTipText( 100101 ), trainStepInfo.mPlayerLevel );
				mRequireValue[mRequireIndex][0].mColor = eCOLOR_RED;
				mRequireValue[mRequireIndex][0].mGapCount = 1;

				mRequireValue[mRequireIndex][1].mString.Clear();
				mRequireValue[mRequireIndex][2].mString.Clear();
				mRequireValue[mRequireIndex][3].mString.Clear();

				mRequireIndex++;
			}
		}

		/// 2. 사용 SP량
		if( pInfo->mJobStep != 0 && pInfo->mJobStep != 9 )
		{
			unsigned long point = HERO->GetJobUsedSkillPoint( pInfo->mJobStep-1 );
			if( point < pInfo->mBeforeReqSP )
			{
				mRequireValue[mRequireIndex][0].mString.Format(GAMERESOURCEMAN->GetSkillToolTipText( 100108 ), pInfo->mBeforeReqSP );
				mRequireValue[mRequireIndex][0].mColor = eCOLOR_RED;
				mRequireValue[mRequireIndex][0].mGapCount = 1;

				mRequireValue[mRequireIndex][1].mString.Clear();
				mRequireValue[mRequireIndex][2].mString.Clear();
				mRequireValue[mRequireIndex][3].mString.Clear();

				mRequireIndex++;
			}
		}

		/// 3. 필요 직업
		bool allowJob = false;
		tArray<unsigned long>* pArray = SKILLSCRIPT->GetPlayerSkillJob( trainStepInfo.mJobType );
		if( pArray )
		{
			if( pArray->GetSize() > 3 )
			{
				assert(0);
				return false;
			}

			mRequireValue[mRequireIndex][0].mString = GAMERESOURCEMAN->GetSkillToolTipText( 100021 );
			mRequireValue[mRequireIndex][0].mColor = eCOLOR_RED;
			mRequireValue[mRequireIndex][0].mGapCount = 1;

			mRequireValue[mRequireIndex][1].mString.Clear();
			mRequireValue[mRequireIndex][2].mString.Clear();
			mRequireValue[mRequireIndex][3].mString.Clear();

			tArray<unsigned long>* playerJobParent = GAMERESOURCEMAN->GetParentJob( HERO->GetJob() );
			if( playerJobParent == 0 )
			{
				/// 상위 직업 없는 경우
				for( unsigned int i = 0 ; i < pArray->GetSize() ; ++i )
				{
					mRequireValue[mRequireIndex][i+1].mString = GAMERESOURCEMAN->GetJobName( (*pArray)[i] );

					if( (*pArray)[i] == (unsigned long)HERO->GetJob() )
					{
						/// 글자 색깔을 흰색으로
						mRequireValue[mRequireIndex][i+1].mColor = eCOLOR_WHITE;
						mRequireValue[mRequireIndex][0].mColor = eCOLOR_WHITE;

						allowJob = true;
						break;
					}
					else
					{
						/// 글자 색깔을 빨강으로
						mRequireValue[mRequireIndex][i+1].mColor = eCOLOR_RED;
					}

					if( i+1 < pArray->GetSize() )
						mRequireValue[mRequireIndex][i+1].mString += _T(", ");
				}
			}
			else
			{
				/// 모든 상위 직업 검사
				for( unsigned int i = 0 ; i < pArray->GetSize() ; ++i )
				{
					mRequireValue[mRequireIndex][i+1].mString = GAMERESOURCEMAN->GetJobName( (*pArray)[i] );
					mRequireValue[mRequireIndex][i+1].mColor = eCOLOR_RED;

					if( (*pArray)[i] == HERO->GetJob() )
					{
						allowJob = true;
						break;
					}

					for( unsigned int j = 0 ; j < playerJobParent->GetSize() ; ++j )
					{
						if( (*pArray)[i] == (*playerJobParent)[j] )
						{
							mRequireValue[mRequireIndex][i+1].mColor = eCOLOR_WHITE;
							mRequireValue[mRequireIndex][0].mColor = eCOLOR_WHITE;

							allowJob = true;
							break;
						}
					}
					if( i+1 < pArray->GetSize() )
						mRequireValue[mRequireIndex][i+1].mString += _T(", ");
				}
			}
		}
		/// 
		if( allowJob == false )
		{
			mRequireIndex++;

			if( mRequireIndex > MAX_RIGHT_TIP )
				assert( 0 && "error tip index" );
		}

		/// 4. 선행 스킬
		mRequireValue[mRequireIndex][0].mString = GAMERESOURCEMAN->GetSkillToolTipText( 100022 );
		mRequireValue[mRequireIndex][0].mColor = eCOLOR_RED;
		mRequireValue[mRequireIndex][1].mColor = eCOLOR_RED;
		mRequireValue[mRequireIndex][2].mColor = eCOLOR_RED;

		/// 선행스킬 1
		bool allowLearn1 = false;
		if( pInfo->mLearnSkillIdx1 )
		{
			sPlayerSkillBaseInfo* pLearn = SKILLSCRIPT->GetPlayerSkillInfo( pInfo->mLearnSkillIdx1 );
			if( pLearn )
			{
				LPCTSTR name = GAMERESOURCEMAN->GetSkillNameText( pLearn->mNameIdx );
				mRequireValue[mRequireIndex][1].mString.Format( GAMERESOURCEMAN->GetSkillToolTipText( 100023 ), name, pInfo->mLearnSkillStep1 );
				sKeepSkill* p = SKILLMAN->GetKeepInfo( pInfo->mLearnSkillIdx1 );
				if( p )
				{
					if( p->mStep + 1 >= pInfo->mLearnSkillStep1 )
					{
						mRequireValue[mRequireIndex][1].mColor = eCOLOR_WHITE;
						allowLearn1 = true;
					}
				}

				if( pInfo->mLearnSkillIdx2 )
					mRequireValue[mRequireIndex][1].mString += _T(", ");
			}

			//allowLearn1 = false;
		}
		else
		{
			mRequireValue[mRequireIndex][1].mString.Clear();
			mRequireValue[mRequireIndex][1].mColor = eCOLOR_WHITE;
			allowLearn1 = true;
		}

		/// 선행스킬 2
		bool allowLearn2 = false;
		if( pInfo->mLearnSkillIdx2 )
		{
			sPlayerSkillBaseInfo* pLearn = SKILLSCRIPT->GetPlayerSkillInfo( pInfo->mLearnSkillIdx2 );
			if( pLearn )
			{
				LPCTSTR name = GAMERESOURCEMAN->GetSkillNameText( pLearn->mNameIdx );
				mRequireValue[mRequireIndex][2].mString.Format( GAMERESOURCEMAN->GetSkillToolTipText( 100023 ), name, pInfo->mLearnSkillStep2 );
				sKeepSkill* p = SKILLMAN->GetKeepInfo( pInfo->mLearnSkillIdx2 );
				if( p )
				{
					if( p->mStep + 1 >= pInfo->mLearnSkillStep2 )
					{
						mRequireValue[mRequireIndex][2].mColor = eCOLOR_WHITE;
						allowLearn2 = true;
					}
				}
			}

			//allowLearn2 = false;
		}
		else
		{
			mRequireValue[mRequireIndex][2].mString.Clear();
			mRequireValue[mRequireIndex][2].mColor = eCOLOR_WHITE;
			allowLearn2 = true;
		}

		/// 
		if( allowLearn1 == true && allowLearn2 == true )
		{
			mRequireValue[mRequireIndex][0].mColor = eCOLOR_WHITE;

			//mRequireValue[mRequireIndex][0].mString.Clear();
			//mRequireValue[mRequireIndex][1].mString.Clear();
			//mRequireValue[mRequireIndex][2].mString.Clear();
		}

		if( pInfo->mLearnSkillIdx1 || pInfo->mLearnSkillIdx2 )
		{
			if( allowLearn1 == false || allowLearn2 == false )
			{
				mRequireIndex++;
				if( mRequireIndex > MAX_RIGHT_TIP )
					assert( 0 && "error tip index" );
			}
		}
	}

	return true;
}

/// 퀵슬롯 팁
bool cSkillTipWindow::SetQuickTip( unsigned long skillIdx, char skillStep )
{
	sPlayerSkillBaseInfo* pInfo = SKILLSCRIPT->GetPlayerSkillInfo( skillIdx );
	if( pInfo == 0 )
	{
		return false;
	}

	/// 이름
	AddGap( 1 );
	SetName( pInfo, eCOLOR_YELLOW );

	AddGap( 2 );
	if( skillStep > -1 )
	{
		/// 현재 스텝 정보를 표현한다.
		unsigned int curStep = (unsigned int)skillStep;

		if( pInfo->mStepCount <= curStep )
		{
			assert(0);
		}

		sPlayerSkillStepInfo curStepInfo = pInfo->mpSetpInfoArray[curStep];

		/// 사용 장비
		SetEquip( pInfo, eCOLOR_WHITE );

		/// 시전시간
		SetCastingTime( pInfo, &curStepInfo, eCOLOR_WHITE );

		/// 재사용시간
		SetCoolTime( &curStepInfo, eCOLOR_WHITE, skillIdx );

		/// 소모 비용
		SetUsedValue( pInfo, &curStepInfo, eCOLOR_WHITE );

		cStringT temp;
		if( curStepInfo.mApplyValue1 != 0 || curStepInfo.mApplyValue2 != 0 )
		{
			if( curStepInfo.mApplyValue1 != 0 && curStepInfo.mApplyValue2 != 0 )
			{
				AddGap( 1 );
				temp.Format( GAMERESOURCEMAN->GetSkillToolTipText( curStepInfo.mToolTipIdx ), curStepInfo.mApplyValue1, curStepInfo.mApplyValue2 );
				CheckText( (LPCTSTR)temp.Cstr(), eCOLOR_YELLOW );
			}
			else if( curStepInfo.mApplyValue1 != 0 )
			{
				AddGap( 1 );
				temp.Format( GAMERESOURCEMAN->GetSkillToolTipText( curStepInfo.mToolTipIdx ), curStepInfo.mApplyValue1 );
				CheckText( (LPCTSTR)temp.Cstr(), eCOLOR_YELLOW );
			}
		}
		else
		{
			/// 일반 툴팁 출력
			AddGap( 1 );
			CheckText( GAMERESOURCEMAN->GetSkillToolTipText( curStepInfo.mToolTipIdx ), eCOLOR_YELLOW );
		}

		/// 오른쪽 툴팁
		AddRightGap( 2 );
		SetRightAttribute( pInfo, eCOLOR_WHITE ); 

		AddRightGap( 1 );
		SetRightStepInfo( pInfo, curStep, eCOLOR_WHITE ); 
		SetRightTargetDist( pInfo, &curStepInfo, eCOLOR_WHITE, skillIdx ); 
		SetRightBound( &curStepInfo, eCOLOR_WHITE ); 

		mBottomIndex = mIndex;
		mBottomRightIndex = mRightIndex;
	}
	return true;
}

void cSkillTipWindow::AddRightGap( unsigned int count )
{
	mRightTip[mRightIndex].mGapCount = count;
}

void cSkillTipWindow::SetName( sPlayerSkillBaseInfo* pInfo, unsigned long color )
{
	mToolTip[mIndex].mString = GAMERESOURCEMAN->GetSkillNameText( pInfo->mNameIdx );
	mToolTip[mIndex].mColor = color;
	CalcMaxWidth( mToolTip[mIndex].mString );
	mIndex++;
	if( mIndex > MAX_TIP )
	{
		assert( 0 && "error tip index" );
	}
}

void cSkillTipWindow::SetShotType( sPlayerSkillBaseInfo* pInfo, unsigned long color )
{
	LPCTSTR temp = 0;
	switch( pInfo->mShotType )
	{
		///제한 없음
	case eSHOTTYPE_NONE: temp = GAMERESOURCEMAN->GetSkillToolTipText(100102); break;
		///한손검
	case eSHOTTYPE_SPOT: temp = GAMERESOURCEMAN->GetSkillToolTipText(100103); break;
		///양손검
	case eSHOTTYPE_CASTING: temp = GAMERESOURCEMAN->GetSkillToolTipText(100104); break;
		///이도류
	case eSHOTTYPE_CHANNEL: temp = GAMERESOURCEMAN->GetSkillToolTipText(100105); break;
		///단검
	case eSHOTTYPE_AURA: temp = GAMERESOURCEMAN->GetSkillToolTipText(100106); break;
	}


	mToolTip[mIndex].mString = temp;
	mToolTip[mIndex].mColor = color;
	CalcMaxWidth( mToolTip[mIndex].mString );
	mIndex++;
	if( mIndex > MAX_TIP )
	{
		assert( 0 && "error tip index" );
	}
}

void cSkillTipWindow::SetEquip( sPlayerSkillBaseInfo* pInfo, unsigned long color )
{
	LPCTSTR temp = 0;
	switch( pInfo->mUseEquipment )
	{
		///제한 없음
	case 0: temp = GAMERESOURCEMAN->GetSkillToolTipText(100027); break;
		///한손검
	case 1: temp = GAMERESOURCEMAN->GetSkillToolTipText(100029); break;
		///양손검
	case 2: temp = GAMERESOURCEMAN->GetSkillToolTipText(100030); break;
		///이도류
	case 3: temp = GAMERESOURCEMAN->GetSkillToolTipText(100031); break;
		///단검
	case 4: temp = GAMERESOURCEMAN->GetSkillToolTipText(100032); break;
		///총
	case 5: temp = GAMERESOURCEMAN->GetSkillToolTipText(100033); break;
		///지팡이
	case 6: temp = GAMERESOURCEMAN->GetSkillToolTipText(100034); break;
		///방패 
	case 7: temp = GAMERESOURCEMAN->GetSkillToolTipText(100035); break;
		///한손검, 양손검
	case 8: temp = GAMERESOURCEMAN->GetSkillToolTipText(100036); break;
		///한손검, 이도류
	case 9: temp = GAMERESOURCEMAN->GetSkillToolTipText(100037); break;
		///양손검, 이도류
	case 10: temp = GAMERESOURCEMAN->GetSkillToolTipText(100038); break;
		///한손검, 양손검, 이도류
	case 11: temp = GAMERESOURCEMAN->GetSkillToolTipText(100039); break;
		///단검 또는 총
	case 12: temp = GAMERESOURCEMAN->GetSkillToolTipText(100040); break;
		///천 방어구
	case 13: temp = GAMERESOURCEMAN->GetSkillToolTipText(100041); break;
		///경갑 방어구
	case 14: temp = GAMERESOURCEMAN->GetSkillToolTipText(100042); break;
		///중갑 방어구
	case 15: temp = GAMERESOURCEMAN->GetSkillToolTipText(100043); break;
	}
	mToolTip[mIndex].mString.Format( GAMERESOURCEMAN->GetSkillToolTipText( 100000 ), temp );
	mToolTip[mIndex].mColor = color;
	CalcMaxWidth( mToolTip[mIndex].mString );
	mIndex++;
	if( mIndex > MAX_TIP )
	{
		assert( 0 && "error tip index" );
	}
}

void cSkillTipWindow::SetCastingTime( sPlayerSkillBaseInfo* pInfo, sPlayerSkillStepInfo* pStepInfo, unsigned long color )
{
	if( pInfo->mShotType == eSHOTTYPE_CASTING )
		mToolTip[mIndex].mString.Format( GAMERESOURCEMAN->GetSkillToolTipText(100001), (float)pStepInfo->mCastingTime * 0.001f );
	else if( pInfo->mShotType == eSHOTTYPE_CHANNEL )
		mToolTip[mIndex].mString.Format( GAMERESOURCEMAN->GetSkillToolTipText(100002), (float)pStepInfo->mCastingTime * 0.001f );
	else
		mToolTip[mIndex].mString = GAMERESOURCEMAN->GetSkillToolTipText(100026);

	mToolTip[mIndex].mColor = color;
	CalcMaxWidth( mToolTip[mIndex].mString );
	mIndex++;
	if( mIndex > MAX_TIP )
	{
		assert( 0 && "error tip index" );
	}
}

void cSkillTipWindow::OnTimer()
{
	cUIWindow::OnTimer();

	if( mVisible == false )
		return;

	if( mSaveSkillIndex == 0 )
		return;

	cStringT str1 = mSaveCoolTime;
	sKeepSkill* skill = SKILLMAN->GetKeepInfo( mSaveSkillIndex );
	if( skill && skill->mRestTime != skill->mTotalTime )
	{
		cStringT str2;

		/// 초를 출력시 반올림해서 출력
		unsigned int restTime = (unsigned int)(skill->mRestTime * 0.001f);
		unsigned int m = (restTime % 3600) / 60;
		unsigned int s = ((restTime % 600) % 60)%60 + 1;

		cStringT rm,rs;
		if( m != 0 )
			rm.Format( GAMERESOURCEMAN->GetSkillToolTipText(100016), m );
		rs.Format( GAMERESOURCEMAN->GetSkillToolTipText(100015), s );

		rm += rs;
		str2.Format( GAMERESOURCEMAN->GetSkillToolTipText( 100004 ), rm.Cstr() );
		str1.Append( str2 );
	}

	mToolTip[mTimeTipIdx].mString = str1;
	mToolTip[mTimeTipIdx].mColor = eCOLOR_WHITE;
	CalcMaxWidth( mToolTip[mTimeTipIdx].mString );
}

void cSkillTipWindow::SetCoolTime( sPlayerSkillStepInfo* pStepInfo, unsigned long color, unsigned long skillIdx )
{
	unsigned long coolTime = pStepInfo->mCoolTime / SECOND_THOUSAND;
	unsigned int h = coolTime / 3600;
	unsigned int m = coolTime / 60;
	unsigned int s = coolTime % 60 + 1;

	/// 재사용시간이 0 이면 찍지 않는다.
	if( h == 0 && m == 0 && s == 0 )
		return;

	cStringT th,tm,ts;
	if( h != 0 )
		th.Format( GAMERESOURCEMAN->GetSkillToolTipText(100017), h );
	if( m != 0 )
		tm.Format( GAMERESOURCEMAN->GetSkillToolTipText(100016), m );
	if( s != 0 )
		ts.Format( GAMERESOURCEMAN->GetSkillToolTipText(100015), s );

	th += tm; th += ts;

	cStringT str1;
	str1.Format( GAMERESOURCEMAN->GetSkillToolTipText(100003), th.Cstr() );

	sKeepSkill* skill = SKILLMAN->GetKeepInfo( skillIdx );
	if( skill && skill->mRestTime > 0.0f)
	{
		/// 저장
		mTimerEnabled = true;
		mSaveCoolTime = str1;
		mSaveSkillIndex = skillIdx;
		mTimeTipIdx = mIndex;
		mIndex++;
	}
	else
	{
		SetText( str1.Cstr(), color );
	}
}

void cSkillTipWindow::SetUsedValue( sPlayerSkillBaseInfo* pInfo, sPlayerSkillStepInfo* pStepInfo, unsigned long color )
{
	if( pInfo->mUseItem == 0 )
	{
		/// 소모 아이템이 없는경우
		if( pStepInfo->mUseMP != 0 || pStepInfo->mUseHP != 0 )
		{
			/// 소모 hp, mp가 있거나..
			cStringT str = GAMERESOURCEMAN->GetSkillToolTipText(100005);
			cStringT hp;
			if( pStepInfo->mUseHP != 0 )
			{
				hp.Format( GAMERESOURCEMAN->GetSkillToolTipText(100007), pStepInfo->mUseHP );
				str += hp;
			}
			cStringT mp;
			if( pStepInfo->mUseMP != 0 )
			{
				if( pStepInfo->mUseHP != 0 )
					str += _T(", ");

				mp.Format( GAMERESOURCEMAN->GetSkillToolTipText(100006), pStepInfo->mUseMP );
				str += mp;
			}

			mToolTip[mIndex].mString = str;
			mToolTip[mIndex].mColor = color;
			CalcMaxWidth( mToolTip[mIndex].mString );
			mIndex++;
			if( mIndex > MAX_TIP )
			{
				assert( 0 && "error tip index" );
			}
		}

		return;
	}

	/// 소모 아이템이 있는 경우
	cItemDefine* p = ITEMMAN->GetItemDefine( pInfo->mUseItem );
	if( pStepInfo->mUseMP != 0 || pStepInfo->mUseHP != 0 )
	{
		cStringT str = GAMERESOURCEMAN->GetSkillToolTipText(100005);
		cStringT mp;
		if( pStepInfo->mUseMP != 0 )
		{
			mp.Format( GAMERESOURCEMAN->GetSkillToolTipText(100006), pStepInfo->mUseMP );
			str += mp;
		}
		cStringT hp;
		if( pStepInfo->mUseHP != 0 )
		{
			hp.Format( GAMERESOURCEMAN->GetSkillToolTipText(100007), pStepInfo->mUseHP );
			if( mp.IsEmpty() == false)
				hp += _T(" ,");
			str += hp;
		}

		mToolTip[mIndex].mString = str;
		mToolTip[mIndex].mColor = color;
		CalcMaxWidth( mToolTip[mIndex].mString );
		mIndex++;
		if( mIndex > MAX_TIP )
		{
			assert( 0 && "error tip index" );
		}

		if( p )
		{
			cStringT item;
			item.Format( GAMERESOURCEMAN->GetSkillToolTipText(100008), p->GetName(), pStepInfo->mUseItemCount );
			mToolTip[mIndex].mString = item;
			mToolTip[mIndex].mColor = color;
			CalcMaxWidth( mToolTip[mIndex].mString );
			mIndex++;
			if( mIndex > MAX_TIP )
			{
				assert( 0 && "error tip index" );
			}
		}
	}
	else
	{
		if( p )
		{
			cStringT str = GAMERESOURCEMAN->GetSkillToolTipText(100005);

			cStringT item;
			item.Format( GAMERESOURCEMAN->GetSkillToolTipText(100009), p->GetName(), pStepInfo->mUseItemCount );
			str += item;
			mToolTip[mIndex].mString = str;
			mToolTip[mIndex].mColor = color;
			CalcMaxWidth( mToolTip[mIndex].mString );
			mIndex++;
			if( mIndex > MAX_TIP )
			{
				assert( 0 && "error tip index" );
			}
		}
	}
}

void cSkillTipWindow::SetInfluence( unsigned long influenceIdx )
{
	sInfluenceScript* pInfo = SKILLSCRIPT->GetInfluenceInfo( influenceIdx );
	if( pInfo == 0 )
		return;
	if( pInfo->mToolTipIdx == 0 )
		return;

	AddGap( 1 );

	/// 효과 찍기
	mToolTip[mIndex].mString = GAMERESOURCEMAN->GetSkillToolTipText(100107);
	mToolTip[mIndex].mColor = eCOLOR_WHITE;
	CalcMaxWidth( mToolTip[mIndex].mString );
	mIndex++;
	if( mIndex > MAX_TIP )
	{
		assert( 0 && "error tip index" );
	}

	/// 효과값이 있으면 효과출력
	cStringT temp;
	if( pInfo->mValue1 != 0 || pInfo->mValue2 != 0 || pInfo->mValue3 != 0 )
	{
		if( pInfo->mValue1 && pInfo->mValue2 && pInfo->mValue3 )
		{
			temp.Format( GAMERESOURCEMAN->GetSkillToolTipText( pInfo->mToolTipIdx ), pInfo->mValue1, pInfo->mValue2, pInfo->mValue3 );
			CheckText( (LPCTSTR)temp.Cstr(), eCOLOR_YELLOW );
		}
		else if( pInfo->mValue1 && pInfo->mValue2 )
		{
			temp.Format( GAMERESOURCEMAN->GetSkillToolTipText( pInfo->mToolTipIdx ), pInfo->mValue1, pInfo->mValue2 );
			CheckText( (LPCTSTR)temp.Cstr(), eCOLOR_YELLOW );
		}
		else if( pInfo->mValue1 )
		{
			temp.Format( GAMERESOURCEMAN->GetSkillToolTipText( pInfo->mToolTipIdx ), pInfo->mValue1 );
			CheckText( (LPCTSTR)temp.Cstr(), eCOLOR_YELLOW );
		}
	}
	else
	{
		/// 일반 툴팁 출력
		if( CheckText( GAMERESOURCEMAN->GetSkillToolTipText( pInfo->mToolTipIdx ), eCOLOR_YELLOW ) )
		{
			cStringT str;
			str.Format( GAMERESOURCEMAN->GetSkillToolTipText( 100025 ), pInfo->mGroupOrder );
			mToolTip[mIndex-1].mString += str.Cstr();
			CalcMaxWidth( mToolTip[mIndex-1].mString );
		}
	}
}

void cSkillTipWindow::SetRightAttribute( sPlayerSkillBaseInfo* pInfo, unsigned long color )
{
	if( pInfo->mAttributeType == eATTRIBUTETYPE_MAGIC )
		mRightTip[mRightIndex].mString = GAMERESOURCEMAN->GetSkillToolTipText( 100018 );
	else
		mRightTip[mRightIndex].mString = GAMERESOURCEMAN->GetSkillToolTipText( 100019 );
	mRightTip[mRightIndex].mColor = color;
	CalcRightMaxWidth( mRightTip[mRightIndex].mString );
	mRightIndex++;
	if( mRightIndex> MAX_RIGHT_TIP )
	{
		assert( 0 && "error tip index" );
	}
}

void cSkillTipWindow::SetRightStepInfo( sPlayerSkillBaseInfo* pInfo, unsigned int curStep, unsigned long color )
{
	if( pInfo->mStepCount == curStep+1 )
	{
		/// master
		mRightTip[mRightIndex].mString = GAMERESOURCEMAN->GetSkillToolTipText( 100011 );
		mRightTip[mRightIndex].mColor = color;
		CalcRightMaxWidth( mRightTip[mRightIndex].mString );
		mRightIndex++;
		if( mRightIndex> MAX_RIGHT_TIP )
		{
			assert( 0 && "error tip index" );
		}
	}
	else
	{
		mRightTip[mRightIndex].mString.Format( GAMERESOURCEMAN->GetSkillToolTipText( 100010 ), curStep+1, pInfo->mStepCount );
		mRightTip[mRightIndex].mColor = color;
		CalcRightMaxWidth( mRightTip[mRightIndex].mString );
		mRightIndex++;
		if( mRightIndex> MAX_RIGHT_TIP )
		{
			assert( 0 && "error tip index" );
		}
	}
}

void cSkillTipWindow::SetRightTargetDist( sPlayerSkillBaseInfo* pInfo, sPlayerSkillStepInfo* pStepInfo, unsigned long color, unsigned long skillIdx )
{
	float targetDist = pStepInfo->mTargetDist;

	/// 일반공격 스킬이면 장착한 아이템의 사거리를 더한다.
	unsigned long weaponIdx = HERO->GetRightWeaponIdx();
	cItemDefine* define = ITEMMAN->GetItemDefine( weaponIdx );
	if( define )
	{
		cItemAbility* abil = define->GetAbililty();
		if( abil && skillIdx == 1)
			targetDist += abil->GetAttackRange();
	}

	/// 사거리 표현
	if( pInfo->mRangeType == eRANGETYPE_CLOSE )
	{
		if( pStepInfo->mTargetDist <= 0.0f )
			return;

		mRightTip[mRightIndex].mString.Format( GAMERESOURCEMAN->GetSkillToolTipText( 100013 ), (float)(targetDist / 100) );
		mRightTip[mRightIndex].mColor = color;
		CalcRightMaxWidth( mRightTip[mRightIndex].mString );
		mRightIndex++;
		if( mRightIndex> MAX_RIGHT_TIP )
		{
			assert( 0 && "error tip index" );
		}
	}
	else if( pInfo->mRangeType == eRANGETYPE_LONG )
	{
		if( pStepInfo->mTargetDist <= 0.0f )
			return;

		mRightTip[mRightIndex].mString.Format( GAMERESOURCEMAN->GetSkillToolTipText( 100012 ), (float)(targetDist / 100) );
		mRightTip[mRightIndex].mColor = color;
		CalcRightMaxWidth( mRightTip[mRightIndex].mString );
		mRightIndex++;
		if( mRightIndex> MAX_RIGHT_TIP )
		{
			assert( 0 && "error tip index" );
		}
	}
}

void cSkillTipWindow::SetRightBound( sPlayerSkillStepInfo* pStepInfo, unsigned long color )
{
	if( pStepInfo->mBoundDist == 0 )
		return;

	mRightTip[mRightIndex].mString.Format( GAMERESOURCEMAN->GetSkillToolTipText( 100014 ), (float)(pStepInfo->mBoundDist / 100) );
	mRightTip[mRightIndex].mColor = color;
	CalcRightMaxWidth( mRightTip[mRightIndex].mString );
	mRightIndex++;
	if( mRightIndex> MAX_RIGHT_TIP )
	{
		assert( 0 && "error tip index" );
	}
}
