#include "stdafx.h"
#include "QuickManager.h"
#include "ItemIcon.h"
#include "SkillIcon.h"
#include "SkillScript.h"
#include "CommunityScript.h"
#include "ItemManager.h"
#include "RadioButton.h"
#include "CoolTimeManager.h"
#include "UIRoundGauge.h"

#include "Application.h"
#include "SkillManager.h"
#include "SkillExecuter.h"
#include "ObjectManager.h"
#include "hero.h"

#include "GameUIManager.h"
#include "SkillWindow.h"

cQuickManager* cQuickManager::mSingleton = 0;

cQuickManager::cQuickManager()
: mTabIndex(0)
, mTabIndexFS(-1)
, mIsRowQuick( false )
, mIsRowQuickFS( false )
, mDragIcon(0)
, mIsLockByMonster( false )
{
	assert( mSingleton == 0 && "bad singleton!" );
	mSingleton = this;
}

cQuickManager::~cQuickManager()
{
}

void cQuickManager::Clear()
{
	mDragIcon = 0;
	mIsLockByMonster = false;

	/// 데이터초기화
	for( unsigned int data = 0; data < QUICK_TOTAL; ++data )
	{
		mQuick[data] = 0;
	}
	
	/// 아이콘 초기화
	for( unsigned int i = 0; i < ICON_COUNT; ++i )
	{
		mBindIcon[i].SetParam( 0 );
		mBindIcon[i].SetCount( 0 );
		mBindIcon[i].SetColor( NiColorA::WHITE );
		mBindIcon[i].StopDelay();
	}
}

void cQuickManager::Open()
{
	UpdateUI();

	/// 
	sPlayerExrInfo* info = HERO->GetPlayerExrInfo();
	if( info )
	{
		ChangeMonster( info->mChgMonsterIdx );
	}
	else
	{
		assert(0);
	}

	QUICKMAN->CheckSkillIcon();
}

void cQuickManager::SetRowQuick( bool IsRow )
{
	mIsRowQuick = IsRow;
}

void cQuickManager::SetRowQuickFS( bool IsRow )
{
	mIsRowQuickFS = IsRow;
}

///
bool cQuickManager::IsUseSlot( unsigned int iconId, bool IsFS )
{
	/// 몬스터 변신상태이고, 0, 1, 2, 아이콘이면 몬스터용 스킬 타입 리턴
	if( IsFS && mIsLockByMonster && iconId < QUICK_COUNT_MON )
		return false;

	int dataIndex = iconId + (( IsFS == false ) ? mTabIndex * QUICKSLOT_COUNT : ( mTabIndexFS * QUICKSLOT_COUNT ) + QUICKSLOT_FS_BEGIN);

	/// 사용하고 있지 않음.
	if( mQuick[dataIndex].mType == eSHORTCUT_NONE )
		return false;
	return true;
}

///
eSHORTCUT_TYPE cQuickManager::GetQuickType( unsigned int iconId, bool IsFS )
{
	int dataIndex = -1;

	if( IsFS == false )
	{
		dataIndex = iconId + mTabIndex * QUICKSLOT_COUNT;
	}
	else
	{
		/// 몬스터 변신상태이고, 0, 1, 2, 아이콘이면 몬스터용 스킬 타입 리턴
		if( mIsLockByMonster == true && iconId < QUICK_COUNT_MON )
		{
			dataIndex = iconId + QUICKSLOT_MON_BEGIN;
		}
		else
		{
			dataIndex = iconId + ( mTabIndexFS * QUICKSLOT_COUNT ) + QUICKSLOT_FS_BEGIN;
		}
	}

	if( dataIndex == -1 )
	{
		assert(0);
		return eSHORTCUT_NONE;
	}

	return (eSHORTCUT_TYPE)mQuick[dataIndex].mType;
}

///
unsigned int cQuickManager::GetItemIndex( unsigned int iconId, bool IsFS )
{
	int dataIndex = iconId + (( IsFS == false ) ? mTabIndex * QUICKSLOT_COUNT : ( mTabIndexFS * QUICKSLOT_COUNT ) + QUICKSLOT_FS_BEGIN);
	return mQuick[dataIndex].mItemIndex;
}

///
unsigned int cQuickManager::GetSkillIndex( unsigned int iconId, bool IsFS )
{
	int dataIndex = iconId + (( IsFS == false ) ? mTabIndex * QUICKSLOT_COUNT : ( mTabIndexFS * QUICKSLOT_COUNT ) + QUICKSLOT_FS_BEGIN);
	return mQuick[dataIndex].mSkillIndex;
}

short cQuickManager::GetMonSkillIndex( unsigned int iconId )
{
	return (short)mQuick[iconId+QUICKSLOT_MON_BEGIN].mSkillIndex;
}

///
void cQuickManager::OnMouseDown( unsigned int iconId, bool IsFS )
{
	/// 몬스터 변신상태면,
	if( IsFS && mIsLockByMonster && iconId < QUICK_COUNT_MON )
		UseMonsterQuickSlot( iconId );
	else
		UseQuickSlot( iconId, IsFS );
}

///
void cQuickManager::OnKeyDown( eKeyCode code )
{
	int iconId = -1;

	bool IsFS = false;
	switch( code )
	{
	case eKEY_0:	iconId = 9;	IsFS = true; break;
	case eKEY_1:	iconId = 0;	IsFS = true; break;
	case eKEY_2:	iconId = 1;	IsFS = true; break;
	case eKEY_3:	iconId = 2;	IsFS = true; break;
	case eKEY_4:	iconId = 3;	IsFS = true; break;
	case eKEY_5:	iconId = 4;	IsFS = true; break;
	case eKEY_6:	iconId = 5;	IsFS = true; break;
	case eKEY_7:	iconId = 6;	IsFS = true; break;
	case eKEY_8:	iconId = 7;	IsFS = true; break;
	case eKEY_9:	iconId = 8;	IsFS = true; break;
	case eKEY_F1:	iconId = 0;	break;
	case eKEY_F2:	iconId = 1;	break;
	case eKEY_F3:	iconId = 2;	break;
	case eKEY_F4:	iconId = 3;	break;
	case eKEY_F5:	iconId = 4;	break;
	case eKEY_F6:	iconId = 5;	break;
	case eKEY_F7:	iconId = 6;	break;
	case eKEY_F8:	iconId = 7;	break;
	case eKEY_F9:	iconId = 8;	break;
	case eKEY_F10:	iconId = 9;	break;
	default: assert(0); break;
	}
	
	/// 몬스터 변신상태면,
	if( IsFS && mIsLockByMonster && iconId < QUICK_COUNT_MON )
		UseMonsterQuickSlot( iconId );
	else
		UseQuickSlot( iconId, IsFS );
}

