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

  Module: TiSkillsWindow

  Author: Carlo Ordonez

  Description:

    Skills & Abilities Window

  Copyright 2005 Sony Online Entertainment.  All rights reserved.

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

#include "TiSkillsWindow.h"
#include "TiUI.h"
#include "TiCharacterData.h"
#include "InputConsole.h"
#include "TiFont.h"
#include "T4utf.h"

static TiRect c_rectOuterFrame(TiPoint(12, 4), TiSize(457, 618));
static TiRect c_rectInnerFrame(TiPoint(28, 200), TiSize(425, 396));
static TiRect c_rectTitlebar(TiPoint(28, 11), TiSize(425, 27));
static TiRect c_rectMapFrame(TiPoint(80, 218), TiSize(320, 350));
static TiPoint c_ptFirstNode(26, 4);
static TiPoint c_ptTierOffset(0, 3);
static TiPoint c_ptNodeOffset(4, 7);
static TiPoint c_ptButtonOffset(0, 40);
static TiPoint c_ptRankOffset(40, 0);
static TiPoint c_ptSelectionOffset(-9, -5);
static TiSize c_sizeNode(64, 64);
static TiSize c_sizeNodeSpacing(48, 48);
static TiSize c_sizeMiniButton(24, 24);
static int32 c_nAdditionalVSpace = 18;

static const char8 *c_pszDefIconNames[5] = {
  "ui_skills_icon_01.tga",
  "ui_skills_icon_02.tga",
  "ui_skills_icon_03.tga",
  "ui_skills_icon_04.tga",
  "ui_skills_icon_05.tga",
};
const char8 *c_pszButtons[] = {
  "|x", "|s", "|t", "|c", 
};

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

TiSkillsWindow::TiSkillsWindow( TiWindow* pParent, TiCharacterData* pData, int32 PlayerId )
: TiCharacterPage( pParent, pData, PlayerId, kSkills )
{
  m_cfd.SetScrollbar(true);
  m_cfd.SetRange(0);
  m_cfd.SetPos(0);

  m_sprToLeft.SetInfo("ability_tree_to_left.tga");
  m_sprToRight.SetInfo("ability_tree_to_right.tga");
  m_sprFromLeft.SetInfo("ability_tree_from_left.tga");
  m_sprFromRight.SetInfo("ability_tree_from_right.tga");
  m_sprHorzBar.SetInfo("ability_tree_horz_bar.tga");
  m_sprVertBar.SetInfo("ability_tree_vert_bar.tga");
  m_sprNode.SetInfo("ability_tree_node.tga");
  m_sprButtons[kX].SetInfo("hud_controller_cross.tga");
  m_sprButtons[kSquare].SetInfo("hud_controller_square.tga");
  m_sprButtons[kTriangle].SetInfo("hud_controller_triangle.tga");
  m_sprButtons[kCircle].SetInfo("hud_controller_circle.tga");
  m_sprTier.SetInfo("ui_skills_tier.tga");
  m_sprRankCircle.SetInfo("ui_skills_circle.tga");
  m_sprSelectedNode.SetInfo("selection_cursor_circle.tga");
  m_sprDamageNumbers[0].SetInfo("DamageNumber0");
  m_sprDamageNumbers[1].SetInfo("DamageNumber1");
  m_sprDamageNumbers[2].SetInfo("DamageNumber2");
  m_sprDamageNumbers[3].SetInfo("DamageNumber3");
  m_sprDamageNumbers[4].SetInfo("DamageNumber4");
  m_sprDamageNumbers[5].SetInfo("DamageNumber5");
  m_sprDamageNumbers[6].SetInfo("DamageNumber6");
  m_sprDamageNumbers[7].SetInfo("DamageNumber7");
  m_sprDamageNumbers[8].SetInfo("DamageNumber8");
  m_sprDamageNumbers[9].SetInfo("DamageNumber9");
}

TiSkillsWindow::~TiSkillsWindow()
{
}

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

