/******************************************************************
  
  Module:  item.cpp
  
  Author: Sean Craig
  
  Copyright 2005 Sony Online Entertainment.  All rights reserved.
  
*******************************************************************/

//-------------------------------------------------------- Includes
#include "item.h"
#include "gameobj.h"
#include "stats.h"
#include "database.h"
//---------------------------------------------- Class Declarations
//----------------------------------------- Functions Declarations
//------------------------------------ Member Functions Definitions

//------------------------------------- cStatsItemMaster 
cStatsItemMaster::cStatsItemMaster():
mType(IT_TRINKET),
mClass(IC_ANY),
mWorldModel(NULL),
mIcon(NULL),
mAttachModel(NULL),
mProjectile(ID_NONE),
mNameString(NULL),
mDescriptionString(NULL)
{
  for (int ii=0;ii<MAX_NUM_ENHANCEMENTS;++ii)
  {
    mEnhancements[ii] = ID_NONE;
  }
}

cStatsItemMaster::~cStatsItemMaster()
{
  delete mWorldModel;
  delete mIcon;
  delete mAttachModel;
  delete mNameString;
  delete mDescriptionString;
}

//------------------------------------- cItem

cItem::cItem() :
   mpMaster(NULL),
  mQuantity(1),
  mEquipSlot(EQUIP_UNEQUIPPED),
  mNoDrop(false)

{
  InitPropObject( ITEM_CLASSID );
}

cItem::~cItem()
{

}


int           
cItem::InitPropClass()
{
  SyPropClassID ClassID = ITEM_CLASSID;

/* Add the class */

  AddClass( ClassID, 
            "cItem", 
            Creator, 
            ClassID, 
            0 ); 

  AddStringProperty(ClassID,PropId_MasterName,SyMemberOffset(cItem,mMasterName),"mMasterName");

  AddInt32Property(ClassID,PropId_Quantity,SyMemberOffset(cItem,mQuantity),"mQuantity");

  SyPropEnum *propEnum;
  AddEnumProperty(ClassID,PropId_EquipSlot,SyMemberOffset(cItem,mEquipSlot),"mEquipSlot",&propEnum);
  propEnum->Add(EQUIP_MELEE,"MELEE");
  propEnum->Add(EQUIP_RANGED,"RANGED");
  propEnum->Add(EQUIP_HEAD,"HEAD");
  propEnum->Add(EQUIP_BODY,"BODY");
  propEnum->Add(EQUIP_FEET,"FEET");
  propEnum->Add(EQUIP_ACCESSORY,"ACCESSORY");
  propEnum->Add(EQUIP_UNEQUIPPED,"UNEQUIPPED");

  return 0;
}

SyPropObject* 
cItem::Creator()
{
  SyPropObject *pObject;

  pObject = SyNew cItem();
  if(pObject == NULL)
  {                            
    SyAssert(0);
    return(NULL);
  }

  return(pObject);
}

void
cItem::Init(cDatabaseSys *db)
{
  if (mMasterName.AsChar()[0] == '\0')
  {
    SyAssert(0);
    return;
  }

  tGameID mMasterID = SyHashResourceID(mMasterName.AsChar());
  SetMaster(db->GetItemMaster(mMasterID));
}

void 
cItem::SetMaster(const cStatsItemMaster *master)
{
  if (master == NULL)
  {
    SyAssertf(0,"Bad Item Master");
    return;
  }
  mpMaster = master;
  mMasterName.Init(master->mID.GetName());
}


void 
cItem::SetQuantity(int quantity)
{
  SyAssertf(quantity > 0,"Bad quantity");
  mQuantity = quantity;
}

bool 
cItem::Merge(cItem *other)
{
  if (other->GetMaster() == GetMaster())
  {
    mQuantity += other->GetQuantity();
    return true;
  }
  return false;
}

bool 
cItem::Unequip(eEquipSlot slot) // if we're in the equip slot, equip it
{
  if (mEquipSlot == slot)
  {
    mEquipSlot = EQUIP_UNEQUIPPED;
    return true;
  }
  return false;
}

bool
cItem::CanEquip(eEquipSlot slot)
{
  SyAssertf(mpMaster!=NULL,"Master Not Set");

  if (slot == EQUIP_UNEQUIPPED)
  {
    return true;
  }
  if ((int)mpMaster->mType == (int)slot)
  {
    return true;
  }
  return false;
}

bool 
cItem::Equip(eEquipSlot slot)
{
  // up to inventory to make sure there aren't two items in the same slot
  
  if (!CanEquip(slot))
  {
    return false;
  }
  mEquipSlot = slot;
  return true;
}

tGameID 
cItem::GetEnhancement(int index) const
{
  if (index <0 || index >= cStatsItemMaster::MAX_NUM_ENHANCEMENTS)
  {
    return ID_NONE;
  }

  return mEffectiveEnhancements[index];

}

bool    
cItem::SetEnhancement(int index,tGameID id)
{
  // todo: check to see if enhancement is valid
  if (index <0 || index >= cStatsItemMaster::MAX_NUM_ENHANCEMENTS)
  {
    return false;
  }
  if (mpMaster->mEnhancements[index] != ID_NONE)
  {
    // cannot change or override enhancements set in the master (designer-placed enhancements)
    return false;
  }

 mEnhancements[index] = id;
 CalcEffectiveEnhancements();
 return true;
}


void    
cItem::CalcEffectiveEnhancements()
{
  for (int index=0;index<cStatsItemMaster::MAX_NUM_ENHANCEMENTS;++index)
  {
    if (mpMaster->mEnhancements[index] != ID_NONE)
    {
      mEffectiveEnhancements[index] = mpMaster->mEnhancements[index];
    }
    else
    {
      mEffectiveEnhancements[index] = mEnhancements[index];
    }
  }

  // todo: Look up morph enhancements in db.
}

//----------------------------------------- Functions Declarations
void 
RegPropClasses_Item()
{
  cItem::InitPropClass();
}
// EOF
