package PrintGame;

/**
 * class representing a two dimensional labyrinth
 */
public class LabyrinthField extends Field
{
      /** the number of diamonds distributed in the field (set from
       * outside of the class with the appropriate method-calls */
  protected int num_diamonds_;

      /** the number of way cells distributed in the field (set from
       * outside of the class with the appropriate method-calls */
  protected int num_way_cells_;

      /** the number of none way cells e.g.way cells (set from
       * outside of the class with the appropriate method-calls */
  protected int num_wall_cells_;

//-----------------------------------------------------------------------------
/**
 * Standard constructor
 * @param rows the number of rows of this labyrinth
 * @param cols the number of columns of this labyrinth
 * @exception IllegalArgumentException thrown if either rows or cols
 * is < 0
 */

  public LabyrinthField(int rows, int cols)
    throws IllegalArgumentException
  {
    super(rows, cols);

    for (int row = 0; row < rows; row++)
    {
      for (int col = 0; col < cols; col++)
      {
        field_[row][col] = new Cell();
        Cell cell = (Cell)field_[row][col];
        //cell.convertToWall();
      }
    }
    num_wall_cells_ = rows * cols;
    num_way_cells_=0;
    num_diamonds_=0;
  }
  
//-----------------------------------------------------------------------------
/**
 *
 */
 public void setCellMark(int row, int col, int cell_mark)
   throws IllegalArgumentException
 {
   if(row<0 || row>getNumRows())
     throw(new IllegalArgumentException(
       "row must be >= 0 and < NumRows"));
   if(col<0 || col>getNumCols())
     throw(new IllegalArgumentException(
       "col must be >= 0 and < NumCols"));
   if(cell_mark<0 || cell_mark>3)
     throw(new IllegalArgumentException(
       "cell_mark is not valid"));
   
   Cell cell=(Cell)field_[row][col];
   cell.setCellMark(cell_mark);
 }
  
//-----------------------------------------------------------------------------
/**
 *
 */

 public void setDiamond(int row, int col)
   throws IllegalArgumentException
 {
   if(row<0 || row>getNumRows())
     throw(new IllegalArgumentException(
       "row must be >= 0 and < NumRows"));
   if(col<0 || col>getNumCols())
     throw(new IllegalArgumentException(
       "col must be >= 0 and < NumCols"));

   Cell cell=(Cell)field_[row][col];
   if((cell.containsDiamond()==false) && (cell.isWay()==true) && (cell.isStartpoint()==false));
   {
     cell.setDiamond();
     num_diamonds_++;
   }
 }

  public void removeDiamond(int row, int col)
    throws IllegalArgumentException
 {
    if(row<0 || row>getNumRows())
       throw(new IllegalArgumentException(
        "row must be >= 0 and < NumRows"));
    if(col<0 || col>getNumCols())
       throw(new IllegalArgumentException(
        "col must be >= 0 and < NumCols"));
    
    Cell cell=(Cell)field_[row][col];
    if((cell.containsDiamond()==true) && (cell.isWay()==true) && (cell.isStartpoint()==false));
    {
      cell.removeDiamond();
      num_diamonds_--;
     
    }
  } 
//-----------------------------------------------------------------------------
/**
 *
 */ 
  public void removeStartpoint(int row, int col)
    throws IllegalArgumentException
 {
    if(row<0 || row>getNumRows())
       throw(new IllegalArgumentException(
        "row must be >= 0 and < NumRows"));
    if(col<0 || col>getNumCols())
       throw(new IllegalArgumentException(
        "col must be >= 0 and < NumCols"));
    
    Cell cell=(Cell)field_[row][col];
    if((cell.isStartpoint()==true) && (cell.isWay()==true))
    {
      cell.removeStartpoint();
    }
  }  
//-----------------------------------------------------------------------------
/**
 *
 */

 public void convertToWay(int row, int col)
   throws IllegalArgumentException
 {
   if(row<0 || row>getNumRows())
     throw(new IllegalArgumentException(
       "row must be >= 0 and < NumRows"));
   if(col<0 || col>getNumCols())
     throw(new IllegalArgumentException(
       "col must be >= 0 and < NumCols"));

   Cell cell=(Cell)field_[row][col];
   if (cell.isWay()==true)
     throw(new IllegalArgumentException(
       "can not convert a Waycell to a Way"));

   num_way_cells_++;
   num_wall_cells_--;
   cell.convertToWay();
 }
//-----------------------------------------------------------------------------
/**
 *
 */

 public void convertToWall(int row, int col)
   throws IllegalArgumentException
 {
   if(row<0 || row>getNumRows())
     throw(new IllegalArgumentException(
       "row must be >= 0 and < NumRows"));
   if(col<0 || col>getNumCols())
     throw(new IllegalArgumentException(
       "col must be >= 0 and < NumCols"));

   Cell cell=(Cell)field_[row][col];
   if (cell.isWall()==true)
     throw(new IllegalArgumentException(
       "can not convert a Wallcell to a Wall"));

   num_way_cells_--;
   num_wall_cells_++;
   cell.convertToWall();
 }
//-----------------------------------------------------------------------------
/**
 *
 */