int32 TiSkillsWindow::Init()
{
  if(m_iPlayer >= 0 && m_iPlayer < m_pData->GetPlayerCount())
  {
    m_bMapping = false;
    m_bLevelingUp = (m_pData->GetAbilityPoints(m_iPlayer) > 0);
    m_tree.LoadFile(m_pData->GetClassAbilityTreeFile(m_iPlayer).AsChar());
    DetermineMaxScrollY();
    bool bFirstNodeFound = false;
    for(TiPoint pt(0, 0); pt.y < c_nMaxATRows; pt.y++)
    {
      for(pt.x = 0; pt.x < c_nMaxATCols; pt.x++)
      {
        TiAbilityTreeNode *pNode = m_tree.GetNode(pt);
        if(pNode->IsAbility())
        {
          if(!bFirstNodeFound)
          {
            m_ptCurrent = pt;
            bFirstNodeFound = true;
          }
          m_sprSkills[pt.y * c_nMaxATCols + pt.x].SetInfo(c_pszDefIconNames[pNode->m_uAbilityHash % 5]);
          //m_sprSkills[pt.y * c_nMaxATCols + pt.x].SetInfo(m_pData->GetTitanInterface()->AbilityGetIcon(pNode->m_uAbilityHash));
        }
        else
        {
          m_sprSkills[pt.y * c_nMaxATCols + pt.x].SetInfo("");
        }
      }
    }
  }
  

  return( 0 );
}

//***********************************************************************
// DetermineMaxScrollY
//***********************************************************************
void TiSkillsWindow::DetermineMaxScrollY()
{
  int32 nMaxScrollY = 0;
  int32 nContentHeight = m_cfd.GetContentRect(c_rectInnerFrame).Height();
  TiPoint pt;

  m_nMaxRow = 0;
  for(pt.y = 0; pt.y < c_nMaxATRows; ++pt.y)
  {
    for(pt.x = 0; pt.x < c_nMaxATCols; ++pt.x)
    {
      TiAbilityTreeNode *pNode = m_tree.GetNode(pt);
      if( pNode->IsAbility() )
      {
        // last item in tree will be an ability
        int nBottom = pt.y * c_sizeNodeSpacing.cy + c_sizeNode.cy + c_nAdditionalVSpace;
        m_nMaxRow = pt.y;

        if(nBottom > nMaxScrollY + nContentHeight)
        {
          nMaxScrollY = nBottom - nContentHeight;
        }
      }
    }
  }
  m_cfd.SetRange(nMaxScrollY);
}
//***********************************************************************
// DrawSelf
//***********************************************************************

