/********************************************************************

  Module: TiCharacterData

  Author: Carlo Ordonez

  Description:

    Updates character window with data from the game

  Copyright 2005 Sony Online Entertainment.  All rights reserved.

*********************************************************************/

#include "TiCharacterData.h"
#include "TitanI.h"
#include "SyDebug.h"
#include "SyMath.h"

//***********************************************************************
// Constructor
//***********************************************************************

TiCharacterData::TiCharacterData()
{
  m_pTitan = NULL;
  m_nPlayerCount = 1;
  m_nHealthPointsPerBonusPoint = 5;   // this will also be read from XML (but this sets it just in case)
  m_nManaPointsPerBonusPoint = 5;     // this will also be read from XML (but this sets it just in case)
}

//***********************************************************************
// Init
//***********************************************************************

int32 TiCharacterData::Init( TitanI* pTitan )
{
  m_pTitan = pTitan;
  return( 0 );
}

//***********************************************************************
// Update
//***********************************************************************

void TiCharacterData::Update()
{
  for( int32 i = 0; i < m_nPlayerCount; i++ )
  {
    const int32 BUF_LEN = 256;
    char8 buffer[BUF_LEN];

    // update equipment & inventory
    m_arPlayers[i].m_arMelee.clear();
    m_arPlayers[i].m_arRanged.clear();
    m_arPlayers[i].m_arHead.clear();
    m_arPlayers[i].m_arChest.clear();
    m_arPlayers[i].m_arShoulders.clear();
    m_arPlayers[i].m_arLegs.clear();
    m_arPlayers[i].m_arFeet.clear();
    m_arPlayers[i].m_arBelt.clear();
    m_arPlayers[i].m_arNecklace.clear();
    m_arPlayers[i].m_arRing.clear();
    m_arPlayers[i].m_arInventory.clear();
    m_arPlayers[i].m_arEnhancements.clear();

    m_arPlayers[i].m_uGold = m_pTitan->GetPlayerEssence(i);

    for( int32 j = 0; j < m_pTitan->InventoryGetItemCount(i); j++ )
    {
      TiCharacterItemInfo info;
      info.m_iHandle      = j;
      m_pTitan->InventoryGetItemInfo(i, j, &info);

      // add to inventory
      m_arPlayers[i].m_arInventory.push_back( info );

      SyDebug("Found %s in inventory\n", info.m_strName.AsChar());

      // add to equippable item types
      switch( info.m_eType )
      {
      case kTypeMelee:
        m_arPlayers[i].m_arMelee.push_back( info );
        break;
        
      case kTypeRanged:
        m_arPlayers[i].m_arRanged.push_back( info );
        break;
      case kTypeHead:
        m_arPlayers[i].m_arHead.push_back( info );
        break;
      case kTypeChest:
        m_arPlayers[i].m_arChest.push_back( info );
        break;
      case kTypeShoulders:
        m_arPlayers[i].m_arShoulders.push_back( info );
        break;
      case kTypeLegs:
        m_arPlayers[i].m_arLegs.push_back( info );
        break;
      case kTypeFeet:
        m_arPlayers[i].m_arFeet.push_back( info );
        break;
      case kTypeBelt:
        m_arPlayers[i].m_arBelt.push_back( info );
        break;
      case kTypeNecklace:
        m_arPlayers[i].m_arNecklace.push_back( info );
        break;
      case kTypeRing:
        m_arPlayers[i].m_arRing.push_back( info );
        break;
      case kTypeEnhancement:
        m_arPlayers[i].m_arEnhancements.push_back( j );
        break;
      }
    }
    // update slot enhancements
    for(int32 iSlot = 0; iSlot < kEnhancementSlotCount; iSlot++)
    {
      m_arPlayers[i].m_arSlotEnhancements[iSlot] = m_pTitan->InventoryGetWeaponEnhancementItem(i, iSlot);
    }

    // update spells & abilities
    m_arPlayers[i].m_arCurrentAbilities.clear();
    m_arPlayers[i].m_arAvailableAbilities.clear();
    m_arPlayers[i].m_nAbilityPoints = m_pTitan->AbilityGetNumPoints( i );

    for( int32 j = 0; j < m_pTitan->AbilityAvailableGetCount(i); j++ )
    {
      if( m_pTitan->AbilityAvailableIsBuyable( i, j ) )
      {
        AbilityInfo info;
        info.m_iHandle      = j;
        m_pTitan->AbilityAvailableGetName( i, j, info.m_strName );
        //info.m_strDescription = m_pTitan->AbilityAvailableGetDescription( i, j );
        info.m_nCost        = m_pTitan->AbilityAvailableGetCost( i ,j );
        info.m_bBuyable     = true;

        m_arPlayers[i].m_arAvailableAbilities.push_back( info );
      }
    }
    for( int32 j = 0; j < m_pTitan->AbilityCurrentGetCount(i); j++ )
    {
      if( m_pTitan->AbilityCurrentIsActive( i, j ) )
      {
        AbilityInfo info;
        info.m_iHandle      = j;
        m_pTitan->AbilityCurrentGetName( i, j, info.m_strName );
        //info.m_strDescription = m_pTitan->AbilityCurrentGetDescription( i, j );
        info.m_bActive      = true;

        m_arPlayers[i].m_arCurrentAbilities.push_back( info );
      }
    }

    // update stats
    m_pTitan->GetPlayerName( i, buffer, BUF_LEN );

    // TAKEOUT
    const char8 *c_pszDefNames[] = {
      "Golan",
      "Golan",
      "Aristotle",
      "Oliver",
    };
    if(strlen(buffer) == 0)
      strcpy(buffer, c_pszDefNames[i]);


    m_arPlayers[i].m_strName.Init( buffer );
    m_arPlayers[i].m_nLevel = m_pTitan->GetPlayerLevel(i);
    
    // TAKEOUT
    const char8 *c_pszDefClass = "Brute";
    strcpy(buffer, c_pszDefClass);
    // m_pTitan->GetPlayerClass(i, buffer, BUF_LEN );
    m_arPlayers[i].m_strClass.Init( buffer );

    // TAKEOUT
    const char8 *c_pszDefAbilityTree = "brute.pat";
    strcpy(buffer, c_pszDefAbilityTree);
    // m_pTitan->GetPlayerClassAbilityTreeFile(i, buffer, BUF_LEN );
    m_arPlayers[i].m_strAbilityTreeFile.Init( buffer );


    sprintf( buffer, "%d", m_pTitan->GetPlayerCurExp(i) );
    m_arPlayers[i].m_strExperience.Init( buffer );
    sprintf( buffer, "%d", m_pTitan->GetPlayerNextLevelExp(i) );
    m_arPlayers[i].m_strNextLevel.Init( buffer );
    sprintf( buffer, "%d/%d", m_pTitan->GetPlayerHealth(i), m_pTitan->GetPlayerHealthMax(i) );
    m_arPlayers[i].m_strHealth.Init( buffer );
    sprintf( buffer, "%d/%d", m_pTitan->GetPlayerMana(i), m_pTitan->GetPlayerManaMax(i) );
    m_arPlayers[i].m_strMana.Init( buffer );

    
    m_arPlayers[i].m_nMaxHealth = m_pTitan->GetPlayerHealthMax(i);
    m_arPlayers[i].m_nMaxMana = m_pTitan->GetPlayerManaMax(i);
    m_arPlayers[i].m_nAttackPower = m_pTitan->GetPlayerAttackPower(i);
    m_arPlayers[i].m_nMagicPower = m_pTitan->GetPlayerMagicPower(i);
    m_arPlayers[i].m_nMeleeDefense = m_pTitan->GetPlayerMeleeDefense(i);
    m_arPlayers[i].m_nSpellDefense = m_pTitan->GetPlayerSpellDefense(i);
    m_arPlayers[i].m_nBonusPoints = m_pTitan->GetPlayerBonusPoints(i);
    
  }
}

