/* ==========================================================================
* 작 성 자 : 이순규
* 작 성 일 : 2007.07.02
* 내    용 : 아이템
* 주의사항 : 
*===========================================================================*/
#pragma once

#include "Item_Common.h"
#include "Player_Common.h"

class cIconParam;

/// 아이템 분해 데이터
const int MAX_DISJOINT = 6;
struct sDisjointData
{
	unsigned long itemIndex;
	unsigned int count;
};

/// 아이템 분해
struct sItemDisjoint
{
	/// 비용
	unsigned long mPrice;

	/// 분해 데이터
	sDisjointData mDisjoint[MAX_DISJOINT];
};

enum eEnhancedType
{
	eENHANCE_PHYSICATTACK = 1,		/// 물공
	eENHANCE_MAGICATTACK,			/// 마공
	eENHANCE_PHYSICDEFENSE,			/// 물방
	eENHANCE_MAGICDEFENSE,			/// 마방
};

/// 아이템 강화
struct sItemEnhanced
{
	/// 강화되는 속성1
	short mEnhanced1;

	/// 강화되는 속성2
	short mEnhanced2;

	/// 증가값
	unsigned int mValue[MAX_ITEM_ENHANCED];
};

/// 어빌리티 효과 정보
struct sAblityOption
{
	short mOptType;		/// 옵션 인덱스겸 타입
	short mOptValue;	/// 옵션 값

	sAblityOption()
	{
		mOptType = 0;
		mOptValue = 0;
	}
};

/// 카드 장착
struct sItemPutCardSlot
{
	short mSlotType[MAX_CARD_SLOT];
};

/// 아이템 장착 타입
enum eItemEquip
{
	ITEM_EQUIP_NORMAL = 0,
	ITEM_EQUIP_ONE_HAND,
	ITEM_EQUIP_TWO_HANDS,
	ITEM_EQUIP_SHIELD
};

/// 아이템 플랙
/// 아이템과 슬롯이 동일한 타입인지 검사 ( 아닌곳에 장착되지 못함 )
enum eItemFlag
{
	ITEM_FLAG_NULL		= 0,
	ITEM_FLAG_WEAPON	= (1 <<  0),
	ITEM_FLAG_WEAR		= (1 <<  1),
	ITEM_FLAG_ACCESSORY	= (1 <<  2),

	ITEM_FLAG_SWORD		= (1 <<  3) | ITEM_FLAG_WEAPON,		/// 한손검
	ITEM_FLAG_BLADE		= (1 <<  4) | ITEM_FLAG_WEAPON,		/// 양손검
	ITEM_FLAG_DUAL		= (1 <<  5) | ITEM_FLAG_WEAPON,		/// 이도류
	ITEM_FLAG_CUTTER	= (1 <<  6) | ITEM_FLAG_WEAPON,		/// 단검
	ITEM_FLAG_GUN		= (1 <<  7) | ITEM_FLAG_WEAPON,		/// 총
	ITEM_FLAG_STAFF		= (1 <<  8) | ITEM_FLAG_WEAPON,		/// 지팡이
	ITEM_FLAG_SHIELD	= (1 <<  9) | ITEM_FLAG_WEAPON,		/// 방패

	ITEM_FLAG_HEAD		= (1 << 10) | ITEM_FLAG_WEAR,		/// 머리
	ITEM_FLAG_UPPER		= (1 << 11) | ITEM_FLAG_WEAR,		/// 상의
	ITEM_FLAG_LOWER		= (1 << 12) | ITEM_FLAG_WEAR,		/// 하의
	ITEM_FLAG_HANDS		= (1 << 13) | ITEM_FLAG_WEAR,		/// 손
	ITEM_FLAG_FEET		= (1 << 14) | ITEM_FLAG_WEAR,		/// 발
	ITEM_FLAG_ONEPIECE	= (1 << 15) | ITEM_FLAG_WEAR,		/// 원피스

