/******************************************************************
  
  Module:  item.h
  
  Author: Sean Craig
  
  Description: Code for game items. 

  
  Copyright 2005 Sony Online Entertainment.  All rights reserved.
  
*******************************************************************/

#ifndef ITEM_H
#define ITEM_H

//-------------------------------------------------------- Includes
#include "SyPropObject.h"
#include "nameid.h"
#include "rulepacket.h"

//-------------------------------------------------------- Typedefs
//---------------------------------------------- Class Declarations
static const int ITEM_CLASSID            =  0xFFFF6001;

class cDatabaseSys;

typedef enum
{
  IT_MELEE,
  IT_RANGED,
  IT_HEAD,
  IT_CHEST,
  IT_SHOULDERS,
  IT_LEGS,
  IT_FEET,
  IT_BELT,
  IT_NECKLACE,
  IT_RING,
  IT_ENHANCEMENT,
  IT_GOLD,
  IT_TRINKET,
  IT_POTION,
  NUM_ITEM_TYPES
} eItemType;

typedef enum
{
  IC_SCOUT,
  IC_MAGE,
  IC_BRUTE,
  IC_ANY,
  NUM_ITEM_CLASSES
} eItemClass; // which classes can use the item

class cStatsItemMaster 
{
public:
  cStatsItemMaster();
  ~cStatsItemMaster();

  cNameID                     mID;
  eItemType                   mType;
  eItemClass                  mClass;

  char *                      mWorldModel; // pathname of model to use when it's sitting in the world                 
  char *                      mFileName; // pathname of model to use when it's sitting in the world                 
  char *                      mIcon; 
  char *                      mAttachModel; 
  char *                      mEmitterModel; 
  tGameID                     mProjectile;  
  int32                       mAttachSkin;

  uint32                      mNameString; // needs localization
  uint32                      mDescriptionString; // needs localization

  int                         mValue;
  eDamageType                 mBaseDamageType;
  int                         mBaseDamageBonus;


  int                         mMaxHP;
  int                         mMaxMana;
  int                         mAttackPower;
  int                         mSpellPower;
  int                         mPhysicalDefense;
  int                         mMagicalDefense;

  static const int  MAX_NUM_ENHANCEMENTS = 4;
  tGameID                     mEnhancements[MAX_NUM_ENHANCEMENTS]; // designer placed enhancemnts; permenantly bound to the item
};

typedef enum
{
  EQUIP_MELEE,
  EQUIP_RANGED,
  EQUIP_HEAD,
  EQUIP_CHEST,
  EQUIP_SHOULDERS,
  EQUIP_LEGS,
  EQUIP_FEET,
  EQUIP_BELT,
  EQUIP_NECKLACE,
  EQUIP_L_RING,
  EQUIP_R_RING,
  EQUIP_UNEQUIPPED,
} eEquipSlot;

typedef enum
{
  SKIN_NONE = 0,
  SKIN_BODY,

  SKIN_BASE_HELMET,
  SKIN_BASE_SHOULDERS,
  SKIN_BASE_CHEST,
  SKIN_BASE_LEGS,
  SKIN_BASE_BOOTS,
  SKIN_BASE_HANDS,

  SKIN_LIGHT_HELMET,
  SKIN_LIGHT_SHOULDERS,
  SKIN_LIGHT_CHEST,
  SKIN_LIGHT_LEGS,
  SKIN_LIGHT_BOOTS,

  SKIN_MEDIUM_HELMET,
  SKIN_MEDIUM_SHOULDERS,
  SKIN_MEDIUM_CHEST,
  SKIN_MEDIUM_LEGS,
  SKIN_MEDIUM_BOOTS,

  SKIN_HEAVY_HELMET,
  SKIN_HEAVY_SHOULDERS,
  SKIN_HEAVY_CHEST,
  SKIN_HEAVY_LEGS,
  SKIN_HEAVY_BOOTS,

  SKIN_HANDS_1,
  SKIN_HANDS_2,
  SKIN_HANDS_3,
  SKIN_HANDS_4,
  SKIN_HANDS_5,
  SKIN_HANDS_6,
  SKIN_HANDS_7,
  SKIN_HANDS_8,
  SKIN_HANDS_9,
  SKIN_HANDS_10,

  NUM_SKINS
} eEquipSkin;

