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_;

  protected int start_point_row_;
  protected int start_point_col_;
  protected Direction start_direction_;
  protected String name_;

//-----------------------------------------------------------------------------
/**
 * 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;
    start_point_row_=-1;
    start_point_col_=-1;
    start_direction_=null;
    name_=new String();
  }

//-----------------------------------------------------------------------------
/**
 *
 */
 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<-1 || 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 setName(String name)
 {
   name_=name;
 }

 public String getName()
 {
   return name_;
 }
 //-----------------------------------------------------------------------------
/**
 *
 */

 public void setStartDirection(Direction direction)
 {
   //start_direction_= new Direction();
   start_direction_=direction;
 }

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

  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"));
    if((start_point_row_!=row) || (start_point_col_!=col))
       throw(new IllegalArgumentException(
        "can not remove startpoint, cell is not a startpoint"));

    if((start_point_row_==row) && (start_point_col_==col))
    {
      start_point_row_=-1;
      start_point_col_=-1;
    }
  }
//-----------------------------------------------------------------------------
/**
 *
 */

 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"));
   if((start_point_row_==row) && (start_point_col_==col))
     throw(new IllegalArgumentException(
       "can not convert to wall, cel is a startpoint"));

   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"));
   if((start_point_row_==row) && (start_point_col_==col))
       throw(new IllegalArgumentException(
        "can not convert to a startpoint, cell is a startpoint"));

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

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

  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"));

   if((start_point_row_==row) && (start_point_col_==col))
     return true;
   else
     return false;
  }


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

  public boolean isStartpoint()
 {
   if((start_point_row_==-1) || (start_point_col_==-1))
    return false;
   else
     return true;
  }


//-----------------------------------------------------------------------------
/**
 *
 *
 */
  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 int getStartpointRow()
   throws IllegalArgumentException
 {
   if(start_point_row_==-1)
     throw(new IllegalArgumentException(
       "startpoint is not set"));

    return start_point_row_;
  }


//-----------------------------------------------------------------------------
/**
 *
 *
 */
  public int getStartpointCol()
   throws IllegalArgumentException
 {
   if(start_point_col_==-1)
     throw(new IllegalArgumentException(
       "startpoint is not set"));

    return start_point_col_;
  }


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


  public Direction getStartDirection()
  {
    return start_direction_;
  }

  public boolean isStartDirection()
  {
    if(start_direction_!=null)
      return true;
    else
      return false;
  }

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

  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_--;
     }
     else if((start_point_row_==row) || (start_point_col_==col))
     {
       start_point_row_=-1;
       start_point_col_=-1;
     }

    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"));
    if((start_point_row_!=row) || (start_point_col_!=col))
    {
      Cell cell=(Cell)field_[row][col];
      return cell.isEmpty();
    }
    else
      return false;
  }
//----------------------------------------------------------------------------
/**
 * 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());
  }

}