void TiSkillsWindow::DrawSelf()
{
  DrawBackground();

  TiRect rectWindow = GetScreenRect();
  TiRect rectTree = c_rectInnerFrame + rectWindow.TopLeft();
  TiRect rectContent = m_cfd.GetContentRect(rectTree);

  sm_bdFrame.DrawWithFill(c_rectOuterFrame + rectWindow.TopLeft(), c_crFrameFill);
  m_cfd.Draw(rectTree);
  TiUI::Instance()->FillRectangle(rectContent, SyColor32F(0.f, 0.f, 0.f, .5f));

  TiFont font(TiUI::Instance()->GetFontHandle("Default"));
  char8 szString[300];

  TiRect rect = c_rectTitlebar + rectWindow.TopLeft();
  char8 szBuffer[256] = "";
  static SyResourceID idEquipmentTabName = SyHashResourceID("UiSkillsTabName");

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


  rect = sm_bdFrame.GetInternalRect(c_rectOuterFrame + rectWindow.TopLeft());
  rect.bottom = rect.top + font.GetHeight();

  font.Draw(m_pData->GetName(m_iPlayer), rect, c_crWhite, TI_TF_SHADOW);
  font.Draw(m_pData->GetClassString(m_iPlayer), rect, c_crWhite, TI_TF_SHADOW | TI_TF_HALIGN_CENTER);
  m_pData->GetTitanInterface()->T4SetContext('0', 0, T4::UNKNOWN_SEX, m_pData->GetLevel(m_iPlayer));
  m_pData->GetTitanInterface()->T4Expand(szString, sizeof(szString), SyHashResourceID("UiLevelFormat"));
  font.Draw(szString, rect, c_crWhite, TI_TF_SHADOW | TI_TF_HALIGN_RIGHT);

  rect += TiPoint(0, font.GetHeight());
  if(m_bLevelingUp)
  {
    m_pData->GetTitanInterface()->T4Expand(szString, sizeof(szString), SyHashResourceID("UiLevelUp"));
    font.Draw(szString, rect, c_crWhite, TI_TF_SHADOW);
    m_pData->GetTitanInterface()->T4SetContext('0', 0, T4::UNKNOWN_SEX, m_pData->GetAbilityPoints(m_iPlayer));
    m_pData->GetTitanInterface()->T4Expand(szString, sizeof(szString), SyHashResourceID("UiAvailablePointsFormat"));
    font.Draw(szString, rect, c_crWhite, TI_TF_SHADOW | TI_TF_HALIGN_RIGHT);
  }

  // describe current ability (if any)
  rect += TiPoint(0, font.GetHeight());
  TiAbilityTreeNode *pCurrentNode = m_tree.GetNode(m_ptCurrent);
  if(pCurrentNode != NULL && pCurrentNode->IsAbility())
  {
    SyString strName;

    m_pData->GetTitanInterface()->AbilityGetName(m_iPlayer, pCurrentNode->m_uAbilityHash, strName);
    font.Draw(strName, rect, c_crWhite, TI_TF_SHADOW | TI_TF_HALIGN_CENTER);
  }


  TiPoint ptNode;
  TiPoint ptOS = c_ptFirstNode + rectContent.TopLeft();
  ptOS.y -= m_cfd.GetPos();

  TiPoint ptTier = rectContent.TopLeft();
  ptTier += c_ptTierOffset;
  ptTier.x += (rectContent.Width() - m_sprTier.GetSize().cx) / 2;
  ptTier.y -= m_cfd.GetPos();
  for(int iTier = 0; iTier <= m_nMaxRow; iTier += 2)
  {
    m_sprTier.Draw(ptTier, rectContent);
    ptTier.y += c_sizeNodeSpacing.cy * 2;
  }

  for(ptNode.y = 0; ptNode.y < c_nMaxATRows; ptNode.y++)
  {
    for(ptNode.x = 0; ptNode.x < c_nMaxATCols; ptNode.x++)
    {
      TiAbilityTreeNode *pNode = m_tree.GetNode(ptNode);

      if(pNode->HasConnector(ATN_FROM_TOP))
      {
        m_sprVertBar.Draw(ptOS, rectContent);
      }
      if(pNode->HasConnector(ATN_HORZBAR))
      {
        m_sprHorzBar.Draw(ptOS, rectContent);
      }

      if(pNode->HasConnector(ATN_FROM_LEFT))
      {
        m_sprFromLeft.Draw(ptOS, rectContent);
      }

      if(pNode->HasConnector(ATN_FROM_RIGHT))
      {
        m_sprFromRight.Draw(ptOS, rectContent);
      }

      if(pNode->HasConnector(ATN_TO_LEFT))
      {
        m_sprToLeft.Draw(ptOS, rectContent);
      }

      if(pNode->HasConnector(ATN_TO_RIGHT))
      {
        m_sprToRight.Draw(ptOS, rectContent);
      }
      if(pNode->IsAbility())
      {
        m_sprNode.Draw(ptOS, rectContent);

        if(ptNode == m_ptCurrent)
        {
          TiRect rectSelect(ptOS + c_ptSelectionOffset, m_sprSelectedNode.GetSize());

          m_sprSelectedNode.Pulse(rectSelect, 0.1f, 9.f, rectContent);
        }

        int32 iRank = m_pData->GetTitanInterface()->AbilityGetRank(m_iPlayer, pNode->m_uAbilityHash);
        float32 fAlpha = 0.25f;
        if(iRank > 0)
          fAlpha = 1.f;
        m_sprSkills[ptNode.y * c_nMaxATCols + ptNode.x].Draw(ptOS + c_ptNodeOffset, rectContent, fAlpha);

        int32 iButton = m_pData->GetTitanInterface()->AbilityGetButtonForAbility(m_iPlayer, pNode->m_uAbilityHash);
        if(iButton >= 0)
        {
          TiPoint ptButton = ptOS + c_ptButtonOffset;
          TiRect rectButton(ptButton, c_sizeMiniButton);
          m_sprButtons[iButton].Stretch(rectButton, rectContent);
        }

        if(iRank > 0 && iRank <= 9)
        {
          TiPoint ptRank = ptOS + c_ptRankOffset;
          m_sprRankCircle.Draw(ptRank, rectContent);
          TiRect rectRank(ptRank, c_sizeMiniButton);
          rectRank.AdjustSize(-2, -2);
          m_sprDamageNumbers[iRank].Stretch(rectRank, rectContent);
        }
      }

      ptOS.x += c_sizeNodeSpacing.cx;
    }
    ptOS.x = c_ptFirstNode.x + rectContent.left;
    ptOS.y += c_sizeNodeSpacing.cy;
  }


  // draw mapping
  if(m_bMapping)
  {
    DrawMap();
  }

}

