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

  Module: TiEquipWindow

  Author: Carlo Ordonez

  Description:

    Equip window (displays equippable items)

  Copyright 2005 Sony Online Entertainment.  All rights reserved.

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

#include "TiEquipWindow.h"
#include "TiUIControl.h"
#include "TiCharacterData.h"
#include "InputConsole.h"
#include "TiUI.h"
#include "TiUILayout.h"
#include "TiFont.h"
#include "TitanUI.h"
#include "TitanI.h"
#include "T4utf.h"
#include "Titan.h"
#include "TitanInputHandler.h"
#include "SyCSprite.h"
#include "SyScene.h"
#include "graphic.h"


const EEquipSlot c_arEquipmentSlots[EW_MaxEquipSlots] = 
{
  kSlotMelee,
  kSlotHead,
  kSlotChest,
  kSlotShoulders,
  kSlotLegs,
  kSlotFeet,
};
const char8 *c_pszDefaultIcons[EW_MaxEquipSlots] = {
  "inventory_icon_melee_00.tga",
  "inventory_icon_helm_00.tga",
  "inventory_icon_armor_00.tga",
  "inventory_icon_shoulders_00.tga",
  "inventory_icon_pants_00.tga",
  "inventory_icon_boots_00.tga",
};

const TiRect c_rectFirstEquipmentSlot(TiPoint(25, 14), TiSize(48, 48));
const TiRect c_rectFirstSelectedEquipmentSlot(TiPoint(17, 6), TiSize(64, 64));
const TiRect c_rectEquipmentFrame(TiPoint(92, 4), TiSize(377, 615));
const TiRect c_rectTitlebar(TiPoint(92, 12), TiSize(377, 30));
const TiRect c_rectEquipmentName(TiPoint(102, 42), TiSize(357, 27));
const TiRect c_rectEquipmentDescr(TiPoint(102, 69), TiSize(357, 180));
const TiRect c_rectEquipmentList(TiPoint(110, 258), TiSize(340, 334));
const int32 c_nEquipmentSlotSpacing = 53;
const int32 c_nVisItemsInList = 5;
const int32 c_nListItemHeight = 56;

//***********************************************************************
// Constructor/Destructor
//***********************************************************************

TiEquipWindow::TiEquipWindow( TiWindow* pParent, TiCharacterData* pData, int32 PlayerId )
: TiCharacterPage( pParent, pData, PlayerId, kEquipment )
{
  m_cfd.SetScrollbar(true);

  m_iSlot = 0;

  Init();
}

TiEquipWindow::~TiEquipWindow()
{
}

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

int32 TiEquipWindow::Init()
{
  m_iSlot = 0;
  m_iItem = 0;
  m_bEquipMode = false;

  InitSlotIcons();

  Debug_AddItems();
  UpdateEquipItemList();

  return( 0 );
}

//***********************************************************************
// UpdateEquipItemList
//***********************************************************************

void TiEquipWindow::UpdateEquipItemList()
{
  if(m_iPlayer < m_pData->GetPlayerCount())
  {
    const std::vector< TiCharacterItemInfo >& arItems = m_pData->GetEquippableItems(m_iPlayer, c_arEquipmentSlots[m_iSlot]);
    int32 nRange = SY_MAX(0, (int32)(arItems.size() - c_nVisItemsInList));
    m_cfd.SetRange(nRange);
    m_cfd.SetPos(0);
  }
}

//***********************************************************************
// InitSlotIcons
//***********************************************************************

void TiEquipWindow::InitSlotIcons()
{
  for(int iSlot = 0; iSlot < EW_MaxEquipSlots; iSlot++)
  {
    if(m_iPlayer < m_pData->GetPlayerCount() && m_pData->GetCurrentItemHandle(m_iPlayer, c_arEquipmentSlots[iSlot]) >= 0)
    {
      SyResourceID id = m_pData->GetCurrentItemIcon(m_iPlayer, c_arEquipmentSlots[iSlot]);

      if(id == 0)
      {
        m_sprEquipIcons[iSlot].SetInfo(c_pszDefaultIcons[iSlot]);
      }
      else
      {
        m_sprEquipIcons[iSlot].SetInfo(id);
      }
    }
    else
    {
      m_sprEquipIcons[iSlot].SetInfo("");
    }
  }
}