	ITEM_FLAG_EARRING	= (1 << 16) | ITEM_FLAG_ACCESSORY,	/// 귀걸이
	ITEM_FLAG_NECKLACE	= (1 << 17) | ITEM_FLAG_ACCESSORY,	/// 목걸이
	ITEM_FLAG_BROOCH	= (1 << 18) | ITEM_FLAG_ACCESSORY,	/// 브로치
	ITEM_FLAG_BRACELET	= (1 << 19) | ITEM_FLAG_ACCESSORY,	/// 팔찌
	ITEM_FLAG_RING		= (1 << 20) | ITEM_FLAG_ACCESSORY,	/// 반지

	ITEM_FLAG_EQUIPCARD	= (1 << 21),						/// 장착용 카드
	ITEM_FLAG_UNKNOWN	= (1 << 22),

	ITEM_FLAG_ALL		= 0x7FFFFFFF
};

/// 아이템 능력
class cItemAbility
{
	friend class cItemManager;

public:
	inline long  GetDescription() { return mDescription; }
	inline short GetTargetType() { return mTargetType; }
	inline short GetDefenseType() { return mDefenseType; }
	inline short GetUseRange() { return mUseRange; }
	inline short GetPhysicMaxAttack() { return mPhysicMaxAttack; }
	inline short GetPhysicMinAttack() { return mPhysicMinAttack; }
	inline short GetMagicMaxAttack() { return mMagicMaxAttack; }
	inline short GetMagicMinAttack() { return mMagicMinAttack; }
	inline short GetPhysicDefense() { return mPhysicDefense; }
	inline short GetMagicDefense() { return mMagicDefense; }
	inline short GetAttackRange() { return mAttackRange; }
	inline short GetAttackSpeed() { return mAttackSpeed; }
	inline long  GetCoolTime() { return mCoolTime; }
	inline unsigned int GetGroupNum() { return mGroupNum; }

	inline sAblityOption* GetOption() { return mOption; }
	inline long GetInfluenceIndex() { return mInfluenceIndex; }

private:
	/// 사용효과 설명 
	long mDescription; 

	/// 방어구재질
	short mDefenseType;

	/// 범위방식
	short mRangeType;

	/// 효과적용타겟
	short mTargetType;

	/// 사용거리
	short mUseRange;

	/// 물리 방어력
	short mPhysicDefense;
	/// 마법 방어력
	short mMagicDefense;

	/// 사정거리
	short mAttackRange;

	/// 공격 속도
	short mAttackSpeed;

	/// 재사용시간
	long mCoolTime;

	/// 그룹쿨타임 번호
	unsigned int mGroupNum;

	/// 물리 공격력(소)
	short mPhysicMinAttack;
	/// 물리 공격력(대)
	short mPhysicMaxAttack;
	/// 마법 공격력(소)
	short mMagicMinAttack;
	/// 마법 공격력(대)
	short mMagicMaxAttack;

	/// 옵션 값
	sAblityOption mOption[10];

	/// 소모효과
	long mInfluenceIndex;
};

/// 아이템 제한
class cItemLimit
{
	friend class cItemManager;

public:
	cItemLimit();

	inline char GetRace() { return mCharRace; }
	inline char GetGender() { return mCharGender; }
	inline long GetJob() { return mCharJob; }
	inline char GetLevel() { return mCharLevel; }
	inline char GetPVPOnly() { return mUsePVPOnly; }

private:
	/// 캐릭터:종족
	char mCharRace;

	/// 캐릭터:성별
	char mCharGender;

	/// 캐릭터:직업
	long mCharJob;

	/// 캐릭터:레벨
	char mCharLevel;

	/// 전장 전용 사용 ( 0 : 사용불가, 1 : 사용가능 )
	char mUsePVPOnly;
};

inline cItemLimit::cItemLimit()
: mCharRace( 0 )
, mCharGender( 0 )
, mCharJob( 0 )
, mCharLevel( 0 )
{
}

/// 스프레드 데이터
class cSpreadParam
{
public:
	/// 이미지 인덱스
	int mImageIndex;

	/// 좌표
	unsigned int mX;

	/// 좌표
	unsigned int mY;

	/// 방향
	int mDir;

	/// 계산식 ( 0 : 노말, 1 : *, 2 : /, 3 : + )
	int mCalc;

	/// 계산수치
	int mValue;
};