class cStatsEnhancementMaster 
{
public:
  cStatsEnhancementMaster();

  enum DeliveryType
  {
    ENH_DELIVERY_EQUIP,
    ENH_DELIVERY_ATTACK,
    ENH_DELIVERY_DEFEND,
    ENH_DELIVERY_NUM_TYPES,
  };

  enum SlotType
  {    
    ENH_SLOT_UNIVERSAL,
    ENH_SLOT_STATISTICAL,
    ENH_SLOT_PROC,
    ENH_SLOT_UTILITY,
    ENH_SLOT_NUM_TYPES
  };

  void AppendPropertyString(cGameObject *obj,SyString &str) const; 

  cNameID                     mID;
  bool                        mEquipSlots[EQUIP_UNEQUIPPED];
  tGameID                     mSpellID;
  int                         mSpellChance;
  tGameID                     mAttachFXID;
  DeliveryType                mDeliveryType;
  SlotType                    mSlotType;
  int                         mSlotUsageCost;
};

class cItem : public SyPropObject
{
public:
  cItem();
  ~cItem();

  /* Property Class Support */
  static int           InitPropClass();
  static SyPropObject* Creator();

  void Init(cDatabaseSys *db);
  void SetMaster(const cStatsItemMaster *master);
  const cStatsItemMaster *GetMaster(){return mpMaster;};
  const char *GetMasterName(){return mMasterName.AsChar();};

  int  GetQuantity(){return mQuantity;};
  void SetQuantity(int quantity); 

  bool Merge(cItem *other);

  bool CanEquip(eEquipSlot slot); // returns true if item is of the correct type
  bool Unequip(cGameObject* pOwner, eEquipSlot slot); // if we're in the specified slot, unequip 
  void Unequip(cGameObject* pOwner);  // unequip no matter what
  bool Equip(cGameObject* pOwner, eEquipSlot slot); // note: up to client (inventory system) to make sure we don't have two equipped helms, etc
  eEquipSlot GetEquipSlot(){return mEquipSlot;};

  tGameID GetMasterID(){return mpMaster->mID.GetID();};

  tGameID GetBaseEnhancement(int index) const;
  tGameID GetEnhancementInSlot(cStatsEnhancementMaster::SlotType slot) const;
  bool    SetEnhancementInSlot(cStatsEnhancementMaster::SlotType slot, tGameID id);

  tGameID GetAttachFX(cGameObject* pOwner) const;
  void GetAttachModelFilename(cGameObject* pOwner, SyString* pName, SyString* pLeftName = NULL) const;
  void GetEmitterModelFilename(cGameObject* pOwner, SyString* pName, SyString* pLeftName = NULL) const;

  static const SyPropID PropId_MasterName   = 0x0000;
  static const SyPropID PropId_Quantity     = 0x0001;
  static const SyPropID PropId_EquipSlot    = 0x0002;


  bool  GetPropertyString(cGameObject *pObject,SyString &ans) const;
  void   T4_SetContext_Name(cGameObject *pObject,char8 slot);
  void   T4_SetContext_Description(cGameObject *pObject,char8 slot);

protected:
//  void  CalcEffectiveEnhancements(cDatabaseSys *db); 
//  void  MorphEnhancement(cStatsEnhancementMaster *master);

  const cStatsItemMaster    * mpMaster;
  SyString                    mMasterName;
  int                         mQuantity;
  eEquipSlot                  mEquipSlot;  
  tGameID                     mEnhancementSlots[cStatsEnhancementMaster::ENH_SLOT_NUM_TYPES]; // user-added enhancements for wpns only.
  bool                        mNoDrop;
};


class cStatsMerchantSet
{
public:
  cStatsMerchantSet() {}

  cNameID mID;
  SyVector<uint32> mItems;
};

class cStatsEnhancementComboModel
{
public:
  cStatsEnhancementComboModel();

  static const int NUM_MODEL_IDS = 4;
  tGameID mSlots[cStatsEnhancementMaster::ENH_SLOT_NUM_TYPES];
  tGameID mModelDataIDs[NUM_MODEL_IDS];
};

//------------------------------------------- Function Declarations
void RegPropClasses_Item();
//--------------------------------------------------------- Globals
//------------------------------------------------ Inline Functions

#endif