/// 퀵슬롯 사용 
void cQuickManager::UseQuickSlot( unsigned int iconId, bool IsFS )
{
	/// 상태 검사
	if( GAMEUI->IsShowCardBook() == true )
		return;

	int quickIndex = iconId + (( IsFS == false ) ? mTabIndex * QUICKSLOT_COUNT : ( mTabIndexFS * QUICKSLOT_COUNT ) + QUICKSLOT_FS_BEGIN) ;
	iconId = ( IsFS == false ) ? iconId : iconId + QUICKSLOT_COUNT;

	if( mQuick[quickIndex].mType == eSHORTCUT_SKILL )
	{
		HERO->SetWaitMoveFlag( false );

		/// 스킬
		if( mQuick[quickIndex].mSkillIndex < NORMAL_ATTACK_SKILL_MAX )
		{
			if( HERO->GetState() != eOBJECT_STATE_ATTACK )
				SKILLEXECUTER->ExecuteAttack( HERO->GetTargetObject() );
		}
		else
		{
			if( SKILLMAN->IsUsedKeepSkill( mQuick[quickIndex].mSkillIndex ) == true )
				SKILLEXECUTER->ExecuteSkill( mQuick[quickIndex].mSkillIndex );
		}

		UIMAN->HideTip();
	}
	else if( mQuick[quickIndex].mType == eSHORTCUT_ITEM )
	{
		/// 아이템
		unsigned int count = mBindIcon[iconId].mColumnIcon->GetNumber();
		/// 갯수가 있어야 사용할수 있다.
		if( count > 0 )
		{
			unsigned int slotIndex = ITEMMAN->FindSlotIndex( mQuick[quickIndex].mItemIndex );
			if( slotIndex <= 0 )
			{
				assert(0 && "failed to find slotindex" );
				return;
			}

			/// 아이템 사용 
			ITEMMAN->TryToEquipItem( slotIndex );
			UIMAN->HideTip();
		}
	}
	else if( mQuick[quickIndex].mType == eSHORTCUT_COMMU )
	{
		sCommunitySkillInfo* pInfo = COMMUNITYSCRIPT->GetCommunityInfo( mQuick[quickIndex].mSkillIndex );
		if( pInfo )
		{
			if( pInfo->mType == 1 )
			{
				if( HERO->GetState() == eOBJECT_STATE_IDLE )
				{
					cSkillWindow* win = GAMEUI->GetSkillWindow();
					if( win )
						win->RequestCommuSkill( pInfo->mIndex );
				}
			}
			else
			{
				cSkillWindow* win = GAMEUI->GetSkillWindow();
				if( win )
					win->RequestLifeCommand( pInfo->mIndex, 0, 0 );
			}
		}
	}
}

void cQuickManager::UseMonsterQuickSlot( unsigned int iconId )
{
	/// 몬스터 변신이 안되어있으면 리턴
	if( HERO->IsTransformMonster() == false )
		return;

	/// 연결된 몬스터 스킬이 없는 경우 리턴
	int slot = QUICKSLOT_MON_BEGIN + iconId;
	if( mQuick[slot].mSkillIndex < eMONSTERATTACK_SKILL1 || 
		mQuick[slot].mSkillIndex >= eMONSTERATTACK_MAX )
		return;

	cIcon* icon = mBindIcon[QUICKSLOT_COUNT+iconId].mColumnIcon;
	if( !icon ) 
	{
		assert(0);
		return;
	}

	if( icon->IsActive() == true )
		return;

	HERO->SetWaitMoveFlag( false );

	if( SKILLMAN->IsUsedMonsterSkill( mQuick[slot].mSkillIndex ) == true )
		SKILLEXECUTER->ExecuteSkill( mQuick[slot].mSkillIndex );

	UIMAN->HideTip();
}

/// 탭 체인지 
void cQuickManager::ChangeTab( unsigned int tabindex )
{
	if( mTabIndex == tabindex )
		return;

	mTabIndex = tabindex;

	/// 갱신
	unsigned int slot = mTabIndex * QUICKSLOT_COUNT;
	for( unsigned int i = slot; i < slot + QUICKSLOT_COUNT; ++i )
	{
		unsigned iconId = i - slot;
		UpdateIcon( i, iconId );	
	}

	/// 쿨타임 로딩
	LoadCoolTime();
}

/// 탭 체인지 
void cQuickManager::ChangeTabFS( unsigned int tabindex )
{
	if( mTabIndexFS == tabindex )
		return;

	mTabIndexFS = tabindex;

	/// FS 퀵슬롯
	unsigned int slot = (mTabIndexFS * QUICKSLOT_COUNT) + QUICKSLOT_FS_BEGIN;
	for( unsigned int i = slot; i < slot + QUICKSLOT_COUNT; ++i )
	{
		unsigned iconId = i - slot + QUICKSLOT_COUNT;
		UpdateIcon( i, iconId );	
	}

	/// 몬스텨 변신일경우 FS퀵슬롯 재세팅
	if( mIsLockByMonster == true )
	{
		for( int i = 0; i < QUICK_COUNT_MON; ++i )
		{
			/// 퀵슬롯 아이콘 세팅
			mBindIcon[ QUICKSLOT_COUNT+i ].SetColor( mQuick[QUICKSLOT_MON_BEGIN+i].mColor );
			mBindIcon[ QUICKSLOT_COUNT+i ].SetParam( UIMAN->GetIconParam(MONICON_PARAMINDEX + i) );
			mBindIcon[ QUICKSLOT_COUNT+i ].SetCount( 0 );
			mBindIcon[ QUICKSLOT_COUNT+i ].ShowNumber( false );
			mBindIcon[ QUICKSLOT_COUNT+i ].SetAniParam( mQuick[QUICKSLOT_MON_BEGIN+i].mAniParam );
			mBindIcon[ QUICKSLOT_COUNT+i ].SetTipType( mQuick[QUICKSLOT_MON_BEGIN+i].mTipType );
		}
	}

	/// 쿨타임 로딩
	LoadCoolTime();
}

void cQuickManager::DragIcon( cIcon* icon )
{
	assert( icon );

	mDragIcon = icon;
	mDragIcon->ShowGauge( false );
	mDragIcon->SetColor( 0.5f, 0.5f, 0.5f, 1.0f );
}

///
void cQuickManager::UnDragIcon()
{
	if( mDragIcon )
	{
		cUIContainer* fromParent = mDragIcon->GetParent();
		if( !fromParent )
		{
			assert(0);
			return;
		}

		/// fs 슬롯에서 온건지 판별
		bool fromIsFS = ( fromParent->GetID() == eUIID_COLUMN_QUICKSLOT || fromParent->GetID() == eUIID_ROW_QUICKSLOT ) ? false : true;
		int dataIndex = mDragIcon->GetID() + (( fromIsFS == false ) ? mTabIndex * QUICKSLOT_COUNT : ( mTabIndexFS * QUICKSLOT_COUNT ) + QUICKSLOT_FS_BEGIN);

		/// 기존 저장되어있던 컬러로 변환 
		mDragIcon->ShowGauge( true );
		mDragIcon->SetColor( mQuick[dataIndex].mColor );
	}
}

/// 서버로부터 기존의 퀵슬롯 정보를 받아 세팅
void cQuickManager::NetSetData( unsigned int dataIndex, const sShortcut& shortcut )
{
	if( mQuick[dataIndex].mType != eSHORTCUT_NONE )
	{
		assert(0 && "already exist");
	}

	/// 퀵슬롯 정보 세팅 
	mQuick[dataIndex].mType = shortcut.mType;
	mQuick[dataIndex].mDBIndex = shortcut.mInventoryIdx;

	if( shortcut.mType == eSHORTCUT_ITEM )
	{
		mQuick[dataIndex].mItemIndex = shortcut.mIndex;
		mQuick[dataIndex].mSkillIndex = 0;
	}
	else if( shortcut.mType == eSHORTCUT_SKILL )
	{
		mQuick[dataIndex].mSkillIndex = shortcut.mIndex;
		mQuick[dataIndex].mItemIndex = 0;
	}
	else if( shortcut.mType == eSHORTCUT_COMMU )
	{
		mQuick[dataIndex].mSkillIndex = shortcut.mIndex;
		mQuick[dataIndex].mItemIndex = 0;
	}
}	