int32 TiEquipWindow::GetIndexForSlotEnum(int iSlotEnum) const
{
  for(int i = 0; i < EW_MaxEquipSlots; i++)
  {
    if(c_arEquipmentSlots[i] == iSlotEnum)
      return i;
  }
  return -1;
}

const TiCharacterItemInfo *TiEquipWindow::GetEquippedItem(int32 iSlot) const
{
  const std::vector< TiCharacterItemInfo >& arItems = m_pData->GetEquippableItems(m_iPlayer, c_arEquipmentSlots[iSlot]);

  for(int32 i = 0; i < (int32)arItems.size(); i++)
  {
    if(arItems[i].m_eSlot == c_arEquipmentSlots[iSlot])
      return &arItems[i];
  }
  return NULL;
}

//***********************************************************************
// DrawSelf
//***********************************************************************
void TiEquipWindow::DrawSelf()
{
  DrawBackground();

  const std::vector< TiCharacterItemInfo >& arItems = m_pData->GetEquippableItems(m_iPlayer, c_arEquipmentSlots[m_iSlot]);
  const TiCharacterItemInfo *pEquippedItem = GetEquippedItem(m_iSlot);
  const TiCharacterItemInfo *pSelectedItem = pEquippedItem;
  if(m_bEquipMode && m_iItem >= 0 && m_iItem < (int32)arItems.size())
  {
    pSelectedItem = &arItems[m_iItem];
  }

  // draw equipped icons
  TiRect rectIcon = c_rectFirstEquipmentSlot + GetScreenRect().TopLeft();
  for(int iSlot = 0; iSlot < EW_MaxEquipSlots; iSlot++)
  {
    m_sprEquipIcons[iSlot].Stretch(rectIcon);
    if(m_bEquipMode && iSlot != m_iSlot)
    {
      TiUI::Instance()->FillRectangle(rectIcon, TiUI::ColorWithAlpha(c_crBlack, .8f));
    }

    rectIcon += TiPoint(0, c_nEquipmentSlotSpacing);
  }

  // draw selected equipped icon
  if(m_iSlot >= 0)
  {
    rectIcon = c_rectFirstSelectedEquipmentSlot + GetScreenRect().TopLeft();
    rectIcon += TiPoint(0, c_nEquipmentSlotSpacing * m_iSlot);
    
    if(!m_bEquipMode)
    {
      sm_bdSelection.Draw(rectIcon);
    }
    m_sprEquipIcons[m_iSlot].Pulse(rectIcon, 0.2f, 8.f);
  }

  // draw frame
  TiRect rectFrame = c_rectEquipmentFrame + GetScreenRect().TopLeft();
  sm_bdFrame.DrawWithFill(rectFrame, c_crFrameFill);

  TiFont font(TiUI::Instance()->GetFontHandle("Default"));
  SyString str;
  char8 szBuffer[256] = "";
  static SyResourceID idEquipmentTabName = SyHashResourceID("UiEquipmentTabName");

  m_pData->GetTitanInterface()->T4Expand(szBuffer, sizeof(szBuffer), idEquipmentTabName);
  font.Draw(szBuffer, c_rectTitlebar + GetScreenRect().TopLeft(), c_crWhite, TI_TF_SHADOW | TI_TF_HALIGN_CENTER);

  // Draw Current Item (either equipped or if we are selecting, current selection)
  if(pSelectedItem != NULL)
  {
    static SyResourceID idAttackPowerString = SyHashResourceID("UiAttackPowerFormat");
    static SyResourceID idMagicPowerString = SyHashResourceID("UiMagicPowerFormat");

    TiRect rectText = c_rectEquipmentName + GetScreenRect().TopLeft();
    rectText.top += font.Draw(pSelectedItem->m_strName, rectText, c_crWhite, TI_TF_HALIGN_CENTER | TI_TF_SHADOW);  

    m_pData->GetTitanInterface()->T4SetContext('0', 0, T4::UNKNOWN_SEX, pSelectedItem->m_nAttackPower);
    m_pData->GetTitanInterface()->T4Expand(szBuffer, sizeof(szBuffer), idAttackPowerString);
    int32 nHeight = font.Draw(szBuffer, rectText, c_crWhite, TI_TF_SHADOW);
    int32 nLength = font.GetTextWidth(szBuffer);

    TiRect rectCompareText = rectText;
    if(pSelectedItem != pEquippedItem && pEquippedItem != NULL && pSelectedItem->m_nAttackPower != pEquippedItem->m_nAttackPower)
    {
      SyColor32F crText = c_crGreen;
      int32 nDiff = pSelectedItem->m_nAttackPower - pEquippedItem->m_nAttackPower;
      if(nDiff < 0)
        crText = c_crRed;
      sprintf(szBuffer, "(%d)", nDiff);
      font.Draw(szBuffer, rectCompareText, crText, TI_TF_SHADOW);
    }

    rectText.top += nHeight;
    m_pData->GetTitanInterface()->T4SetContext('0', 0, T4::UNKNOWN_SEX, pSelectedItem->m_nSpellPower);
    m_pData->GetTitanInterface()->T4Expand(szBuffer, sizeof(szBuffer), idMagicPowerString);
    nHeight = font.Draw(szBuffer, rectText, c_crWhite, TI_TF_SHADOW);
    nLength = font.GetTextWidth(szBuffer);

    rectCompareText = rectText;
    if(pSelectedItem != pEquippedItem && pEquippedItem != NULL && pSelectedItem->m_nSpellPower != pEquippedItem->m_nSpellPower)
    {
      SyColor32F crText = c_crGreen;
      int32 nDiff = pSelectedItem->m_nSpellPower - pEquippedItem->m_nSpellPower;
      if(nDiff < 0)
        crText = c_crRed;
      sprintf(szBuffer, "(%d)", nDiff);
      font.Draw(szBuffer, rectCompareText, crText, TI_TF_SHADOW);
    }
    rectText.top += nHeight;

    str = pSelectedItem->m_strDescription;
    font.Draw(str, rectText, c_crWhite, TI_TF_HALIGN_CENTER);
  }

  TiRect rectSelect = c_rectEquipmentList;
  rectSelect += GetScreenRect().TopLeft();
  m_cfd.Draw(rectSelect);

  TiRect rectList = m_cfd.GetContentRect(rectSelect);
  TiRect rectItem = rectList;
  rectItem.bottom = rectItem.top + c_nListItemHeight;

  TiSprite sprItem;

  // draw equippable items
  for(int32 i = m_cfd.GetPos(); i < (int32)arItems.size() && i < m_cfd.GetPos() + c_nVisItemsInList; i++)
  {
    TiCharacterItemInfo item = arItems[i];

    SyColor32F crText = c_crWhite;
    if(i == m_iItem && m_bEquipMode)
    {
      sm_bdSelection.Draw(rectItem);
    }

    if(item.m_eSlot != kSlotUnequipped)
    {
      crText = c_crItemEquipped;
    }


    if(item.m_idIcon == 0)
    {
      sprItem.SetInfo(c_pszDefaultIcons[m_iSlot]);
    }
    else
    {
      sprItem.SetInfo(item.m_idIcon);
    }
    TiRect rectIcon(rectItem.TopLeft() + TiPoint(2, 2), TiSize(48, 48));
    sprItem.Stretch(rectIcon);

    TiRect rectText = rectItem;
    rectText.left = rectIcon.right + 2;

    font.Draw(item.m_strName, rectText, crText, TI_TF_VCENTER | TI_TF_SHADOW);

    rectItem += TiPoint(0, c_nListItemHeight);
  }
}