void TiSkillsWindow::DrawMap()
{
  TiFont font(TiUI::Instance()->GetFontHandle("Default"));
  TiRect rectWindow = GetScreenRect();
  TiRect rectMapFrame = c_rectMapFrame + rectWindow.TopLeft();
  TiRect rectContent = sm_bdFrame.GetInternalRect(rectMapFrame);
  TiRect rectTitle;

  sm_bdFrame.DrawWithFill(rectMapFrame, c_crFrameFill);

  SyString strName;

  rectTitle = rectMapFrame;
  rectTitle.top += 7;
  rectTitle.bottom = rectTitle.top + font.GetHeight();
  m_pData->GetTitanInterface()->AbilityGetName(m_iPlayer, m_tree.GetNode(m_ptCurrent)->m_uAbilityHash, strName);
  font.Draw(strName, rectTitle, c_crWhite, TI_TF_SHADOW | TI_TF_HALIGN_CENTER | TI_TF_VCENTER);


  TiSize sizeButton(36, 36);
  TiSize sizeContent = rectContent.Size();
  TiSize sizeNode(56, 56);
  int32 nSpacing = 4;

  TiRect rectButtonChars[] = {
    TiRect(TiPoint((sizeContent.cx - sizeButton.cx) / 2, sizeContent.cy - nSpacing - sizeNode.cy - nSpacing - sizeButton.cy), sizeButton), // X on bottom
    TiRect(TiPoint(nSpacing + sizeNode.cx + nSpacing, (sizeContent.cy - sizeButton.cy) / 2), sizeButton), // Square on left
    TiRect(TiPoint((sizeContent.cx - sizeButton.cx) / 2,  nSpacing + sizeNode.cy + nSpacing), sizeButton), // Triangle on top
    TiRect(TiPoint(sizeContent.cx - nSpacing - sizeNode.cx - nSpacing - sizeButton.cx, (sizeContent.cy - sizeButton.cy) / 2), sizeButton), // Circle on right
  };
  TiRect rectIcons[] = {
    TiRect(TiPoint((sizeContent.cx - sizeNode.cx) / 2, sizeContent.cy - nSpacing - sizeNode.cy), sizeNode), // X on bottom
    TiRect(TiPoint(nSpacing, (sizeContent.cy - sizeNode.cy) / 2), sizeNode), // Square on left
    TiRect(TiPoint((sizeContent.cx - sizeNode.cx) / 2,  nSpacing), sizeNode), // Triangle on top
    TiRect(TiPoint(sizeContent.cx - nSpacing - sizeNode.cx, (sizeContent.cy - sizeNode.cy) / 2), sizeNode), // Circle on right
  };

  for(int i = 0; i < kButtonsToMap; i++)
  {
    if(m_iCurrentlyMappedButton == i)
      m_sprButtons[i].Pulse(rectButtonChars[i] + rectContent.TopLeft(), .2f, 9.f);
    else
      m_sprButtons[i].Stretch(rectButtonChars[i] + rectContent.TopLeft());

    m_sprNode.Stretch(rectIcons[i] + rectContent.TopLeft());
    m_sprButtonSkills[i].Stretch(rectIcons[i] + rectContent.TopLeft());

      
  }

  TiPoint ptCenterNode((sizeContent.cx - sizeNode.cx) / 2, (sizeContent.cy - sizeNode.cy) / 2);

  m_sprNode.Draw(ptCenterNode + rectContent.TopLeft());
  m_sprSkills[m_ptCurrent.y * c_nMaxATCols + m_ptCurrent.x].Draw(ptCenterNode + rectContent.TopLeft());
}

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

bool TiSkillsWindow::ProcessKeyDown( int32 KeyCode )
{
  switch( KeyCode )
  {
  case SyInputEvent::KEYCODE_UP:
    TreeUp();
  	return( true );

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

  case SyInputEvent::KEYCODE_LEFT:
    TreeLeft();
    return( true );

  case SyInputEvent::KEYCODE_RIGHT:
    TreeRight();
    return( true );

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

  case SyInputEvent::KEYCODE_SPACE:
    TryMap( kSquare );
    return( true );

  case SyInputEvent::KEYCODE_DELETE:
    TryMap( kTriangle );
    return( true );

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

  case SyInputEvent::KEYCODE_HOME:
    BeginMap();
    return( true );
  }
  return( false );
}

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

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

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

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

  case TiButtonMap::kLeft:
    TreeLeft();
    return( true );

  case TiButtonMap::kRight:
    TreeRight();
    return( true );

  case TiButtonMap::kX:
    if(m_bMapping)
    {
      TryMap(kX);
    }
    else
    {
      Select();
    }
    return( true );

  case TiButtonMap::kSquare:
    if(m_bMapping)
    {
      TryMap( kSquare );
    }
    return( true );

  case TiButtonMap::kTriangle:
    if(m_bMapping)
    {
      TryMap( kTriangle );
    }
    return( true );

  case TiButtonMap::kCircle:
    if(m_bMapping)
    {
      TryMap(kCircle);
      return true;
    }
    else
    {
      return( Back() );
    }

  case TiButtonMap::kL2:
    BeginMap();
    return( true );

  default:
    return( false );
  }
}