///
void cQuickManager::NetUpdateData()
{
	/// 서버에 퀵슬롯 정보 보내기
	MSG_REQ_PLAYER_SHORTCUT_UPDATE msg;
	msg.Category = NM_PLAYER;
	msg.Protocol = NM_PLAYER_SHORTCUT_UPDATE_REQ;

	/// 변신상태 스킬은 등록할 필요없다!
	for( unsigned int i = 0; i < QUICK_COUNT; ++i )
	{
		msg.mShortcut[i].mType = mQuick[i].mType;
		msg.mShortcut[i].mInventoryIdx = mQuick[i].mDBIndex; 

		if( mQuick[i].mItemIndex > 0 )
		{
			msg.mShortcut[i].mIndex = mQuick[i].mItemIndex;
		}
		else if( mQuick[i].mSkillIndex > 0 )
		{
			msg.mShortcut[i].mIndex = mQuick[i].mSkillIndex;
		}
	}

	NETWORK->SendNetworkMsg( (char*)&msg, sizeof(msg) );
}

///
void cQuickManager::AddData( unsigned int iconId, cIcon* srcIcon, bool toIsFS )
{
	int i = -1;
	if( toIsFS == false )
	{
		/// 일반 퀵슬롯인경우,
		i = iconId + ( mTabIndex * QUICKSLOT_COUNT );
	}
	else
	{
		/// FS 퀵슬롯인경우 재설정
		i = iconId + ( mTabIndexFS * QUICKSLOT_COUNT ) + QUICKSLOT_FS_BEGIN;
		iconId = iconId + QUICKSLOT_COUNT;
	}

	if( i == -1 )
	{
		assert(0);
		return;
	}

	/// 범위 체크
	if( iconId >= ICON_COUNT )
	{
		assert(0);
		return;
	}

	/// 비어있으면 등록
	unsigned int type = srcIcon->GetIconType();
	switch( type )
	{
	case eICON_ITEM:
		{
			cItemIcon* itemIcon = (cItemIcon*)srcIcon;
			cItemDefine* itemDefine = ITEMMAN->GetItemDefine( itemIcon->GetItemIndex() );
			if( !itemDefine )
			{
				assert(0);
				return;
			}

			/// 일정 타입만 등록됨
			unsigned char type = itemDefine->GetType();	
			unsigned char subtype = itemDefine->GetSubType();
			if( type == ITEM_ETC1 || (type == ITEM_CARD && subtype == ITEM_CARD_COMMON) 
								  || (type == ITEM_MATERIAL && subtype == ITEM_MATERIAL_MAP)
								  || (type == ITEM_MATERIAL && subtype == ITEM_MATERIAL_VEHICLE) )
			{
				/// 자리검사 - 기존데이터가 있으면 삭제 처리
				if( mQuick[i].mType != eSHORTCUT_NONE )
					DeleteData( iconId, i );

				mQuick[i].mType = eSHORTCUT_ITEM;
				mQuick[i].mDBIndex = itemIcon->GetDBIndex();
				mQuick[i].mItemIndex = itemIcon->GetItemIndex();
				mQuick[i].mAniParam = itemIcon->GetAniParam();
				mQuick[i].mTipType = itemIcon->GetTipType();

				/// 아이콘세팅
				mBindIcon[iconId] = *srcIcon;
				mBindIcon[iconId].SetAniParam( itemIcon->GetAniParam() );
				mBindIcon[iconId].SetTipType( itemIcon->GetTipType() );
                
				/// 총 갯수 설정
				SetTotalCount( i, iconId, mQuick[i].mItemIndex );
			
				/// 쿨타임 매니저로부터 쿨타임 정보 가져다 세팅 
				COOLMAN->RequestQuickCool( i, mQuick[i].mItemIndex );

				/// 퀵슬롯 정보 서버에 쏘기
				NetUpdateData();
			}
		}
		break;
	case eICON_SKILL:
		{
			/// 자리검사 /// 기존데이터가 있으면 삭제 처리
			if( mQuick[i].mType != eSHORTCUT_NONE )
				DeleteData( iconId, i );

			cSkillIcon* skillIcon = (cSkillIcon*)srcIcon;
			mQuick[i].mType = eSHORTCUT_SKILL;
			mQuick[i].mSkillIndex = skillIcon->GetSkillIdx();
			mQuick[i].mSkillStep = skillIcon->GetSkillStep();
			mQuick[i].mAniParam = skillIcon->GetAniParam();
			mQuick[i].mTipType = eTOOLTIP_NONE;

			/// 아이콘세팅
			mBindIcon[iconId] = *srcIcon;
			mBindIcon[iconId].ShowNumber( false );
			mBindIcon[iconId].SetAniParam( skillIcon->GetAniParam() );
			mBindIcon[iconId].SetTipType( eTOOLTIP_NONE );

			/// 
			eWEAPON_STATE wstate = HERO->GetWeaponState();
			if( UsableSkillIcon( wstate, skillIcon->GetSkillIdx(), skillIcon->GetSkillStep() ) == true )
			{
				mQuick[i].mColor =  NiColorA::WHITE;
				mBindIcon[iconId].SetColor( NiColorA::WHITE );
			}
			else
			{
				mQuick[i].mColor = NiColorA( 1.0f, 0.0f, 0.0f, 1.0f );
				mBindIcon[iconId].SetColor( NiColorA( 1.0f, 0.0f, 0.0f, 1.0f ) );
			}

			/// 쿨타임 데이터 저장
			SaveSkillCool( i, iconId );

			/// 퀵슬롯 정보 서버에 쏘기
			NetUpdateData();
		}
		break;
	case eICON_COMMUNITY:
		{
			if( mQuick[i].mType != eSHORTCUT_NONE )
				DeleteData( iconId, i );

			/// 
			cCommunityIcon* comIcon = (cCommunityIcon*)srcIcon;
			mQuick[i].mType = eSHORTCUT_COMMU;
			mQuick[i].mSkillIndex = comIcon->GetCommunityIndex();
			mQuick[i].mColor =  NiColorA::WHITE;

			/// 아이콘세팅
			mBindIcon[iconId] = *srcIcon;
			mBindIcon[iconId].ShowNumber( false );
			mBindIcon[iconId].SetColor( NiColorA::WHITE );

			/// 퀵슬롯 정보 서버에 쏘기
			NetUpdateData();
		}
		break;
	}
}

