#include ".\playerdata.h"
#include ".\LD.h"



PlayerData::PlayerData()
{

  Init();

}



void PlayerData::Init()
{

  m_Radars.clear();
  m_Resources.clear();
  m_CollectedResources.clear();
  m_BoughtItems.clear();

  m_Oxygen                = 0;
  m_OxygenPerExpedition   = 20;

  m_Credits               = 200;

  m_Radars.insert( LD::RT_ZINC );

  m_BoughtItems.insert( LD::SI_EDISON_WARP_DRIVE );
  m_BoughtItems.insert( LD::SI_SMALL_GROUND_ROVER );
  m_BoughtItems.insert( LD::SI_ZINC_RADAR );

  //m_Credits               = 80000000;

}



bool PlayerData::HasCollected( Universe::Star* pStar, int PlanetIndex, LD::Resource& Resource )
{

  std::map<std::pair<tPoint,int>,std::set<tPoint> >::iterator    itStar( m_CollectedResources.find( std::make_pair( pStar->Location, PlanetIndex ) ) );
  if ( itStar == m_CollectedResources.end() )
  {
    return false;
  }
  std::set<tPoint>&   setRes( itStar->second );

  return( setRes.find( Resource.Location ) != setRes.end() );

}



void PlayerData::Collect( Universe::Star* pStar, int PlanetIndex, LD::Resource& Resource )
{

  m_Resources[Resource.Type] += Resource.Quantity;
  m_CollectedResources[std::make_pair( pStar->Location, PlanetIndex )].insert( Resource.Location );

  if ( pStar->HasAlienTech )
  {
    bool    hasAlienTech = false;
    for ( size_t i = 0; i < pStar->Planets.size(); ++i )
    {
      if ( theApp.m_Universe.HasPlanetResource( pStar, (int)i, LD::RT_ALIEN_TECHNOLOGY ) )
      {
        hasAlienTech = true;
        break;
      }
    }
    pStar->HasAlienTech = hasAlienTech;
  }

}



bool PlayerData::HasBought( LD::ShopItem Item )
{

  return( m_BoughtItems.find( Item ) != m_BoughtItems.end() );
}



void PlayerData::Buy( LD::ShopItem Item, long long Cost )
{

  m_Credits -= Cost;
  m_BoughtItems.insert( Item );

  switch ( Item )
  {
    case LD::SI_ALIEN_RADAR:
      m_Radars.insert( LD::RT_ALIEN_TECHNOLOGY );
      break;
    case LD::SI_CRYSTITE_RADAR:
      m_Radars.insert( LD::RT_CRYSTITE );
      break;
    case LD::SI_GOLD_RADAR:
      m_Radars.insert( LD::RT_GOLD );
      break;
    case LD::SI_SPICE_RADAR:
      m_Radars.insert( LD::RT_SPICE );
      break;
    case LD::SI_UNOBTANIUM_RADAR:
      m_Radars.insert( LD::RT_UNOBTAINIUM );
      break;
    case LD::SI_ZINC_RADAR:
      m_Radars.insert( LD::RT_ZINC );
      break;
  }

}



int PlayerData::PossibleTravelDistance()
{

  int   possibleDistance = 0;

  if ( HasBought( LD::SI_EDISON_WARP_DRIVE ) )
  {
    possibleDistance = 35;
  }
  if ( HasBought( LD::SI_EDISON_WARP_DRIVE_20 ) )
  {
    possibleDistance = 90;
  }
  if ( HasBought( LD::SI_HYPERSPACE_DRIVE ) )
  {
    possibleDistance = 430;
  }
  if ( HasBought( LD::SI_HYPERSPACE_DRIVE_HRON ) )
  {
    possibleDistance = 14800;
  }

  return possibleDistance;

}