//***********************************************************************
// OnProcessFrame
//***********************************************************************

void TiSkillsWindow::OnProcessFrame()
{
  float32 fElapse = TiUI::Instance()->GetFrameElapse();

  int32 nMinY = m_ptCurrent.y * c_sizeNodeSpacing.cy - c_nAdditionalVSpace;
  int32 nMaxY = nMinY + c_sizeNode.cy + c_nAdditionalVSpace * 2;
  int32 nContentHeight = m_cfd.GetContentRect(c_rectInnerFrame).Height();
  int32 nScroll = (int)(fElapse * 384.f);

  if(nMinY < m_cfd.GetPos())
  {
    m_cfd.SetPos(SY_MAX(0, m_cfd.GetPos() - nScroll));
  }
  else if(nMaxY > m_cfd.GetPos() + nContentHeight)
  {
    m_cfd.SetPos(SY_MIN(m_cfd.GetRange(), m_cfd.GetPos() + nScroll));
  }
}

//***********************************************************************
// ProcessKeyUp
//***********************************************************************

bool TiSkillsWindow::ProcessKeyUp( int32 KeyCode )
{
  switch( KeyCode )
  {
  case SyInputEvent::KEYCODE_HOME:
    return( true );
  }
  return( false );
}

//***********************************************************************
// ProcessButtonUp
//***********************************************************************

bool TiSkillsWindow::ProcessButtonUp( int32 DeviceId, int32 ButtonId )
{
  switch( TiWindow::GetButton( ButtonId ) )
  {
  case TiButtonMap::kL2:
    EndMap();
    return( true );

  default:
    return( false );
  }
}

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

void TiSkillsWindow::ProcessReloadLayout()
{
}

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

void TiSkillsWindow::AbilityMap( FaceButton Button )
{
}

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

void TiSkillsWindow::AbilityBuy()
{
  TiAbilityTreeNode *pNode = m_tree.GetNode(m_ptCurrent);
  if(pNode == NULL || !pNode->IsAbility())
    return;

  m_pData->GetTitanInterface()->AbilityBuy(m_iPlayer, pNode->m_uAbilityHash);
  m_pData->Update();
  m_bLevelingUp = (m_pData->GetAbilityPoints(m_iPlayer) > 0);
}

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

void TiSkillsWindow::TreeDown()
{
  TiPoint ptOld = m_ptCurrent;
  m_ptCurrent.y = SY_MIN(m_nMaxRow, m_ptCurrent.y + 2);

  TiAbilityTreeNode *pNode = m_tree.GetNode(m_ptCurrent);
  bool bLeft = (m_ptCurrent.x > 0);
  while(pNode != NULL && !pNode->IsAbility())
  {
    if(bLeft)
    {
      m_ptCurrent.x--;
      if(m_ptCurrent.x == 0)
        bLeft = false;
    }
    else
    {
      m_ptCurrent.x++;
      if(m_ptCurrent.x >= c_nMaxATCols)
      {
        // failure (go back)
        m_ptCurrent = ptOld;
        return;
      }
    }
    pNode = m_tree.GetNode(m_ptCurrent);
  }
  TiUI::Instance()->PlaySound(TiUI::kSoundTick);
}

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

void TiSkillsWindow::TreeUp()
{
  TiPoint ptOld = m_ptCurrent;
  m_ptCurrent.y = SY_MAX(0, m_ptCurrent.y - 2);
  TiAbilityTreeNode *pNode = m_tree.GetNode(m_ptCurrent);
  bool bLeft = (m_ptCurrent.x > 0);
  while(pNode != NULL && !pNode->IsAbility())
  {
    if(bLeft)
    {
      m_ptCurrent.x--;
      if(m_ptCurrent.x == 0)
        bLeft = false;
    }
    else
    {
      m_ptCurrent.x++;
      if(m_ptCurrent.x >= c_nMaxATCols)
      {
        // failure (go back)
        m_ptCurrent = ptOld;
        return;
      }
    }
    pNode = m_tree.GetNode(m_ptCurrent);
  }
  TiUI::Instance()->PlaySound(TiUI::kSoundTick);
}