/// fromIsFS: 시작 지점 아이콘이 fs 슬롯인지 여부
/// toIsFS: 도착 지점 아이콘이 fs 슬롯인지 여부
void cQuickManager::MoveData( unsigned int toId, cIcon* srcIcon, bool toIsFS )
{
	if( mDragIcon == 0 )
	{
		assert(0);
		return;
	}

	cUIContainer* fromParent = mDragIcon->GetParent();
	if( !fromParent )
	{
		assert(0);
		return;
	}

	bool fromIsFS = ( fromParent->GetID() == eUIID_COLUMN_QUICKSLOT || fromParent->GetID() == eUIID_ROW_QUICKSLOT ) ? false : true;

	/// 시작지점과 도착지점으로 각 아이콘 세팅
	int from = ( fromIsFS == false ) ? mDragIcon->GetID() + ( mTabIndex * QUICKSLOT_COUNT ) : mDragIcon->GetID() + ( mTabIndexFS * QUICKSLOT_COUNT ) + QUICKSLOT_FS_BEGIN;
	int to = ( toIsFS == false ) ? toId + ( mTabIndex * QUICKSLOT_COUNT ) : toId + ( mTabIndexFS * QUICKSLOT_COUNT ) + QUICKSLOT_FS_BEGIN;
	
	/// FS 퀵슬롯인경우 재설정
	if( toIsFS == true )
	{
		toId = toId + QUICKSLOT_COUNT;
	}

	/// 범위 체크
	if( toId >= ICON_COUNT )
	{
		assert(0);
		return;
	}

	/// 자리검사 
	if( mQuick[to].mType != eSHORTCUT_NONE )
	{
		/// 다른데이터가 있으면 스왑
		cQuickData temp = mQuick[from];
		mQuick[from] = mQuick[to];
		mQuick[to] = temp;

		/// 아이콘 정보 스왑
		cBindIcon tempIcon;
		tempIcon.mColumnIcon = srcIcon;
		tempIcon.mRowIcon = srcIcon;

		int fromId = ( fromIsFS == false ) ? mDragIcon->GetID() : mDragIcon->GetID() + QUICKSLOT_COUNT;
		tempIcon = mBindIcon[toId];
		mBindIcon[toId] = mBindIcon[fromId];
		mBindIcon[fromId] = tempIcon;

		/// 색 변경
		mBindIcon[toId].SetColor( mQuick[to].mColor );
		mBindIcon[fromId].SetColor( mQuick[from].mColor );

		/// 애니메이션 세팅
 		mBindIcon[toId].SetAniParam( mQuick[to].mAniParam );
		mBindIcon[fromId].SetAniParam( mQuick[from].mAniParam );

		/// 레어도타입 세팅
		mBindIcon[toId].SetTipType( mQuick[to].mTipType );
		mBindIcon[fromId].SetTipType( mQuick[from].mTipType );
	}
	else
	{
		/// 없으면 이동 
		mQuick[to] = mQuick[from];

		/// 아이콘 세팅
		mBindIcon[toId] = *mDragIcon;
		mBindIcon[toId].SetColor( mQuick[to].mColor );
		mBindIcon[toId].SetAniParam( mQuick[to].mAniParam );
		mBindIcon[toId].SetTipType( mQuick[to].mTipType );

		/// 삭제 
		int fromId = ( fromIsFS == false ) ? mDragIcon->GetID() : mDragIcon->GetID() + QUICKSLOT_COUNT;
		DeleteData( fromId, from );
	}

	/// 퀵슬롯 정보 서버에 쏘기
	NetUpdateData();
}

void cQuickManager::UpdateUI()
{
	mTabIndexFS = ITEMMAN->GetActiveWeapon();

	/// 일반 퀵슬롯
	unsigned int slot = mTabIndex * QUICKSLOT_COUNT;
	for( unsigned int i = slot; i < slot + QUICKSLOT_COUNT; ++i )
	{
		unsigned iconId = i - slot;
		UpdateIcon( i, iconId, false );	
	}
	
	/// FS 퀵슬롯
	slot = (mTabIndexFS * QUICKSLOT_COUNT) + QUICKSLOT_FS_BEGIN;
	for( unsigned int i = slot; i < slot + QUICKSLOT_COUNT; ++i )
	{
		unsigned iconId = i - slot + QUICKSLOT_COUNT;
		UpdateIcon( i, iconId, false );	
	}

	/// 쿨타임 로딩
	LoadCoolTime();
}

/// 퀵슬롯 생성후 OnShow 시 자동호출
/// 현재 탭인덱스를 기반으로 퀵슬롯 정보 업데이트 
void cQuickManager::UpdateIcon( int i, int iconId, bool countCheck )
{
	/// 초기화
	/// 0 이되면 아이콘 안에서 아무것도 그리지 않으므로 갯수도 안그려진다.
	mBindIcon[iconId].SetParam( 0 );
	mBindIcon[iconId].SetAniParam( 0 );
	mBindIcon[iconId].SetTipType( eTOOLTIP_NONE );

	/// 스킬 아이콘 세팅
	if( mQuick[i].mType == eSHORTCUT_SKILL )
	{
		sKeepSkill* p = SKILLMAN->GetKeepInfo( mQuick[i].mSkillIndex );
		assert(p);
		mQuick[i].mSkillStep = 0;
		if( p )
			mQuick[i].mSkillStep = p->mStep;

		sPlayerSkillBaseInfo* info = SKILLSCRIPT->GetPlayerSkillInfo( mQuick[i].mSkillIndex );
		if( info )
		{
			cIconParam* param = UIMAN->GetIconParam( info->mIconIdx );
			if( param )
			{
				/// 세팅
				mBindIcon[iconId].SetParam( param );
				mBindIcon[iconId].SetCount( 0 );
				mBindIcon[iconId].ShowNumber( false );
				mBindIcon[iconId].SetColor( mQuick[i].mColor );
				mBindIcon[iconId].SetAniParam( mQuick[i].mAniParam );
				mBindIcon[iconId].SetTipType( mQuick[i].mTipType );
			}
		}
		else
		{
			assert(0);
		}
	}
	else if( mQuick[i].mType == eSHORTCUT_COMMU )
	{
		sCommunitySkillInfo* pInfo = COMMUNITYSCRIPT->GetCommunityInfo( mQuick[i].mSkillIndex );
		if( pInfo )
		{
			cIconParam* param = UIMAN->GetIconParam( pInfo->mIconIndex );
			if( param )
			{
				/// 세팅
				mBindIcon[iconId].SetParam( param );
				mBindIcon[iconId].SetCount( 0 );
				mBindIcon[iconId].ShowNumber( false );
				mBindIcon[iconId].SetColor( mQuick[i].mColor );
				mBindIcon[iconId].SetAniParam( mQuick[i].mAniParam );
				mBindIcon[iconId].SetTipType( mQuick[i].mTipType );
			}
		}
		else
		{
			assert(0);
		}
	}
	/// 아이템 아이콘 세팅 
	else if( mQuick[i].mType == eSHORTCUT_ITEM )
	{
		cItemDefine* itemDefine = ITEMMAN->GetItemDefine( mQuick[i].mItemIndex );
		if( itemDefine )
		{
			cIconParam* param = itemDefine->GetIconParam();
			if( param )
			{
				/// 세팅
				mBindIcon[iconId].SetParam( param );

				/// 갯수 검사를 해야할때만한다
				if( countCheck )
					SetTotalCount( i, iconId, mQuick[i].mItemIndex );

				///
				mQuick[i].mTipType = (unsigned int)itemDefine->GetTipType();
				mBindIcon[iconId].SetAniParam( mQuick[i].mAniParam );
				mBindIcon[iconId].SetTipType( mQuick[i].mTipType );
			}
		}
		else
		{
			assert(0);
		}
	}			
}

/// 데이터삭제
void cQuickManager::DeleteData()
{
	if( mDragIcon )
	{
		cUIContainer* fromParent = mDragIcon->GetParent();
		if( !fromParent )
		{
			assert(0);
			return;
		}

		/// fs 슬롯에서 온건지 판별
		bool fromIsFS = ( fromParent->GetID() == eUIID_COLUMN_QUICKSLOT || fromParent->GetID() == eUIID_ROW_QUICKSLOT ) ? false : true;

        ///
		int dataIndex = mDragIcon->GetID() + (( fromIsFS == false ) ? mTabIndex * QUICKSLOT_COUNT : ( mTabIndexFS * QUICKSLOT_COUNT ) + QUICKSLOT_FS_BEGIN);
		unsigned int iconId = ( fromIsFS == false ) ? mDragIcon->GetID() : mDragIcon->GetID() + QUICKSLOT_COUNT;

		DeleteData( iconId, dataIndex );

		/// 퀵슬롯 정보 서버에 쏘기
		NetUpdateData();
	}
}

///
void cQuickManager::DeleteData( unsigned int iconId, unsigned int dataIndex )
{
	if( iconId >= ICON_COUNT )
	{
		assert(0);
		return;
	}

	/// 데이터초기화
	mQuick[dataIndex] = 0;

	/// 아이콘 초기화
	mBindIcon[iconId].SetParam( 0 );
	mBindIcon[iconId].SetCount( 0 );
	mBindIcon[iconId].SetTipType( eTOOLTIP_NONE );
	mBindIcon[iconId].SetColor( NiColorA::WHITE );
}