bool PlayerData::CanEnterPlanet( Universe::Planet* pPlanet )
{

  switch ( pPlanet->PlanetType )
  {
    case Universe::PT_DIRT:
      if ( ( HasBought( LD::SI_SMALL_GROUND_ROVER ) )
      ||   ( HasBought( LD::SI_HAPPYCO_JET ) ) )
      {
        return true;
      }
      break;
    case Universe::PT_ROCK:
      if ( ( HasBought( LD::SI_SMALL_GROUND_ROVER ) )
      ||   ( HasBought( LD::SI_HAPPYCO_JET ) ) )
      {
        return true;
      }
      break;
    case Universe::PT_ICE:
      if ( HasBought( LD::SI_HAPPYCO_JET ) )
      {
        return true;
      }
      if ( ( HasBought( LD::SI_SMALL_GROUND_ROVER ) )
      &&   ( HasBought( LD::SI_ROVER_SPIKES ) ) )
      {
        return true;
      }
      break;
    case Universe::PT_FIRE:
      if ( ( HasBought( LD::SI_HAPPYCO_JET ) )
      &&   ( HasBought( LD::SI_HEAT_SHIELD ) ) )
      {
        return true;
      }
      break;
    case Universe::PT_LAVA:
      if ( HasBought( LD::SI_HAPPYCO_JET ) )
      {
        return true;
      }
      if ( ( HasBought( LD::SI_BASIC_BOAT ) )
      &&   ( HasBought( LD::SI_HEAT_SHIELD ) ) )
      {
        return true;
      }
      break;
    case Universe::PT_WATER:
      if ( ( HasBought( LD::SI_BASIC_BOAT ) )
      ||   ( HasBought( LD::SI_HAPPYCO_JET ) ) )
      {
        return true;
      }
      break;
  }
  return false;

}



LD::VehicleType PlayerData::SuggestVehicle( Universe::Planet* pPlanet )
{

  switch ( pPlanet->PlanetType )
  {
    case Universe::PT_DIRT:
      if ( HasBought( LD::SI_HAPPYCO_JET ) )
      {
        return LD::VT_JET;
      }
      if ( HasBought( LD::SI_SMALL_GROUND_ROVER ) )
      {
        return LD::VT_ROVER;
      }
      break;
    case Universe::PT_ROCK:
      if ( HasBought( LD::SI_HAPPYCO_JET ) )
      {
        return LD::VT_JET;
      }
      if ( HasBought( LD::SI_SMALL_GROUND_ROVER ) )
      {
        return LD::VT_ROVER;
      }
      break;
    case Universe::PT_ICE:
      if ( HasBought( LD::SI_HAPPYCO_JET ) )
      {
        return LD::VT_JET;
      }
      if ( ( HasBought( LD::SI_SMALL_GROUND_ROVER ) )
      &&   ( HasBought( LD::SI_ROVER_SPIKES ) ) )
      {
        return LD::VT_ROVER;
      }
      break;
    case Universe::PT_FIRE:
      if ( ( HasBought( LD::SI_HAPPYCO_JET ) )
      &&   ( HasBought( LD::SI_HEAT_SHIELD ) ) )
      {
        return LD::VT_JET;
      }
      break;
    case Universe::PT_LAVA:
      if ( HasBought( LD::SI_HAPPYCO_JET ) )
      {
        return LD::VT_JET;
      }
      if ( ( HasBought( LD::SI_BASIC_BOAT ) )
      &&   ( HasBought( LD::SI_HEAT_SHIELD ) ) )
      {
        return LD::VT_BOAT;
      }
      break;
    case Universe::PT_WATER:
      if ( HasBought( LD::SI_HAPPYCO_JET ) )
      {
        return LD::VT_JET;
      }
      if ( HasBought( LD::SI_BASIC_BOAT ) )
      {
        return LD::VT_BOAT;
      }
      break;
  }
  return LD::VT_NONE;

}



void PlayerData::Destroyed( Universe::Star* pVisitedStarSystem, int PlanetIndex, int X, int Y )
{

  m_DestroyedUnits[std::make_pair( pVisitedStarSystem->Location, PlanetIndex )].insert( tPoint( X, Y ) );

}



bool PlayerData::HasDestroyed( Universe::Star* pStar, int PlanetIndex, int X, int Y )
{

  std::map<std::pair<tPoint,int>,std::set<tPoint> >::iterator    itStar( m_DestroyedUnits.find( std::make_pair( pStar->Location, PlanetIndex ) ) );
  if ( itStar == m_DestroyedUnits.end() )
  {
    return false;
  }
  std::set<tPoint>&   setRes( itStar->second );

  return( setRes.find( tPoint( X, Y ) ) != setRes.end() );

}