//***********************************************************************
// SetPlayerCount
//***********************************************************************

void TiCharacterData::SetPlayerCount( int32 Count )
{
  m_nPlayerCount = SY_CLAMP( Count, 1, PLAYER_MAX );
}

//***********************************************************************
// GetName
//***********************************************************************

const SyString& TiCharacterData::GetName( int32 iPlayer ) const
{
  SyAssert( iPlayer >= 0 && iPlayer < m_nPlayerCount );
  return( m_arPlayers[iPlayer].m_strName );
}

//***********************************************************************
// GetClass
//***********************************************************************

const SyString& TiCharacterData::GetClassString( int32 iPlayer ) const
{
  SyAssert( iPlayer >= 0 && iPlayer < m_nPlayerCount );
  return( m_arPlayers[iPlayer].m_strClass );
}

const SyString& TiCharacterData::GetClassAbilityTreeFile( int32 iPlayer ) const
{
  SyAssert( iPlayer >= 0 && iPlayer < m_nPlayerCount );
  
  return( m_arPlayers[iPlayer].m_strAbilityTreeFile );
}

int32 TiCharacterData::GetLevel( int32 iPlayer ) const
{
  SyAssert( iPlayer >= 0 && iPlayer < m_nPlayerCount );
  return( m_arPlayers[iPlayer].m_nLevel );
}
//***********************************************************************
// GetExperience
//***********************************************************************