/// 퀵슬롯에 등록된 아이템 총 갯수 갱신
/// 현재 출력되고 있는 탭만 갱신
void cQuickManager::CheckItemIcon()
{
	unsigned int slot = mTabIndex * QUICKSLOT_COUNT;
	for( unsigned int i = slot; i < slot + QUICKSLOT_COUNT; ++i )
	{
		unsigned iconId = i - slot;

		/// 아이템이면 개수 갱신
		if( mQuick[i].mType == eSHORTCUT_ITEM )
		{
			SetTotalCount( i, iconId, mQuick[i].mItemIndex );
		}
	}

	/// FS 슬롯
	slot = (mTabIndexFS * QUICKSLOT_COUNT) + QUICKSLOT_FS_BEGIN;
	for( unsigned int i = slot; i < slot + QUICKSLOT_COUNT; ++i )
	{
		unsigned iconId = i - slot + QUICKSLOT_COUNT;

		if( iconId >= ICON_COUNT )
		{
			assert(0);
			return;
		}

		/// 아이템이면 개수 갱신
		if( mQuick[i].mType == eSHORTCUT_ITEM )
		{
			SetTotalCount( i, iconId, mQuick[i].mItemIndex );
		}
	}

	/// 몬스텨 변신일경우 FS퀵슬롯 재세팅
	if( mIsLockByMonster == true )
	{
		for( int i = 0; i < QUICK_COUNT_MON; ++i )
		{
			/// 퀵슬롯 아이콘 세팅
			mBindIcon[ QUICKSLOT_COUNT+i ].SetColor( mQuick[QUICKSLOT_MON_BEGIN+i].mColor );
			mBindIcon[ QUICKSLOT_COUNT+i ].SetCount( 0 );
			mBindIcon[ QUICKSLOT_COUNT+i ].ShowNumber( false );
		}
	}
}

/// 총 갯수 세팅
void cQuickManager::SetTotalCount( unsigned int dataIndex, unsigned int iconId, unsigned long itemIndex )
{
	if( itemIndex == 0 )
		return;

	cItemDefine* itemDefine = ITEMMAN->GetItemDefine( itemIndex );
	if( !itemDefine )
	{
		assert(0);
		return;
	}
	unsigned char type = itemDefine->GetType();
	unsigned char subtype = itemDefine->GetSubType();

	/// 일정 타입만 등록됨
	if( type == ITEM_ETC1 || (type == ITEM_CARD && subtype == ITEM_CARD_COMMON) 
						  || (type == ITEM_MATERIAL && subtype == ITEM_MATERIAL_MAP)
						  || (type == ITEM_MATERIAL && subtype == ITEM_MATERIAL_VEHICLE) )
	{
		/// 해당 타입의 아이템은 인벤에 없어도 0으로 찍는다.
		unsigned int count = ITEMMAN->GetItemCount( itemIndex );
		if( count <= 0 )
		{
			mQuick[dataIndex].mColor = NiColorA( 0.5f, 0.5f, 0.5f, 1.0f );
		}
		else
		{
			mQuick[dataIndex].mColor = NiColorA::WHITE;
		}

		/// 몬스터 변신상태가 아닐때만 세팅하도록 한다
		//if( mIsLockByMonster && iconId >= QUICKSLOT_COUNT && iconId < QUICKSLOT_COUNT + QUICK_COUNT_MON )
		//	return;
	
		mBindIcon[iconId].SetCount( count );
		mBindIcon[iconId].ShowNumber( true );
		mBindIcon[iconId].SetColor( mQuick[dataIndex].mColor );
	}
	/*else
	{
		/// 전체 아이템 등록가능시 사용하는 부분
		mQuick[dataIndex].mColor = NiColorA::WHITE;
		mBindIcon[iconId].SetCount(1);		
		mBindIcon[iconId].ShowNumber( false );
		mBindIcon[iconId].SetColor( NiColorA::WHITE );
	}*/
}

/// 게임접속시 쿨타임 매니저로부터 모든 쿨타임을 복사하도록 한다
void cQuickManager::SetAllItemCool()
{	
	for( unsigned int slot = 0; slot < QUICK_COUNT; ++slot )
	{
		if( mQuick[slot].mType != eSHORTCUT_ITEM )
			continue;

		COOLMAN->RequestQuickCool( slot, mQuick[slot].mItemIndex );
	}
}

/// 아이템 쿨타임 세팅
void cQuickManager::SetItemCool( unsigned int quickIdx, unsigned long startTime, unsigned long restTime, unsigned long totalTime )
{
	mQuick[quickIdx].mStartTime = startTime;
	mQuick[quickIdx].mMaintainTime = totalTime;
	mQuick[quickIdx].mElapsedTime = totalTime - restTime;

	LoadCoolTime();
}

/// 탭체인지등을 위해 쿨타임 데이터 저장
void cQuickManager::SaveSkillCool( unsigned int dataIdx, unsigned int iconId )
{
	cIcon* icon = mBindIcon[iconId].mColumnIcon;
	cUIRoundGauge& gauge = icon->GetGauge();
	if( gauge.mActivate == false )
		return;

	/// 자기랑 동일한 데이터 모두 세팅
	for( unsigned int slot = 0; slot < QUICK_TOTAL; ++slot )
	{
		if( mQuick[slot].mType == eSHORTCUT_NONE )
			continue;

		if( mQuick[slot].mType == eSHORTCUT_SKILL && mQuick[dataIdx].mType == eSHORTCUT_SKILL )
		{
			/// 동일 스킬 찾기
			if( mQuick[slot].mSkillIndex == mQuick[dataIdx].mSkillIndex )
			{
				mQuick[slot].mStartTime = gauge.mStartTime;
				mQuick[slot].mElapsedTime = gauge.mElapsedTime;
				mQuick[slot].mMaintainTime = gauge.mMaintainTime;
			}
		}
	}
}

/// 몬스터 스킬 쿨타임 저장
void cQuickManager::SaveSkillCoolMon( unsigned int dataIdx, unsigned int iconId )
{
	cIcon* icon = mBindIcon[iconId].mColumnIcon;
	cUIRoundGauge& gauge = icon->GetGauge();
	if( gauge.mActivate == false )
		return;

	if( mQuick[dataIdx].mType == eSHORTCUT_MONSKILL )
	{
		/// 동일 스킬 찾기
		mQuick[dataIdx].mStartTime = gauge.mStartTime;
		mQuick[dataIdx].mElapsedTime = gauge.mElapsedTime;
		mQuick[dataIdx].mMaintainTime = gauge.mMaintainTime;
	}
}


void cQuickManager::ClearCoolTime( unsigned int slottype, unsigned long index )
{
	for( unsigned int slot = 0; slot < QUICK_COUNT; ++slot )
	{
		if( mQuick[slot].mType == eSHORTCUT_NONE )
			continue;

		if( slottype == eSHORTCUT_SKILL )
		{
			if( mQuick[slot].mSkillIndex == index )
			{
				mQuick[slot].mStartTime = 0;
				mQuick[slot].mMaintainTime = 0;
				mQuick[slot].mElapsedTime = 0;
			}
		}
		else if( slottype == eSHORTCUT_ITEM )
		{
			if( mQuick[slot].mItemIndex == index )
			{
				mQuick[slot].mStartTime = 0;
				mQuick[slot].mMaintainTime = 0;
				mQuick[slot].mElapsedTime = 0;
			}
		}
	}
}

