// ocean.h
// 
// implementation for ocean
// 

#include <cstdlib>
#include <ctime>

#include "ocean.h"
#include "Sub.h"

namespace
{
std::string OceanTargetsString[Seahunt::Ocean::MAX_TARGET] = {
  "Stealth Spy Submarine",
  "Rescue Submarine",
  "Supply Submarine",
  "Attack Submarine",
  "Boomer Submarine" };
int OceanTargetDepths[Seahunt::Ocean::MAX_TARGET] = { 100, 200, 400, 700, 1000 };
int OceanTargetArmor[Seahunt::Ocean::MAX_TARGET] = { 1, 2, 3, 4, 5 };
}

namespace Seahunt
{

Ocean::Ocean()
{
  Utility::UserEntry( "Ocean Name", name, 50 );
  Utility::UserEntry( "Number of Targets", target_count, 1, MAX_TARGET );
  Init();
  #ifdef OCEAN_TEST
  std::cout << "Constructed Ocean: " << name << std::endl;
  #endif
}

void
Ocean::Init( void )
{
  active_targets = 0;
  destroyed_targets = 0;

  // Go through the target list and delete the objects
  for ( int c=0; c < MAX_TARGET; ++c )
  {
    targets[c] = 0;
  }
  for ( int i = 0; i < 10; i++ )
  {
    for ( int j = 0; j < 10; j++ )
    {
      for ( int k = 0; k < 10; k++ )
      {
        ocean[i][j][k].Set_xyz( i, j, k );
      }
    }
  }
}

Ocean::~Ocean()
{
  // Go through the target list and delete the objects
  for ( int i=0; i < MAX_TARGET; ++i )
  {
    if ( targets[i] )
    {
      delete targets[i];
      targets[i] = 0;
    }
  }
  #ifdef OCEAN_TEST
  std::cout << "Destructed Ocean: " << name << std::endl;
  #endif
}

void
Ocean::PlaceTarget( void )
{
  for ( int i=0; i<target_count; i++ )
  {
     targets[i] = Sub::Create( OceanTargetsString[i], 
                               OceanTargetArmor[i], 
                               OceanTargetDepths[i] );
     if ( targets[i] )
     {
       TargetPlacement ( targets[i] );
     }
  }
  active_targets = i;
}

void
Ocean::TargetPlacement ( Target * t )
{
  int i = 0;
  if (t)
  {
    while ( i < t->Get_armor() )
    {
      int r = 0;
      int c = 0;
      int d = 0;
      std::cout << "\nTarget: " << t->Get_name() << std::endl;
      std::cout << "Position " << i+1 << " of " << t->Get_armor() << std::endl;
      Utility::UserEntry ( "Row Position", r, 1, ROW );
      Utility::UserEntry ( "Column Position", c, 1, COL );
      Utility::UserEntry ( "Depth Position", d, 100, t->Get_depth_limit() );       
      d = d/DEPTHFACTOR;
      if ( ocean[r-1][c-1][d-1].Get_target() == 0 )
      {
        ocean[r-1][c-1][d-1].Set_target(t);
        i++;
      }
      else
      {
        std::cout << "\nOcean [" << r << "][" << c << "][" << d << "]"
                  << " is already populated\n" << std::endl;
      }
    }
  }
}

bool
Ocean::Hit ( void )
{
  int r = 0;
  int c = 0;
  int d = 0;
  bool status = false;
  std::cout << "\nHit a spot in the " << name << std::endl;
  Utility::UserEntry ( "Row Position", r, 1, ROW );
  Utility::UserEntry ( "Column Position", c, 1, COL );
  Utility::UserEntry ( "Depth Position", d, 100, DEPTH*DEPTHFACTOR );
  d = d/DEPTHFACTOR;
  status = ocean[r-1][c-1][d-1].Hit();
  if ( status == true )
  {
    if ( ocean[r-1][c-1][d-1].Get_target()->Get_status() == DEAD )
    {
      destroyed_targets++;
      active_targets--;
    }
  }
  return ( status );
}

void 
Ocean::Show ( void )
{
  int i = 0;
  int j = 0;
  int d = 0;
  for ( d=0; d<DEPTH; ++d )
  {
    std::cout << "Ocean Depth: " << (d+1)*DEPTHFACTOR << std::endl;
    std::cout << "------------------------------------------" << std::endl;
    std::cout << "    1   2   3   4   5   6   7   8   9   10" << std::endl;
    for ( i=0; i<ROW; ++i )
    {
      std::cout << std::endl << i+1;
      if ( i < 9 )
      {
        std::cout << "   ";
      }
      else
      {
        std::cout << "  ";
      }
      for ( j=0; j<COL; ++j )
      {
        if ( ocean[i][j][d].Get_target() )
        {
         
          std::cout << ocean[i][j][d].Get_target()->Get_armor() << "   ";
        }
        else
        {
          std::cout << "-   ";
        }
      }
      std::cout << std::endl;
    }
    Utility::WaitKey();
  }
}

void 
Ocean::ShowTargets( void )
{
  std::cout << 
  "\nOcean Target Status\n" << 
  "----------------------------------------\n" <<
  "Target Count     : " << target_count << "\n" <<
  "Active Targets   : " << active_targets << "\n" <<
  "Destroyed Targets: " << destroyed_targets << std::endl;
  for ( int i=0; i<MAX_TARGET; ++i )
  {
    std::cout << "\nOcean Target " << i+1 << std::endl;
    if ( targets[i] )
    {
      targets[i]->Show();
    }
  }
  std::cout << "----------------------------------------" << std::endl;
}

int 
Ocean::Get_target_count( void ) const
{
  return( target_count );
}

int 
Ocean::Get_active_targets( void ) const
{
  return( active_targets );
}

int 
Ocean::Get_destroyed_targets( void ) const
{
  return( destroyed_targets );
}

} // namespace Seahunt

#ifdef OCEAN_TEST

int
main ( void )
{
  std::cout << "Ocean Unit Test\n" << std::endl;

  Seahunt::Ocean atlantic;

  atlantic.PlaceTarget();

  atlantic.Hit(); 
  atlantic.Hit(); 

  Seahunt::Utility::WaitKey();

  atlantic.Show();

  atlantic.ShowTargets();

  Seahunt::Utility::WaitKey();

  return(0);
}
#endif