/// 아이템 스프레드
class cItemSpread
{
	friend class cItemManager;

public:
	cItemSpread();

public:
	/// 스프레드 데이터 배열
	cSpreadParam mParam[10];
};

inline cItemSpread::cItemSpread()
{	
	memset( mParam, 0, sizeof(mParam) );
}

/// 아이템 카드
class cItemCard
{
	friend class cItemManager;

public:
	cItemCard();

private:
	/// 판
	char mEpisode;

	/// 카드넘버
	unsigned int mCardNumber;

	/// 희귀도
	char mRareLevel;

	/// 카드분류
	char mCardType;

	/// 장착위치
	char mWearPos;

	/// 이미지인덱스
	unsigned int mImageIndex;
};

inline
cItemCard::cItemCard()
: mEpisode(0)
, mCardNumber(0)
, mRareLevel(0)
, mCardType(0)
, mWearPos(0)
, mImageIndex(0)
{

}

/// 아이템 타로카드
class cItemTarot
{
	friend class cItemManager;

public:
	cItemTarot();

	///
	inline unsigned int GetImageIndex() { return mImageIndex; }
	inline unsigned char GetUniqueNumber() { return mNumber; }

	///
	inline short GetStraightValue() { return mStraightValue; }
	inline short GetInverseValue() { return mInverseValue; }

	/// 해석번호 
	inline unsigned long GetStraightDesc() { return mStraightIdx; }
	inline unsigned long GetInverseDesc() { return mInverseIdx; }

private:
	/// 카드 이미지 인덱스
	unsigned int mImageIndex;

	/// 고유 번호
	char mNumber;

	/// 카드레벨
	char mLevel;

	/// 정방향수치
	short mStraightValue;

	/// 역방향수치
	short mInverseValue;

	/// 속성
	char mProperty;

	/// 에피소드(판)
	char mEpisode;

	/// 정방향해석 인덱스 
	unsigned long mStraightIdx;

	/// 역방향해석 인덱스
	unsigned long mInverseIdx;
};

inline cItemTarot::cItemTarot()
: mImageIndex(0)
, mNumber(0)
, mLevel(0)
, mStraightValue(0)
, mInverseValue(0)
, mProperty(0)
, mEpisode(0)
, mStraightIdx(0)
, mInverseIdx(0) 
{

}

/// 아이템 정의
class cItemDefine
{
	friend class cItemManager;

public:
	cItemDefine();

	inline LPCTSTR GetName() { return mName; }
	inline LPCTSTR GetDescription() { return mDescription; }
	inline unsigned char GetType() { return mType; }
	unsigned char GetSubType() { return mSubType; }
	inline unsigned short GetTipType() { return mTooltipColor; }
	inline short GetWeight() { return mWeight; }
	inline unsigned short GetCapacity() { return mCapacity; }
	inline cIconParam* GetIconParam() { return mIconParam; }
	inline const char* GetFileName0( unsigned int race, unsigned int gender );
	inline const char* GetFileName1( unsigned int race, unsigned int gender );
	inline eItemEquip GetEquipType() { return mEquipType; }
	inline cItemCard* GetCardDefine() { return mCard; }
	inline cItemTarot*	GetTarotDefine() { return mTarot; }
	inline cItemSpread* GetSpreadDefine() { return mSpread; }
	inline sItemDisjoint* GetDisjoint() { return mDisjoint; }
	inline sItemPutCardSlot* GetPutCard() { return mPutCardSlot; } 
	inline cItemAbility* GetAbililty() { return mAbility; }
	inline cItemLimit* GetLimit() { return mLimit; }
	inline sItemEnhanced* GetEnhanced() { return mEnhance; }
	inline unsigned long GetBuyPrice() { return mBuyPrice; }
	inline unsigned long GetSellPrice() { return mSellPrice; }
	inline unsigned long GetBuyType() { return mBuyType; }
	inline unsigned long GetSellType() { return mSellType; }
	inline unsigned short GetPutSlotCount() { return mPutSlotCount; }
	inline char GetExchange() { return mExchange; }
	inline unsigned long GetTitleIndex() { return mTitleIndex; }
	inline char GetShowHead() { return mShowHead; }		/// 0 : 머리표시 on, 1 : 머리표시 off

private:
	/// 이름
	LPCTSTR mName;