/// 탭체인지시, 각 쿨타임 데이터 로드
void cQuickManager::LoadCoolTime()
{
	for( unsigned int i = 0; i < ICON_COUNT; ++i )
	{
		unsigned int dataIndex = i + ( mTabIndex * QUICKSLOT_COUNT );

		/// FS 슬롯
		if( i >= QUICKSLOT_COUNT )
			dataIndex = i + ( mTabIndexFS * QUICKSLOT_COUNT ) + QUICKSLOT_FS_BEGIN - QUICKSLOT_COUNT;
		
		if( mQuick[dataIndex].mType != eSHORTCUT_NONE )
		{
			/// column 아이콘 세팅
			cIcon* colIcon = mBindIcon[i].mColumnIcon;
			cUIRoundGauge& colGauge = colIcon->GetGauge();
			colGauge.mStartTime = mQuick[dataIndex].mStartTime;
			colGauge.mElapsedTime = mQuick[dataIndex].mElapsedTime;
			colGauge.mMaintainTime = mQuick[dataIndex].mMaintainTime;
			colGauge.mActivate = true;

			/// row 아이콘 세팅
			cIcon* rowIcon = mBindIcon[i].mRowIcon;
			cUIRoundGauge& rowGauge = rowIcon->GetGauge();
			rowGauge.mStartTime = mQuick[dataIndex].mStartTime;
			rowGauge.mElapsedTime = mQuick[dataIndex].mElapsedTime;
			rowGauge.mMaintainTime = mQuick[dataIndex].mMaintainTime;
			rowGauge.mActivate = true;
		}
	}
	
	/// 몬스터 변신시
	LoadCoolTimeMon();
}

/// 몬스터 쿨타임 세팅
void cQuickManager::LoadCoolTimeMon()
{
	/// 몬스터 변신시
	if( !mIsLockByMonster )
		return;

	for( unsigned int i = 0; i < QUICK_COUNT_MON; ++i )
	{
		unsigned int dataIndex = QUICKSLOT_MON_BEGIN+i;
		unsigned int iconId = QUICKSLOT_COUNT + i;

		if( mQuick[dataIndex].mType == eSHORTCUT_MONSKILL )
		{
			/// column 아이콘 세팅
			cIcon* colIcon = mBindIcon[iconId].mColumnIcon;
			if( colIcon )
			{
				cUIRoundGauge& colGauge = colIcon->GetGauge();
				colGauge.mStartTime = mQuick[dataIndex].mStartTime;
				colGauge.mElapsedTime = mQuick[dataIndex].mElapsedTime;
				colGauge.mMaintainTime = mQuick[dataIndex].mMaintainTime;
				colGauge.mActivate = true;

				if( THEAPP->GetWorldAccumTime() - mQuick[dataIndex].mStartTime > mQuick[dataIndex].mMaintainTime - mQuick[dataIndex].mElapsedTime )
					colGauge.mActivate = false;
			}
			else
			{
				assert(0);
			}

			/// row 아이콘 세팅
			cIcon* rowIcon = mBindIcon[iconId].mRowIcon;
			if( rowIcon )
			{
				cUIRoundGauge& rowGauge = rowIcon->GetGauge();
				rowGauge.mStartTime = mQuick[dataIndex].mStartTime;
				rowGauge.mElapsedTime = mQuick[dataIndex].mElapsedTime;
				rowGauge.mMaintainTime = mQuick[dataIndex].mMaintainTime;
				rowGauge.mActivate = true;

				if( THEAPP->GetWorldAccumTime() - mQuick[dataIndex].mStartTime > mQuick[dataIndex].mMaintainTime - mQuick[dataIndex].mElapsedTime )
					rowGauge.mActivate = false;
			}
			else
			{
				assert(0);
			}
		}
	}
}


/// 스킬 사용시 호출
void cQuickManager::StartSkillCoolTime( unsigned long skillIndex, unsigned long cool )
{
	if( skillIndex <= 0 )
	{
		assert(0);
		return;
	}
	
	for( unsigned int i = 0; i < ICON_COUNT; ++i )
	{
		unsigned int dataIndex = i + ( mTabIndex * QUICKSLOT_COUNT );
		
		/// FS 슬롯
		if( i >= QUICKSLOT_COUNT )
			dataIndex = i + ( mTabIndexFS * QUICKSLOT_COUNT ) + QUICKSLOT_FS_BEGIN - QUICKSLOT_COUNT;

		if( mQuick[dataIndex].mType == eSHORTCUT_SKILL )
		{
			if( mQuick[dataIndex].mSkillIndex == skillIndex )
			{
				/// 아이콘 세팅
				mBindIcon[i].mColumnIcon->StartDelay( cool );
				mBindIcon[i].mRowIcon->StartDelay( cool );

				SaveSkillCool( dataIndex, i );
			}
		}
	}
}

void cQuickManager::StartCoolTime( unsigned long itemIndex, unsigned long coolTime )
{
	/// 정보 세팅
	for( unsigned int slot = 0; slot < QUICK_COUNT; ++slot )
	{
		if( mQuick[slot].mType != eSHORTCUT_ITEM )
			continue;

		/// 동일한 아이템 모두 세팅
		if( mQuick[slot].mItemIndex == itemIndex )
		{
			mQuick[slot].mStartTime = THEAPP->GetWorldAccumTime();
			mQuick[slot].mElapsedTime = 0;
			mQuick[slot].mMaintainTime = coolTime;
		}
	}

	/// ui갱신
	LoadCoolTime();
}

void cQuickManager::EndCoolTime( unsigned long itemIndex )
{
	/// 정보 세팅
	for( unsigned int slot = 0; slot < QUICK_COUNT; ++slot )
	{
		if( mQuick[slot].mType != eSHORTCUT_ITEM )
			continue;

		/// 동일한 아이템 모두 세팅
		if( mQuick[slot].mItemIndex == itemIndex )
		{
			mQuick[slot].mStartTime = 0;
			mQuick[slot].mElapsedTime = 0;
			mQuick[slot].mMaintainTime = 0;
		}
	}

	/// ui갱신
	LoadCoolTime();
}

/// 재접속시, 남은 스킬 쿨타임 세팅 
void cQuickManager::InitSkillCooltime( unsigned long skillIndex, unsigned long restTime, unsigned long totalTime )
{
	if( skillIndex <= 0 )
	{
		assert(0);
		return;
	}

	/// 자기랑 동일한 데이터 모두 세팅
	for( unsigned int slot = 0; slot < QUICK_COUNT; ++slot )
	{
		if( mQuick[slot].mType != eSHORTCUT_SKILL )
			continue;

		/// 동일한 스킬을 모두 세팅.
		if( mQuick[slot].mSkillIndex == skillIndex )
		{
			mQuick[slot].mStartTime = THEAPP->GetWorldAccumTime();
			mQuick[slot].mElapsedTime = totalTime - restTime;
			mQuick[slot].mMaintainTime = totalTime;
		}
	}
}

void cQuickManager::SetSkillAniAura( unsigned long skillIndex, sAniParam* param )
{
	for( unsigned int i = 0; i < QUICK_COUNT; ++i )
	{
		if( mQuick[i].mType != eSHORTCUT_SKILL )
			continue;

		/// 아이콘 애니메이션 세팅
		if( mQuick[i].mSkillIndex == skillIndex )
			mQuick[i].mAniParam = param;
	}

	for( unsigned int i = 0; i < ICON_COUNT; ++i )
	{
		unsigned int dataIndex = i + ( mTabIndex * QUICKSLOT_COUNT );

		/// FS 슬롯
		if( i >= QUICKSLOT_COUNT )
			dataIndex = i + ( mTabIndexFS * QUICKSLOT_COUNT ) + QUICKSLOT_FS_BEGIN - QUICKSLOT_COUNT;

		if( mQuick[dataIndex].mType == eSHORTCUT_SKILL )
		{
			/// 아이콘 애니메이션 세팅
			if( mQuick[dataIndex].mSkillIndex == skillIndex )
				mBindIcon[i].SetAniParam( param );
		}
	}
}	