const SyString& TiCharacterData::GetExperience( int32 iPlayer ) const
{
  SyAssert( iPlayer >= 0 && iPlayer < m_nPlayerCount );
  return( m_arPlayers[iPlayer].m_strExperience );
}

//***********************************************************************
// GetNextLevel
//***********************************************************************

const SyString& TiCharacterData::GetNextLevel( int32 iPlayer ) const
{
  SyAssert( iPlayer >= 0 && iPlayer < m_nPlayerCount );
  return( m_arPlayers[iPlayer].m_strNextLevel );
}

//***********************************************************************
// GetHealth
//***********************************************************************

const SyString& TiCharacterData::GetHealth( int32 iPlayer ) const
{
  SyAssert( iPlayer >= 0 && iPlayer < m_nPlayerCount );
  return( m_arPlayers[iPlayer].m_strHealth );
}

//***********************************************************************
// GetMana
//***********************************************************************

const SyString& TiCharacterData::GetMana( int32 iPlayer ) const
{
  SyAssert( iPlayer >= 0 && iPlayer < m_nPlayerCount );
  return( m_arPlayers[iPlayer].m_strMana );
}

//***********************************************************************
// GetItemCount
//***********************************************************************

int32 TiCharacterData::GetItemCount( int32 iPlayer ) const
{
  SyAssert( iPlayer >= 0 && iPlayer < m_nPlayerCount );
  return( (int32)m_arPlayers[iPlayer].m_arInventory.size() );
}

//***********************************************************************
// GetCurrentItemIcon
//***********************************************************************

SyResourceID TiCharacterData::GetCurrentItemIcon( int32 iPlayer, EEquipSlot eSlot ) const
{
  SyAssert( iPlayer >= 0 && iPlayer < m_nPlayerCount );
  const std::vector< TiCharacterItemInfo >& inventory = m_arPlayers[iPlayer].m_arInventory;
  for( uint32 i = 0; i < inventory.size(); i++ )
  {
    const TiCharacterItemInfo& item = inventory[i];
    if( item.m_eSlot == eSlot )
    {
      return( item.m_idIcon );
    }
  }

  // not found
  return( 0 );
}

//***********************************************************************
// GetCurrentItemHandle
//***********************************************************************

int32 TiCharacterData::GetCurrentItemHandle( int32 iPlayer, EEquipSlot eSlot ) const
{
  SyAssert( iPlayer >= 0 && iPlayer < m_nPlayerCount );
  const std::vector< TiCharacterItemInfo >& inventory = m_arPlayers[iPlayer].m_arInventory;
  for( uint32 i = 0; i < inventory.size(); i++ )
  {
    const TiCharacterItemInfo& item = inventory[i];
    if( item.m_eSlot == eSlot )
    {
      return i;
    }
  }
  return -1;
}
//***********************************************************************
// GetCurrentItemName
//***********************************************************************

const SyString TiCharacterData::GetCurrentItemName( int32 iPlayer, EEquipSlot eSlot ) const
{
  SyAssert( iPlayer >= 0 && iPlayer < m_nPlayerCount );
  const std::vector< TiCharacterItemInfo >& inventory = m_arPlayers[iPlayer].m_arInventory;
  for( uint32 i = 0; i < inventory.size(); i++ )
  {
    const TiCharacterItemInfo& item = inventory[i];
    if( item.m_eSlot == eSlot )
    {
      return( item.m_strName );
    }
  }

  // not found
  return( SyString("") );
}

//***********************************************************************
// GetCurrentItemName
//***********************************************************************