	/// 설명
	LPCTSTR mDescription;

	/// 종류
	unsigned char mType;

	/// 세부 종류
	unsigned char mSubType;

	/// 무게
	short mWeight;

	/// 제한 수량
	unsigned short mCapacity;

	/// 판매 방법
	unsigned long mSellType;

	/// 판매가격
	unsigned long mSellPrice;

	/// 구입 방법
	unsigned long mBuyType;

	/// 구입가격
	unsigned long mBuyPrice;

	/// 최대 출현갯수
	unsigned long mPresentNum;

	/// 보유 가능 개수
	unsigned long mMaxHaveInven;

	/// 툴팁 컬러 ( 레어도관련 )
	unsigned short mTooltipColor;

	/// 호칭 인덱스
	unsigned long mTitleIndex;

	/// 거래 가능 여부(0거래가능/1거래불가)
	char mExchange;

	/// 능력
	cItemAbility* mAbility;

	/// 제한
	cItemLimit* mLimit;

	/// 카드 인덱스
	cItemCard* mCard;

	/// 타롯 인덱스 
	cItemTarot* mTarot;

	/// 스프레드 인덱스 
	cItemSpread* mSpread;

	/// 분해 정보
	sItemDisjoint* mDisjoint;

	/// 강화 정보
	sItemEnhanced* mEnhance;

	/// 카드장착 슬롯 정보
	sItemPutCardSlot* mPutCardSlot;
	unsigned short mPutSlotCount;			/// 카드장착 가능한 슬롯 갯수

	/// 아이콘 이미지
	cIconParam* mIconParam;

	/// 파일명 배열
	cString* mFileNames0;
	cString* mFileNames1;

	/// 장착 타입
	eItemEquip mEquipType;

	/// 투구 보기
	char mShowHead;

	/// 플랙
	eItemFlag mFlag;
};

inline
cItemDefine::cItemDefine()
: mName( 0 )
, mDescription( 0 )
, mType( 0 )
, mSubType( 0 )
, mWeight( 0 )
, mBuyPrice( 0 )
, mSellPrice( 0 )
, mAbility( 0 )
, mLimit( 0 )
, mCard( 0 )
, mTarot(0)
, mSpread( 0 )
, mDisjoint( 0 )
, mEnhance( 0 )
, mPutCardSlot( 0 )
, mIconParam( 0 )
, mFileNames0( 0 )
, mFileNames1( 0 )
, mEquipType( ITEM_EQUIP_NORMAL )
, mFlag( ITEM_FLAG_NULL )
, mTooltipColor( 0 )
, mPutSlotCount( 0 )
, mTitleIndex( 0 )
, mExchange( false )
, mShowHead( 0 )
{
}

inline
const char* cItemDefine::GetFileName0( unsigned int race, unsigned int gender )
{
	assert( race < eRACE_MAX );
	assert( gender < eGENDER_MAX );

	if( mFileNames0 == 0 )
		return 0;
	else
	{
		if( mType == ITEM_WEAPON )
		{
			/// None인 경우는 인간/남자 사용
			if( mFileNames0[race * eGENDER_MAX + gender] == "None" )
				return mFileNames0[0].Cstr();
			else
				return mFileNames0[race * eGENDER_MAX + gender].Cstr();
		}
		else
		{
			return mFileNames0[race * eGENDER_MAX + gender].Cstr();
		}
	}
}

inline
const char* cItemDefine::GetFileName1( unsigned int race, unsigned int gender )
{
	assert( race < eRACE_MAX );
	assert( gender < eGENDER_MAX );

	if( mFileNames1 == 0 )
		return 0;
	else
	{
		if( mType == ITEM_WEAPON )
		{
			/// None인 경우는 인간/남자 사용
			if( mFileNames1[race * eGENDER_MAX + gender] == "None" )
				return mFileNames1[0].Cstr();
			else
				return mFileNames1[race * eGENDER_MAX + gender].Cstr();
		}
		else
		{
			return mFileNames1[race * eGENDER_MAX + gender].Cstr();
		}
	}
}