void cQuickManager::CheckSkillIcon()
{
	/// HERO 가 착용한 무기 타입 
	eWEAPON_STATE wstate = HERO->GetWeaponState();

	/// 퀵슬롯 전체 검사
	for( unsigned int slot = 0; slot < QUICK_COUNT; ++slot )
	{
		if( mQuick[slot].mType != eSHORTCUT_SKILL )
			continue;

		if( UsableSkillIcon( wstate, mQuick[slot].mSkillIndex, mQuick[slot].mSkillStep) == true )
		{
			mQuick[slot].mColor = NiColorA::WHITE;
		}
		else
		{
			mQuick[slot].mColor = NiColorA( 1.0f, 0.0f, 0.0f, 1.0f );
		}
	}

	/// 몬스터 변신상태인경우.
	if( mIsLockByMonster == true )
	{
		for( unsigned int slot = 0; slot < QUICK_COUNT_MON; ++slot )
		{
			unsigned int dataIndex = QUICKSLOT_MON_BEGIN + slot;
			if( mQuick[dataIndex].mSkillIndex == ULONG_MAX )
				continue;

			if( UsableMonSkillIcon( mQuick[dataIndex].mSkillIndex ) == true )
			{
				mQuick[dataIndex].mColor = NiColorA::WHITE;
			}
			else
			{
				mQuick[dataIndex].mColor = NiColorA( 1.0f, 0.0f, 0.0f, 1.0f );
			}
		}
	}

	/// 일반 슬롯 아이콘 갱신
	for( unsigned int i = 0; i < QUICKSLOT_COUNT; ++i )
	{
		unsigned int dataIndex = i + ( mTabIndex * QUICKSLOT_COUNT );
		if( mQuick[dataIndex].mType == eSHORTCUT_SKILL )
			mBindIcon[i].SetColor( mQuick[dataIndex].mColor );
	}

	/// FS 슬롯 아이콘 갱신
	for( unsigned int i = QUICKSLOT_COUNT; i < ICON_COUNT; ++i )
	{
		unsigned int dataIndex = i + ( mTabIndexFS * QUICKSLOT_COUNT ) + QUICKSLOT_FS_BEGIN - QUICKSLOT_COUNT;

		/// 몬스터 변신인경우,
		if( mIsLockByMonster == true && i < QUICKSLOT_COUNT + QUICK_COUNT_MON )
			dataIndex = i + QUICKSLOT_MON_BEGIN - QUICKSLOT_COUNT;

		if( mQuick[dataIndex].mType == eSHORTCUT_SKILL || 
			mQuick[dataIndex].mType == eSHORTCUT_MONSKILL )
		{
			mBindIcon[i].SetColor( mQuick[dataIndex].mColor );
		}
	}
}

bool cQuickManager::UsableMonSkillIcon( unsigned long skillindex )
{
	unsigned long monIdx = HERO->GetTransMonsterClassIdx();
	sMonsterSkillScript* skill = SKILLSCRIPT->GetMonsterSkillInfo( monIdx, (eMONSTERATTACK_TYPE)skillindex );
	if( !skill )
	{
		assert(0);
		return false;
	}

	/// 소모 MP 량 검사
	unsigned long curMP = HERO->GetMP();
	if( curMP < skill->mUseMP )
		return false;
	return true;
}

bool cQuickManager::UsableSkillIcon( eWEAPON_STATE heroWeaponState, unsigned long skillindex, unsigned char skillstep )
{
	///
	if( HERO->IsTransformMonster() )
		return false;

	/// 동일한 스킬을 모두 세팅.
	sPlayerSkillBaseInfo* pInfo = SKILLSCRIPT->GetPlayerSkillInfo( skillindex );
	if( pInfo == 0 )
	{
		assert(0);
		return false;
	}

	if( skillstep >= pInfo->mStepCount )
	{
		assert(0);
		return false;
	}
	sPlayerSkillStepInfo* pStepInfo = &pInfo->mpSetpInfoArray[skillstep];

	/// use item check
	if( pInfo->mUseItem )
	{
		unsigned int count = ITEMMAN->GetItemCount( pInfo->mUseItem );
		if( count < pStepInfo->mUseItemCount )
			return false;
	}

	/// 현재 MP량
	unsigned long curMP = HERO->GetMP();
	if( curMP < pStepInfo->mUseMP )
		return false;

	if( pInfo->mUseEquipment )
	{
		/// 착용 장비 체크
		switch( pInfo->mUseEquipment )
		{
		case eEQUIPTYPE_SWORD:
			if( heroWeaponState != eWEAPON_STATE_SWORD &&
				heroWeaponState != eWEAPON_STATE_SWORD_SHEILD )
				return false;
			break;
		case eEQUIPTYPE_LONGSWORD:
			if( heroWeaponState != eWEAPON_STATE_LONGSWORD )
				return false;
			break;
		case eEQUIPTYPE_DOUBLESWORD:
			if( heroWeaponState != eWEAPON_STATE_DOUBLESWORD )
				return false;
			break;
		case eEQUIPTYPE_SHORTSWORD:
			if( heroWeaponState != eWEAPON_STATE_SHORTSWORD )
				return false;
			break;
		case eEQUIPTYPE_GUN:
			if( heroWeaponState != eWEAPON_STATE_GUN )
				return false;
			break;
		case eEQUIPTYPE_STAFF:
			if( heroWeaponState != eWEAPON_STATE_STAFF )
				return false;
			break;
		case eEQUIPTYPE_SHIELD:
			if( heroWeaponState != eWEAPON_STATE_SHEILD &&
				heroWeaponState != eWEAPON_STATE_SWORD_SHEILD )
				return false;
			break;
		case eEQUIPTYPE_SWORD_LONGSWORD:
			if( heroWeaponState != eWEAPON_STATE_SWORD &&
				heroWeaponState != eWEAPON_STATE_SWORD_SHEILD &&
				heroWeaponState != eWEAPON_STATE_LONGSWORD )
				return false;
			break;
		case eEQUIPTYPE_SWORD_DOUBLESWORD:
			if( heroWeaponState != eWEAPON_STATE_SWORD &&
				heroWeaponState != eWEAPON_STATE_SWORD_SHEILD &&
				heroWeaponState != eWEAPON_STATE_DOUBLESWORD )
				return false;
			break;
		case eEQUIPTYPE_LONGSWORD_DOUBLESWORD:
			if( heroWeaponState != eWEAPON_STATE_LONGSWORD &&
				heroWeaponState != eWEAPON_STATE_DOUBLESWORD )
				return false;
			break;
		case eEQUIPTYPE_SWORD_LONGSWORD_DOUBLESWORD:
			if( heroWeaponState != eWEAPON_STATE_SWORD &&
				heroWeaponState != eWEAPON_STATE_SWORD_SHEILD &&
				heroWeaponState != eWEAPON_STATE_LONGSWORD &&
				heroWeaponState != eWEAPON_STATE_DOUBLESWORD )
				return false;
			break;
		case eEQUIPTYPE_SHORTSWORD_GUN:
			if( heroWeaponState != eWEAPON_STATE_SHORTSWORD &&
				heroWeaponState != eWEAPON_STATE_GUN )
				return false;
			break;
		}
	}
	return true;
}