 public void convertToStartpoint(int row, int col)
   throws IllegalArgumentException
 {
   if(row<0 || row>getNumRows())
     throw(new IllegalArgumentException(
       "row must be >= 0 and < NumRows"));
   if(col<0 || col>getNumCols())
     throw(new IllegalArgumentException(
       "col must be >= 0 and < NumCols"));

   Cell cell=(Cell)field_[row][col];
   if (cell.isWay()==true)
   {
     num_wall_cells_--;
     num_way_cells_++;
   }
   else
     num_way_cells_++;
   cell.convertToStartpoint();

 }

//-----------------------------------------------------------------------------
/**
 *
 *
 */

  public int getNumDiamonds()
  {
    return num_diamonds_;
  }

//-----------------------------------------------------------------------------
/**
 *
 *
 */

  public int getNumWayCells()
  {
    return num_way_cells_;
  }

//-----------------------------------------------------------------------------
/**
 *
 *
 */

  public int getNumWallCells()
  {
    return num_wall_cells_;
  }

//-----------------------------------------------------------------------------
/**
 *
 *
 */

  public boolean isWay(int row, int col)
   throws IllegalArgumentException
 {
   if(row<0 || row>getNumRows())
     throw(new IllegalArgumentException(
       "row must be >= 0 and < NumRows"));
   if(col<0 || col>getNumCols())
     throw(new IllegalArgumentException(
       "col must be >= 0 and < NumCols"));

    Cell cell=(Cell)field_[row][col];
    return cell.isWay();
  }

//-----------------------------------------------------------------------------
/**
 *
 *
 */

  public boolean isWall(int row, int col)
   throws IllegalArgumentException
 {
   if(row<0 || row>getNumRows())
     throw(new IllegalArgumentException(
       "row must be >= 0 and < NumRows"));
   if(col<0 || col>getNumCols())
     throw(new IllegalArgumentException(
       "col must be >= 0 and < NumCols"));

    Cell cell=(Cell)field_[row][col];
    return cell.isWall();
  }

//-----------------------------------------------------------------------------
/**
 *
 *
 */

  public boolean isStartpoint(int row, int col)
   throws IllegalArgumentException
 {
   if(row<0 || row>getNumRows())
     throw(new IllegalArgumentException(
       "row must be >= 0 and < NumRows"));
   if(col<0 || col>getNumCols())
     throw(new IllegalArgumentException(
       "col must be >= 0 and < NumCols"));

    Cell cell=(Cell)field_[row][col];
    return cell.isStartpoint();
  }

  
//-----------------------------------------------------------------------------
/**
 *
 *
 */
  public int getCellMark(int row, int col)
   throws IllegalArgumentException
 {
   if(row<0 || row>getNumRows())
     throw(new IllegalArgumentException(
       "row must be >= 0 and < NumRows"));
   if(col<0 || col>getNumCols())
     throw(new IllegalArgumentException(
       "col must be >= 0 and < NumCols"));

    Cell cell=(Cell)field_[row][col];
    return cell.getCellMark();
  }  

//-----------------------------------------------------------------------------
/**
 *
 *
 */

  public boolean containsDiamond(int row, int col)
   throws IllegalArgumentException
 {
   if(row<0 || row>getNumRows())
     throw(new IllegalArgumentException(
       "row must be >= 0 and < NumRows"));
   if(col<0 || col>getNumCols())
     throw(new IllegalArgumentException(
       "col must be >= 0 and < NumCols"));

    Cell cell=(Cell)field_[row][col];
    return cell.containsDiamond();
  }
//-----------------------------------------------------------------------------
/**
 * package-internal method that returns if all diamonds were found
 * according to the internal counters
 */

  public boolean wereAllDiamondsFound()
  {
    return(num_diamonds_ == 0);
  }

  public void setEmpty(int row, int col)
    throws IllegalArgumentException
  {
     if(row<0 || row>getNumRows())
     throw(new IllegalArgumentException(
       "row must be >= 0 and < NumRows"));
     if(col<0 || col>getNumCols())
       throw(new IllegalArgumentException(
         "col must be >= 0 and < NumCols"));

     Cell cell=(Cell)field_[row][col];
     if (cell.isWay()==true)
     {
       num_way_cells_--;
     }
     else if (cell.isWall())
     {
       num_wall_cells_--;
     }
      
    cell.setEmpty();
  }
  public boolean isEmpty(int row, int col)
   throws IllegalArgumentException
 {
   if(row<0 || row>getNumRows())
     throw(new IllegalArgumentException(
       "row must be >= 0 and < NumRows"));
   if(col<0 || col>getNumCols())
     throw(new IllegalArgumentException(
       "col must be >= 0 and < NumCols"));

    Cell cell=(Cell)field_[row][col];
    return cell.isEmpty();
  }
//----------------------------------------------------------------------------
/**
 * standard toString method for debugging
 * @return info about the labyrinth field in string-format
 */

  public String toString()
  {
    return("Labyrinthfield: num_diamonds_ = " + num_diamonds_ +
           ", num_way_cells_ = " + num_way_cells_ +
           ", num_wall_cells_ = " + num_wall_cells_ +
           super.toString());
  }

}