const SyString TiCharacterData::GetCurrentItemDescr( int32 iPlayer, EEquipSlot eSlot ) const
{
  SyAssert( iPlayer >= 0 && iPlayer < m_nPlayerCount );
  const std::vector< TiCharacterItemInfo >& inventory = m_arPlayers[iPlayer].m_arInventory;
  for( uint32 i = 0; i < inventory.size(); i++ )
  {
    const TiCharacterItemInfo& item = inventory[i];
    if( item.m_eSlot == eSlot )
    {
      return( item.m_strDescription );
    }
  }

  // not found
  return( SyString("") );
}

//***********************************************************************
// GetEquippableItems
//***********************************************************************

const std::vector< TiCharacterItemInfo >& TiCharacterData::GetEquippableItems( int32 iPlayer, EEquipSlot eSlot ) const
{
  SyAssert( iPlayer >= 0 && iPlayer < m_nPlayerCount );

  switch( eSlot )
  {
  case kSlotMelee:
    return( m_arPlayers[iPlayer].m_arMelee );

  case kSlotRanged:
    return( m_arPlayers[iPlayer].m_arRanged );

  case kSlotHead:
    return( m_arPlayers[iPlayer].m_arHead );

  case kSlotChest:
    return( m_arPlayers[iPlayer].m_arChest );

  case kSlotShoulders:
    return( m_arPlayers[iPlayer].m_arShoulders );

  case kSlotLegs:
    return( m_arPlayers[iPlayer].m_arLegs );

  case kSlotFeet:
    return( m_arPlayers[iPlayer].m_arFeet );

  case kSlotBelt:
    return( m_arPlayers[iPlayer].m_arBelt );

  case kSlotNecklace:
    return( m_arPlayers[iPlayer].m_arNecklace );

  case kSlotLRing:
  case kSlotRRing:
    return( m_arPlayers[iPlayer].m_arRing );

  default:
    SyAssert( 0 );
    return( m_arPlayers[iPlayer].m_arMelee );
  }
}

//***********************************************************************
// GetInventory
//***********************************************************************

const std::vector< TiCharacterItemInfo >& TiCharacterData::GetInventory( int32 iPlayer ) const
{
  SyAssert( iPlayer >= 0 && iPlayer < m_nPlayerCount );
  return( m_arPlayers[iPlayer].m_arInventory );
}

const std::vector< int32 >& TiCharacterData::GetEnhancements( int32 iPlayer ) const
{
  SyAssert( iPlayer >= 0 && iPlayer < m_nPlayerCount );
  return( m_arPlayers[iPlayer].m_arEnhancements );
}

//***********************************************************************
// GetAbilityPoints
//***********************************************************************

int32 TiCharacterData::GetAbilityPoints( int32 iPlayer ) const
{
  SyAssert( iPlayer >= 0 && iPlayer < m_nPlayerCount );
  return( m_arPlayers[iPlayer].m_nAbilityPoints );
}

int32 TiCharacterData::GetBonusPoints(int32 iPlayer) const
{
  SyAssert( iPlayer >= 0 && iPlayer < m_nPlayerCount );
  return m_arPlayers[iPlayer].m_nBonusPoints;
}

int32 TiCharacterData::GetMaxHealth(int32 iPlayer) const
{
  SyAssert( iPlayer >= 0 && iPlayer < m_nPlayerCount );
  return m_arPlayers[iPlayer].m_nMaxHealth;
}

int32 TiCharacterData::GetMaxMana(int32 iPlayer) const
{
  SyAssert( iPlayer >= 0 && iPlayer < m_nPlayerCount );
  return m_arPlayers[iPlayer].m_nMaxMana;
}

int32 TiCharacterData::GetAttackPower(int32 iPlayer) const
{
  SyAssert( iPlayer >= 0 && iPlayer < m_nPlayerCount );
  return m_arPlayers[iPlayer].m_nAttackPower;
}

int32 TiCharacterData::GetMagicPower(int32 iPlayer) const
{
  SyAssert( iPlayer >= 0 && iPlayer < m_nPlayerCount );
  return m_arPlayers[iPlayer].m_nMagicPower;
}

int32 TiCharacterData::GetMeleeDefense(int32 iPlayer) const
{
  SyAssert( iPlayer >= 0 && iPlayer < m_nPlayerCount );
  return m_arPlayers[iPlayer].m_nMeleeDefense;
}