void cQuickManager::SetCharge( unsigned long skillIndex, bool charge )
{
	if( HERO->IsTransformMonster() == true )
	{
		assert(0);
		return;
	}

	eWEAPON_STATE wstate = HERO->GetWeaponState();

	sPlayerSkillBaseInfo* pInfo = SKILLSCRIPT->GetPlayerSkillInfo( skillIndex );
	if( pInfo )
	{
		/// 사용 가능 무기가 아니면 리턴
		if( wstate != pInfo->mUseEquipment )
			return;
	}

	/// 퀵슬롯 전체 검사
	bool update = false;
	for( unsigned int slot = 0; slot < QUICK_COUNT; ++slot )
	{
		if( mQuick[slot].mType != eSHORTCUT_SKILL )
			continue;

		/// 해당스킬이면 챠지
		if( mQuick[slot].mSkillIndex == skillIndex )
		{
			update = true;

			if( charge == true )
				mQuick[slot].mColor = NiColorA( 0.78f, 0.77f, 0.12f, 1.0f );
			else
			{
				/// charge가 풀릴때 상태검사
				eWEAPON_STATE wstate = HERO->GetWeaponState();
				if( UsableSkillIcon( wstate, mQuick[slot].mSkillIndex, mQuick[slot].mSkillStep ) == true )
					mQuick[slot].mColor =  NiColorA::WHITE;
				else
					mQuick[slot].mColor = NiColorA( 1.0f, 0.0f, 0.0f, 1.0f );
			}
		}
	}

	if( update == true )
	{
		for( unsigned int i = 0; i < ICON_COUNT; ++i )
		{
			unsigned int dataIndex = i + ( mTabIndex * QUICKSLOT_COUNT );

			/// FS 슬롯
			if( i >= QUICKSLOT_COUNT )
				dataIndex = i + ( mTabIndexFS * QUICKSLOT_COUNT ) + QUICKSLOT_FS_BEGIN - QUICKSLOT_COUNT;

			if( mQuick[dataIndex].mType == eSHORTCUT_SKILL )
				mBindIcon[i].SetColor( mQuick[dataIndex].mColor );
		}
	}
}

/// 몬스터 스킬 챠지
void cQuickManager::SetMonCharge( unsigned long skillIndex, bool charge )
{
	for( unsigned int slot = 0; slot < QUICK_COUNT_MON; ++slot )
	{
		int dataIndex = QUICKSLOT_MON_BEGIN + slot;
		if( mQuick[dataIndex].mSkillIndex == ULONG_MAX )
			continue;

		if( mQuick[dataIndex].mSkillIndex == skillIndex )
		{
			if( charge == true )
				mQuick[dataIndex].mColor = NiColorA( 0.78f, 0.77f, 0.12f, 1.0f );
			else
			{
				if( UsableMonSkillIcon( skillIndex ) == true )
					mQuick[dataIndex].mColor = NiColorA::WHITE;
				else
					mQuick[dataIndex].mColor = NiColorA( 1.0f, 0.0f, 0.0f, 1.0f );
			}

			mBindIcon[slot+QUICKSLOT_COUNT].SetColor( mQuick[dataIndex].mColor );
		}
	}
}

void cQuickManager::ChangeMonster( unsigned long monIndex )
{
	/// 몬스터 변신
	if( monIndex > 0 )
	{	
		mIsLockByMonster = true;
	
		/// 세팅
		for( int i = 0; i < QUICK_COUNT_MON; ++i )
		{
			unsigned int dataIndex = QUICKSLOT_MON_BEGIN+i;

			/// 초기화
			mQuick[dataIndex] = 0;

			sMonsterSkillScript* skill = SKILLSCRIPT->GetMonsterSkillInfo( monIndex, (eMONSTERATTACK_TYPE)(eMONSTERATTACK_SKILL1 + i) );
			if( skill )
			{
				mQuick[dataIndex].mType = eSHORTCUT_MONSKILL;
				mQuick[dataIndex].mSkillIndex = eMONSTERATTACK_SKILL1 + i;
				mQuick[dataIndex].mColor = NiColorA::WHITE;
			}
			else
			{
				mQuick[dataIndex].mType = eSHORTCUT_MONSKILL;
				mQuick[dataIndex].mSkillIndex = ULONG_MAX;
				mQuick[dataIndex].mColor = NiColorA( 0.5f, 0.5f, 0.5f, 1.0f );
			}

			/// 퀵슬롯 아이콘 세팅
			unsigned int iconId = QUICKSLOT_COUNT + i;
			mBindIcon[iconId].SetColor( mQuick[dataIndex].mColor );
			mBindIcon[iconId].SetParam( UIMAN->GetIconParam(MONICON_PARAMINDEX + i) );
			mBindIcon[iconId].SetCount( 0 );
			mBindIcon[iconId].ShowNumber( false );
			mBindIcon[iconId].SetColor( mQuick[dataIndex].mColor );
			mBindIcon[iconId].SetAniParam( mQuick[dataIndex].mAniParam );
			mBindIcon[iconId].SetTipType( mQuick[dataIndex].mTipType );
		}
	}
	/// 변신 해제
	else
	{
		mIsLockByMonster = false; 

		/// FS 퀵슬롯 재세팅 - 앞에서부터 3개만 리셋
		unsigned int slot = (mTabIndexFS * QUICKSLOT_COUNT) + QUICKSLOT_FS_BEGIN;
		for( unsigned int i = slot; i < slot + QUICK_COUNT_MON; ++i )
		{
			unsigned iconId = i - slot + QUICKSLOT_COUNT;
			UpdateIcon( i, iconId );	
		}

		LoadCoolTime();
	}
}

void cQuickManager::InitMonSkillCooltime( short skillindex, unsigned long restTime, unsigned long totalTime )
{
	if( restTime <= 0 || totalTime <= 0 )
		return;

	int i = skillindex - eMONSTERATTACK_SKILL1;
	if( i >= 0 && i < QUICK_COUNT_MON )
	{
		/// 자기랑 동일한 데이터 모두 세팅
		for( unsigned int slot = 0; slot < QUICK_COUNT_MON; ++slot )
		{
			int dataIndex = QUICKSLOT_MON_BEGIN + slot;
			if( mQuick[dataIndex].mSkillIndex == -1 )
				continue;

			/// 동일한 스킬을 모두 세팅.
			if( mQuick[dataIndex].mSkillIndex == skillindex )
			{
				mQuick[dataIndex].mStartTime = THEAPP->GetWorldAccumTime();
				mQuick[dataIndex].mElapsedTime = totalTime - restTime;
				mQuick[dataIndex].mMaintainTime = totalTime;
			}
		}
	}
	else
	{
		assert(0);
	}
}

void cQuickManager::StartMonSkillCoolTime( short skillIdx, unsigned long cool )
{
	if( cool <= 0 )
		return;

	int i = skillIdx - eMONSTERATTACK_SKILL1;
	if( i >= 0 && i < QUICK_COUNT_MON )
	{
		if( mBindIcon[QUICKSLOT_COUNT+i].mColumnIcon )
			mBindIcon[QUICKSLOT_COUNT+i].mColumnIcon->StartDelay( cool );

		if( mBindIcon[QUICKSLOT_COUNT+i].mRowIcon )
			mBindIcon[QUICKSLOT_COUNT+i].mRowIcon->StartDelay( cool );

		/// 이쪽에 버그-_-
		SaveSkillCoolMon( QUICKSLOT_MON_BEGIN + i, QUICKSLOT_COUNT+i );
	}
	else
	{
		assert(0);
	}
}