//***********************************************************************
// ProcessKeyDown
//***********************************************************************

bool TiEquipWindow::ProcessKeyDown( int32 KeyCode )
{
  switch( KeyCode )
  {
  case SyInputEvent::KEYCODE_UP:
    Prev();
    return( true );

  case SyInputEvent::KEYCODE_DOWN:
    Next();
    return( true );

  case SyInputEvent::KEYCODE_ENTER:
    Select();
    return( true );

  case SyInputEvent::KEYCODE_DELETE:
    Drop();
    return( true );

  case SyInputEvent::KEYCODE_ESCAPE:
    return( Back() );
  }

  return( false );
}

//***********************************************************************
// ProcessButtonDown
//***********************************************************************

bool TiEquipWindow::ProcessButtonDown( int32 DeviceId, int32 ButtonId )
{
  if( DeviceId != m_iPlayer )
  {
    return( false ); 
  }

  switch( TiWindow::GetButton( ButtonId ) )
  {
  case TiButtonMap::kUp:
    Prev();
  	return( true );

  case TiButtonMap::kDown:
    Next();
    return( true );

  case TiButtonMap::kRight:
    if(!m_bEquipMode)
    {
      Select();
      return true;
    }
    return false;
  case TiButtonMap::kLeft:
    if(m_bEquipMode)
    {
      Back();
      return true;
    }
    return false;

  case TiButtonMap::kX:
    Select();
    return( true );

  case TiButtonMap::kTriangle:
    Drop();
    return( true );

  case TiButtonMap::kCircle:
    return( Back() );

  default:
    return( false );
  }
}