//***********************************************************************
// NextGroup
//***********************************************************************

void TiSkillsWindow::TreeLeft()
{
  TiPoint ptOld = m_ptCurrent;
  m_ptCurrent.x = SY_MAX(0, m_ptCurrent.x - 1);
  TiAbilityTreeNode *pNode = m_tree.GetNode(m_ptCurrent);
  while(pNode != NULL && !pNode->IsAbility())
  {
    m_ptCurrent.x--;
    if(m_ptCurrent.x < 0)
    {
      // failure (go back)
      m_ptCurrent = ptOld;
      return;
    }
    pNode = m_tree.GetNode(m_ptCurrent);
  }
  TiUI::Instance()->PlaySound(TiUI::kSoundTick);
}

//***********************************************************************
// PrevGroup
//***********************************************************************

void TiSkillsWindow::TreeRight()
{
  TiPoint ptOld = m_ptCurrent;
  m_ptCurrent.x = SY_MIN(c_nMaxATCols - 1, m_ptCurrent.x + 1);
  TiAbilityTreeNode *pNode = m_tree.GetNode(m_ptCurrent);
  while(pNode != NULL && !pNode->IsAbility())
  {
    m_ptCurrent.x++;
    if(m_ptCurrent.x >= c_nMaxATCols)
    {
      // failure (go back)
      m_ptCurrent = ptOld;
      return;
    }
    pNode = m_tree.GetNode(m_ptCurrent);
  }
  TiUI::Instance()->PlaySound(TiUI::kSoundTick);
}

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

void TiSkillsWindow::Select()
{
  if(m_bLevelingUp && !m_bMapping)
  {
    AbilityBuy();
    TiUI::Instance()->PlaySound(TiUI::kSoundSpellSelect);
  }
}

//***********************************************************************
// TryMap
//***********************************************************************

void TiSkillsWindow::TryMap( FaceButton iButton )
{
  TiAbilityTreeNode *pNode = m_tree.GetNode(m_ptCurrent);
  SyAssert(pNode->IsAbility());
  
  SyResourceID idAbilityToSwap = 0;
  if(m_iCurrentlyMappedButton >= 0 && m_iCurrentlyMappedButton < kButtonsToMap)
  {
    // save this ability to swap it to the old button
    idAbilityToSwap = m_pData->GetTitanInterface()->AbilityGetAbilityForButton(m_iPlayer, iButton);
  }

  m_pData->GetTitanInterface()->AbilityMapButton(m_iPlayer, pNode->m_uAbilityHash, iButton);
  if(idAbilityToSwap != 0)
  {
    // assign the displaced ability to the old button
    m_pData->GetTitanInterface()->AbilityMapButton(m_iPlayer, idAbilityToSwap, m_iCurrentlyMappedButton);
  }
  BeginMap();
}

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

bool TiSkillsWindow::Back()
{
  return false;
}

//***********************************************************************
// BeginMap
//***********************************************************************

void TiSkillsWindow::BeginMap()
{
  TiAbilityTreeNode *pNode = m_tree.GetNode(m_ptCurrent);
  if(pNode != NULL && pNode->IsAbility() && m_pData->GetTitanInterface()->AbilityGetRank(m_iPlayer, pNode->m_uAbilityHash) >= 1)
  {
    m_bMapping = true;

    m_iCurrentlyMappedButton = -1;
    for(int i = 0; i < kButtonsToMap; i++)
    {
      SyResourceID idAbility = m_pData->GetTitanInterface()->AbilityGetAbilityForButton(m_iPlayer, i);
      if(idAbility != 0)
      {
        //SyResourceID idIcon = m_pData->GetTitanInterface()->AbilityGetIcon(m_iPlayer, idAbility);
        //m_sprButtonSkills[i].SetInfo(idIcon);

        m_sprButtonSkills[i].SetInfo(c_pszDefIconNames[idAbility % 5]);

        if(idAbility == pNode->m_uAbilityHash)
        {
          m_iCurrentlyMappedButton = i;
        }
      }
      else
      {
        m_sprButtonSkills[i].SetInfo("");
      }
    }

  }
}

void TiSkillsWindow::EndMap()
{
  m_bMapping = false;
}
