import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

/** The main window showing the HiQ board and its contents. */
public class HiQWindow extends JFrame implements ActionListener {
  
  /** The labels with the characters. */
  private JButton[][] visuals;
  
  /** The HiQBoard to display. */
  private HiQBoard gameBoard;
  
  /** The last button that was clicked. */
  private JButton lastClicked;
  
  /** A new HiQ game window. 
   * @param b The HiQBoard to display.
   */
  public HiQWindow(HiQBoard b) {
    gameBoard = b;
    setTitle("HiQ");
  }
  
  /**
   * Initialize the window by creating a grid of buttons, one 
   * for each position and labelling it with the appropriate 
   * character.Register each button as an ActionListener in this 
   * window.
   */
  public void initWindow() {
    visuals = new JButton[gameBoard.numRows()][gameBoard.numCols()];
    Container content = this.getContentPane();
    content.setLayout(new GridLayout(gameBoard.numRows(), gameBoard.numCols()));
      
    for (int r = 0; r != gameBoard.numRows(); r++) {
      for (int c = 0; c != gameBoard.numCols(); c++) {
        visuals[r][c] = new JButton(gameBoard.getMark(r, c) + "");
        visuals[r][c].addActionListener(this);
        content.add(visuals[r][c]);
      }
    }
    
    // let Java determine the size of the window based on what's in it; 
    // display the window; 
    // see if there are any moves on the board to start with.
    pack();
    
    show();
    
    checkGameOver();
  }
  
  /**
   * Refresh the display by resetting the text of the buttons
   * to match the game board. Check whether game is over yet.
   */
  public void update() {
    // update the game display to be the contents of the board
    for (int r = 0; r < gameBoard.numRows(); r++) { 
      for (int c = 0; c < gameBoard.numCols(); c++) { 
        visuals[r][c].setText(gameBoard.getMark(r, c) + "");
      }
    }
    
    checkGameOver();
  }
  
  /**
   * If the game is over, display a message window informing the user and
   * terminate the game; do nothing otherwise.
   */
  public void checkGameOver() {
    // check whether or not the game is over
    if (gameBoard.gameOver()) {
      if (gameBoard.getNumPegs() != 1) {
        JOptionPane.showMessageDialog
          (this, "Game over.  There are " + gameBoard.getNumPegs() + 
           " pegs remaining.");
      } else {
        JOptionPane.showMessageDialog
          (this, "Game over.  Great job!  There is only " + 
           gameBoard.getNumPegs() + " peg left.");
      }
      System.exit(0);
    }
  }   
  
  /**
   * Implements actionPerformed.
   * @see ActionListener#actionPerformed
   */
  public void actionPerformed(ActionEvent e) {
    JButton b= (JButton) e.getSource();
    
    if (lastClicked != null) {
      gameBoard.move(getRow(lastClicked), getCol(lastClicked), getRow(b), 
                     getCol(b));
      lastClicked = null;
      update();
    } else {
      lastClicked = b;
    }
  }
  
  /**
   * Get the row index for the given button's location
   * in the window.
   * @param b The button to find the coordinates of.
   * @return The row index of the given button.
   */ 
  public int getRow(JButton b) {
    for (int r = 0; r < gameBoard.numRows(); r++) {
      for (int c = 0; c < gameBoard.numCols(); c++) {
        if (b == visuals[r][c]) {
          return r;
        }
      }
    }
    return -1;
  }
  
  /**
   * Get the column index for the given button's location
   * in the window.
   * @param b The button to find the coordinates of.
   * @return The column index of the given button.
   */ 
  public int getCol(JButton b) {
    for (int r = 0; r < gameBoard.numRows(); r++) {
      for (int c = 0; c < gameBoard.numCols(); c++) {
        if (b == visuals[r][c]) {
          return c;
        }
      }
    }
    return -1;
  }
}