int32 TiCharacterData::GetSpellDefense(int32 iPlayer) const
{
  SyAssert( iPlayer >= 0 && iPlayer < m_nPlayerCount );
  return m_arPlayers[iPlayer].m_nSpellDefense;
}

//***********************************************************************
// GetCurrentAbilities
//***********************************************************************

const std::vector< TiCharacterData::AbilityInfo >& TiCharacterData::GetCurrentAbilities( int32 iPlayer ) const
{
  SyAssert( iPlayer >= 0 && iPlayer < m_nPlayerCount );
  return( m_arPlayers[iPlayer].m_arCurrentAbilities );
}

const std::vector< TiCharacterData::AbilityInfo >& TiCharacterData::GetAvailableAbilities( int32 iPlayer ) const
{
  SyAssert( iPlayer >= 0 && iPlayer < m_nPlayerCount );
  return( m_arPlayers[iPlayer].m_arAvailableAbilities );
}

//***********************************************************************
// ItemActivate
//***********************************************************************

void TiCharacterData::ItemActivate( int32 iPlayer, int32 ItemHandle )
{
  if( m_pTitan->InventoryIsEquipped( iPlayer, ItemHandle ) )
  {
    // un-equip item
    m_pTitan->InventoryUnequip( iPlayer, ItemHandle );
  }
  else
  {
    // equip item
    m_pTitan->InventoryEquip( iPlayer, ItemHandle );
  }
  Update();
}

//***********************************************************************
// ItemDrop
//***********************************************************************

void TiCharacterData::ItemDrop( int32 iPlayer, int32 ItemHandle )
{
  m_pTitan->InventoryDrop( iPlayer, ItemHandle );
  Update();
}

//***********************************************************************
// AbilityMap
//***********************************************************************

void TiCharacterData::AbilityMap( int32 iPlayer, int32 AbilityHandle, int32 Button )
{
  m_pTitan->AbilityCurrentMap( iPlayer, AbilityHandle, Button );
  Update();
}

//***********************************************************************
// AbilityBuy
//***********************************************************************

void TiCharacterData::AbilityBuy( int32 iPlayer, int32 AbilityHandle )
{
  m_pTitan->AbilityAvailableBuy( iPlayer, AbilityHandle );
  Update();
}

//***********************************************************************
// GetMappedAbility
//***********************************************************************

const SyString TiCharacterData::GetMappedAbility( int32 iPlayer, int32 Button ) const
{
  int32 abilityHandle = m_pTitan->AbilityMappedGetIndex( iPlayer, Button );
  if( abilityHandle >= 0 )
  {  
    SyString name;
    m_pTitan->AbilityCurrentGetName( iPlayer, abilityHandle, name );
    return( name );
  }
  else
  {
    // no ability mapped
    return( SyString("") );
  }
}

int32 TiCharacterData::GetSlotEnhancement(int32 iPlayer, int32 iSlot) const
{
  SyAssert(iSlot >= 0 && iSlot < kEnhancementSlotCount);
  return m_arPlayers[iPlayer].m_arSlotEnhancements[iSlot];
}

//***********************************************************************
// TiCharacterItemInfo class
//***********************************************************************

TiCharacterItemInfo::TiCharacterItemInfo()
{
  m_iHandle = 0;
  m_strName.Init( "" );
  m_strDescription.Init( "" );
  m_strIcon.Init( "" );
  m_eType = kTypeMelee;
  m_eSlot = kSlotUnequipped;
}

//***********************************************************************
// PlayerInfo class
//***********************************************************************

TiCharacterData::PlayerInfo::PlayerInfo()
{
  m_uGold = 0;
  m_strName.Init( "" );
  m_strClass.Init( "" );
  m_strExperience.Init( "" );
  m_strNextLevel.Init( "" );
  m_strHealth.Init( "" );
  m_strMana.Init( "" );
  m_nMaxHealth = 0;
  m_nMaxMana = 0;
  m_nAttackPower = 0;
  m_nMagicPower = 0;
  m_nMeleeDefense = 0;
  m_nSpellDefense = 0;
}

//***********************************************************************
// AbilityInfo class
//***********************************************************************

TiCharacterData::AbilityInfo::AbilityInfo()
{
  m_iHandle = 0;
  m_strName.Init( "" );
  m_strDescription.Init( "" );
  m_nCost = 0;
  m_bBuyable = false;
  m_bActive = false;
}