//***********************************************************************
// ProcessReloadLayout
//***********************************************************************

void TiEquipWindow::ProcessReloadLayout()
{
}

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

void TiEquipWindow::ItemActivate()
{
  TiUI::Instance()->PlaySound(TiUI::kSoundEquip);
  const std::vector< TiCharacterItemInfo >& items = m_pData->GetEquippableItems(m_iPlayer, c_arEquipmentSlots[m_iSlot]);
  if ( !items.empty() )
  {
    int32 itemHandle = items[m_iItem].m_iHandle;
    m_pData->ItemActivate( m_iPlayer, itemHandle );
    UpdatePaperDoll (itemHandle);
    InitSlotIcons();
  }
}

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

void TiEquipWindow::ItemDrop()
{
  TiUI::Instance()->PlaySound(TiUI::kSoundLootDrop);
  const std::vector< TiCharacterItemInfo >& items = m_pData->GetEquippableItems(m_iPlayer, c_arEquipmentSlots[m_iSlot]);
  if ( !items.empty() )
  {
    int32 itemHandle = items[m_iItem].m_iHandle;
    m_pData->ItemDrop( m_iPlayer, itemHandle );
  }
}

//***********************************************************************
// Next
//***********************************************************************

void TiEquipWindow::Next()
{
  const std::vector< TiCharacterItemInfo >& arItems = m_pData->GetEquippableItems(m_iPlayer, c_arEquipmentSlots[m_iSlot]);
  if( m_bEquipMode )
  {
    TiUI::Instance()->PlaySound(TiUI::kSoundTick);
    m_iItem = SY_MIN(m_iItem + 1, (int32)arItems.size() - 1);
    if(m_iItem >= m_cfd.GetPos() + c_nVisItemsInList)
    {
      m_cfd.SetPos(m_cfd.GetPos() + 1);
    }
  }
  else
  {
    if( m_iSlot+1 < EW_MaxEquipSlots )
    {
      TiUI::Instance()->PlaySound(TiUI::kSoundTick);
      m_iSlot++;
      UpdateEquipItemList();
    }
  }
}

//***********************************************************************
// Prev
//***********************************************************************

void TiEquipWindow::Prev()
{
  const std::vector< TiCharacterItemInfo >& arItems = m_pData->GetEquippableItems(m_iPlayer, c_arEquipmentSlots[m_iSlot]);
  if( m_bEquipMode )
  {
    if(arItems.size() == 0)
      return;

    TiUI::Instance()->PlaySound(TiUI::kSoundTick);
    m_iItem = SY_MAX(m_iItem - 1, 0);
    if(m_iItem < m_cfd.GetPos())
      m_cfd.SetPos(m_iItem);
  }
  else
  {
    if( m_iSlot > 0 )
    {
      TiUI::Instance()->PlaySound(TiUI::kSoundTick);
      m_iSlot--;
      UpdateEquipItemList();
    }
  }
}

