/*
 * This is the "main" class.  All it does is instantiate
 * a controller and get the game running.
 */

public class mine {

  public static void main(String [] argv){
    
    GameController control = new GameController();
    control.startGame();
    
  }
}

/*********************************************************************/

/*
 * This class is eventually going to control all the flow
 * of Minesweeper.  All input/output of the program will 
 * be through this class.  
 */
public class GameController{

  private int level_;
  private Grid grid_;

  public GameController(){
  }

  public void startGame(){

    System.out.println("Hello!  Welcome to Danah's Minesweeper");
    if (this.askLevel()){
      this.createGame();
      this.startFlow();
    }
    else {
      System.out.println("Oh well, thanks for trying!");
    }

  }
    
  /* 
   * The goal of this method is to ask the user what level
   * they want to play.  It is important to make certain that
   * the input is accurate and that we act accordingly.
   *
   * The boolean tells the controller whether or not we want
   * to actually play
   */
  public boolean askLevel(){

    System.out.println("What level would you like to play?");
    System.out.println("1=Beginner, 2=Intermediate, 3=Advanced (0 for no play)");
    level_ = ReadInput.getInt();
System.out.println("more stuff = " + ReadInput.isMoreStuff());
    ReadInput.flushLine(); // flush the rest of the line!

    System.out.println("You have chosen level " + level_);

    /* Since 0 is no play, we check for no play and return whether
     * or not we got a zero.  I don't know what to do if they type 
     * something that is not correct...
     */
    if (level_ != 0){
      return true;
    }
    else return false;
  }

  /*
   * Given the level of the game, this method creates the
   * actual board.  [Right now, it only prints out the very
   * basics since we don't have a board class]
   */
  public void createGame(){
    /* eventually, this will create a real game but for now
     * I will just print out an array of the appropriate size
     */
    
    int xSize, ySize, numMines;
    

    /* THESE SHOULD BE CONSTANTS */
    if (level_ == 1){
      xSize = 8;
      ySize = 8;
      numMines = 4;
    }
    else if (level_ == 2){
      xSize = 16;
      ySize = 16;
      numMines = 4;
    }
    else if (level_ == 3){
      xSize = 16;
      ySize = 30;
      numMines = 4;
    }
    else {
      System.out.println("What size x,y would you like? [x y]");
      xSize = ReadInput.getInt();
      ySize = ReadInput.getInt();
      ReadInput.flushLine(); // flush the rest of the line!
      System.out.println("How many mines do you want?");
      numMines = ReadInput.getInt();
      ReadInput.flushLine(); // flush the rest of the line! 
      
    }

    grid_ = new Grid(xSize, ySize, numMines);
    grid_.createGrid();
    grid_.printGrid();
    
  }

  /* 
   * Eventually, this will deal with the flow of control.
   * Right now, we are just asking the questions and doing
   * nothing with the responses.
   */
  public void startFlow(){
    
    int option, x, y;
    System.out.println("What would you like to do next?");
    System.out.println("Options: 1=Uncover, 2=Flag, 3=Clear");
    option = ReadInput.getInt();
    ReadInput.flushLine(); // flush the rest of the line!

    System.out.println("What x and y positions? [x y]");
    x = ReadInput.getInt();
    y = ReadInput.getInt();
    ReadInput.flushLine(); // flush the rest of the line!

    /*
     * While this is not the eventual goal, it lets me know
     * what I am _wanting_ to do.
     */
    if (option == 1){
      System.out.println("You would like to uncover node (" + x + "," + y + ")");
    }
    else if (option == 2){
      System.out.println("You would like to flag node (" + x + "," + y + ")");
    }
    
    else if (option == 3){
      System.out.println("You would like to clear node (" + x + "," + y + ")");
    }
    else {
      System.out.println("You did not choose a valid commmand");
    }
    

  }
}

/*********************************************************************/


/*
 * This class models the grid of the entire board and also
 * has a print method...
 */

public class Grid {

  private int width_, height_, numMines_;

  private Square [][] grid_;

  public Grid(int x, int y, int numMines){
    
    width_ = x;
    height_ = y;
    numMines_ = numMines;
    
    grid_ = new Square[width_][height_];

  }


  public void createGrid(){

    java.util.Random randomizer = new java.util.Random();
    
    int randomX, randomY;

    for (int i=0; i<numMines_; i++){
      
      randomX = (int) (randomizer.nextDouble() * width_);
      randomY = (int) (randomizer.nextDouble() * height_);

      grid_[randomX][randomY] = new MineSquare();

    }

    
    for (int y=0; y<height_; y++){
      for (int x=0; x<width_; x++){
	if (grid_[x][y] == null){
	  grid_[x][y] = new NumberSquare();
	}
      }
    }


  }

  public void printGrid(){
    System.out.println(""); // this gives clearer space
    for (int y=0; y<height_; y++){
      for (int x=0; x<width_; x++){
	System.out.print(" ");
	grid_[x][y].printSquare();
      }
      System.out.println("");
    }
   System.out.println(""); // this ends it so it does not cram into the bottom
  }
    
}

/*********************************************************************/


/* 
 *  The goal of this class is to model a generic square.  It
 *  is an abstract class because we never use a square, only
 *  its subclasses.
 */

public abstract class Square {

  protected String printableElement_;

  public Square(){

    printableElement_ = "x";  // this is a good starter type

  }

  public void printSquare(){
    System.out.print("" + printableElement_);
  }
  
  public void flagSquare(){
    printableElement_ = "f";
  }

  public void clearSquare(){}

  abstract public void uncoverSquare();


}

/*********************************************************************/

public class MineSquare extends Square {


  public MineSquare(){

    super();

  }

  public void uncoverSquare(){
    
    printableElement_ = "B";
    // I don't know how to tell the game that it is the end!

  }


}


/*********************************************************************/


public class NumberSquare extends Square {


  public NumberSquare(){

    super();

  }

  public void clearSquare(){
  }

  public void uncoverSquare(){
    
    printableElement_ = " "; // this is temporary
    // i don't know how to tell what number I am and then combine
    // that information to pass on everything to uncover everything

  }


}
