// cell.cpp
// 
// Implementation for type cell where cell is a piece of an ocean. 
// Cell contains a pointer to the base class Target.  Through
// the based class pointer Cell polymorphically calls Hit of the
// derived target object/

#include "cell.h"

namespace Seahunt
{

Cell::Cell()
{
  hit_status = false;
  x = 0;
  y = 0;
  z = 0;
  target = 0;
}

Cell::Cell ( const Cell & c )
{
  hit_status = false;
  x = c.Get_x();
  y = c.Get_y();
  z = c.Get_z();
  target = c.Get_target();
}

Cell::~Cell()      
{                 
  // do not cleanup the target
}                 

void
Cell::Set_xyz( int _x, int _y, int _z )
{
  x = _x;  y = _y;  z = _z;
}

inline
int
Cell::Get_x ( void ) const
{
  return(x);
}

inline
int
Cell::Get_y ( void ) const
{
  return(y);
}

inline                    
int                       
Cell::Get_z ( void ) const
{                         
  return(z);              
}                         

bool
Cell::Set_target ( Target * t )
{
  bool set_status = false;
  if ( target == 0 )
  {
    target = t;
    set_status = true;
  }
  return(set_status);
}   

Target *
Cell::Get_target ( void ) const
{
  return ( target );
}

bool
Cell::Hit ( void )
{
  std::cout << "\n[" << x+1 << ","
            << y+1 << "," << z+1 << "]" << std::endl; 
  bool local_hit = false;
  if ( target )
  {
    if ( hit_status == false )
    {
      if ( target->Hit() )
      {
        std::cout << "*** Hit ***" << std::endl;
        hit_status = true;
        local_hit = true;
      }
    }
    else
    {
      std::cout << "*** Already Hit ***" << std::endl;
      local_hit = false;
    }
  }
  else
  {
    std::cout << "*** Miss ***" << std::endl;
  }
  return(local_hit);
}

} // namespace Seahunt

#ifdef CELL_TEST

#include "sub.h"

int
main (void)
{
  std::cout << "Cell Unit Test" << std::endl;

  Seahunt::Sub * s = Seahunt::Sub::Create();
  
  Seahunt::Cell layer[10][10][10];

  for ( int i = 0; i < 10; i++ )
  {
    for ( int j = 0; j < 10; j++ )
    {
      for ( int k = 0; k < 10; k++ )
      {
        layer[i][j][k].Set_xyz( i, j, k );
      }
    }
  }

  layer[3][1][2].Set_target( s );
  layer[3][2][2].Set_target( s );
  layer[3][3][2].Set_target( s );

  // fails for already popluated
  bool place_stat = layer[3][3][2].Set_target( s );
  if ( !place_stat )
  {
    std::cout << "\nFailed to place target: already popluated\n" 
              << std::endl;
    s->Show();
  }

  // miss
  layer[2][1][5].Hit();

  // hits
  layer[3][1][2].Hit();
  layer[3][2][2].Hit();
  layer[3][3][2].Hit();

  // multiple common hit
  layer[3][3][2].Hit();

  return(0);
}
#endif


// eof cell.cpp