//***********************************************************************
// Select
//***********************************************************************

void TiEquipWindow::Select()
{
  if( m_bEquipMode )
  {
    ItemActivate();
  }
  else
  {
    m_bEquipMode = true;
    m_iItem = 0;
    UpdateEquipItemList();
  }
}

//***********************************************************************
// Drop
//***********************************************************************

void TiEquipWindow::Drop()
{
  if( m_bEquipMode )
  {
    ItemDrop();
  }
}

//***********************************************************************
// Back
//***********************************************************************

bool TiEquipWindow::Back()
{
  if( m_bEquipMode )
  {
    TiUI::Instance()->PlaySound(TiUI::kSoundBack);
    m_bEquipMode = false;
    return( true );
  }
  return( false );
}


void TiEquipWindow::Debug_AddItems()
{
  static bool bWasHere = false;

  if(bWasHere || m_pData->GetTitanInterface() == NULL)
    return;

  /*
  m_pData->GetTitanInterface()->Debug_AddItemToPlayerInventory(m_iPlayer, "Barbed Steel Boots");
  m_pData->GetTitanInterface()->Debug_AddItemToPlayerInventory(m_iPlayer, "Leather Boots of Auras");
  m_pData->GetTitanInterface()->Debug_AddItemToPlayerInventory(m_iPlayer, "KnucklesSteel");
  m_pData->GetTitanInterface()->Debug_AddItemToPlayerInventory(m_iPlayer, "KnucklesIron");
  m_pData->GetTitanInterface()->Debug_AddItemToPlayerInventory(m_iPlayer, "KnucklesTitanium");
  m_pData->GetTitanInterface()->Debug_AddItemToPlayerInventory(m_iPlayer, "Hammer of Counter");
  m_pData->GetTitanInterface()->Debug_AddItemToPlayerInventory(m_iPlayer, "Hammer of CriticalHit");
  m_pData->GetTitanInterface()->Debug_AddItemToPlayerInventory(m_iPlayer, "Hammer of CrushingBlow");
  m_pData->GetTitanInterface()->Debug_AddItemToPlayerInventory(m_iPlayer, "Hammer of DemonBane");
  */

  m_pData->Update();

  bWasHere = true;

}

/**********************************************************
 * SetPaperDollSpriteHandle
 **********************************************************/
void TiEquipWindow::SetPaperDollSpriteHandle (int32 paperDoll)
{
  mPaperDollSpriteHandle = paperDoll;
}

/**********************************************************
 * UpdatePaperDoll
 **********************************************************/
void TiEquipWindow::UpdatePaperDoll(int32 item)
{
  int itemSpriteHandle;
  /*
   * Get the usual suspects
   */
  Titan* pTitan =   (Titan*) m_pData->GetTitanInterface();
  TitanUI* pTitanUI = (TitanUI*) pTitan->GetTitanUI();
  SyScene* pScene =   pTitanUI->GetScene();

  /*
   * paperDollSprite is the sprite of the paper doll sprite.
   */
  SyCSprite * paperDollSprite = (SyCSprite*) (pScene->Sprite (mPaperDollSpriteHandle));

  SyRefID slotID = 1;
  int equipSlot;
  int itemEquipped = pTitan->InventoryIsEquipped (m_iPlayer, item);
  if (itemEquipped == 1)
  {
    pTitan->InventoryGetItemSpriteAndSlot (m_iPlayer, item, itemSpriteHandle, equipSlot);
    if (equipSlot != -1)
    {
      slotID = GetAttachSlotFromEquip (equipSlot);
      if (itemSpriteHandle != -1)
      {
        // if we attach a sprite to a slot with another sprite, the old one 
        // automatically is detached and released
        paperDollSprite->AttachToSlot (itemSpriteHandle, slotID, *pScene);
      }
    }
  }
  else
  {
    pTitan->InventoryGetItemSpriteAndSlot (m_iPlayer, item, itemSpriteHandle, equipSlot);
    if (equipSlot != -1)
    {
      slotID = GetAttachSlotFromEquip (equipSlot);
      paperDollSprite->DetachFromSlot (slotID, *pScene);
    }
  }
}
