import java.applet.Applet;
import java.awt.*;
import java.awt.event.*;
import java.util.Vector;

class Vector2D extends Vector {
  public int rowsize = 3;
  public Object elementAt(int row, int col) {
    return(this.elementAt(row*rowsize+col));
  }
  public void setElementAt(Object obj, int row, int col) {
    this.setElementAt(obj,row*rowsize+col);
  }
  public int rowOf(int index) {
    return(index/rowsize);
  }
  public int colOf(int index) {
    return(index%rowsize);
  }
  public int rowOf(Object elem) {
    return(indexOf(elem)/rowsize);
  }
  public int colOf(Object elem) {
    return(indexOf(elem)%rowsize);
  }
}

class TTTgame extends Object {
  public static int numlabels = 9;

  private String labels[][] =
     { {"", "", ""},
       {"", "", ""},
       {"", "", ""} };
  private String message = "Have you tried running this as an applet yet?  It is eks' turn.                                                                                 ";
  public String getlabel(int index) {
    return(labels[index/3][index%3]);
  }
  public String getlabel(int row, int col) {
    return(labels[row][col]);
  }
  public String getmessage() {
    return(message);
  }
 
  // These have to do with the game.

  private boolean eksturn = true;
  private int turnsmade = 0;
  private boolean gameover = false;

  public void reset() {
    eksturn = true;
    gameover = false;
    turnsmade = 0;
    for(int row=0;row<3;row++) 
      for(int col=0;col<3;col++) 
        labels[row][col] = "";
    message = "Playing again, huh?  It is eks' turn.";
  }

  private String description(int row, int col) {
    if ((row==0) && (col==0)) return("upper left");
    else if ((row==0) && (col==1)) return("top");
    else if ((row==0) && (col==2)) return("upper right");
    else if ((row==1) && (col==0)) return("left");
    else if ((row==1) && (col==1)) return("center");
    else if ((row==1) && (col==2)) return("right");
    else if ((row==2) && (col==0)) return("lower left");
    else if ((row==2) && (col==1)) return("bottom");
    else if ((row==2) && (col==2)) return("lower right");
    else return("where?!?!?");
  }
  
  private String checkwin() {
    String answer = "";
    String tocheck = "eks";
    while (answer.equals("") && !tocheck.equals("")) {
      if (labels[0][0].equals(tocheck)) {
        if (labels[0][1].equals(tocheck) && (labels[0][2].equals(tocheck))) 
          answer = tocheck;
        if (labels[1][1].equals(tocheck) && (labels[2][2].equals(tocheck))) 
          answer = tocheck;
        if (labels[1][0].equals(tocheck) && (labels[2][0].equals(tocheck))) 
          answer = tocheck;
      } else if (labels[1][2].equals(tocheck)) {
        if (labels[2][2].equals(tocheck) && (labels[0][2].equals(tocheck))) 
          answer = tocheck;
        if (labels[1][1].equals(tocheck) && (labels[1][0].equals(tocheck))) 
          answer = tocheck;
      } else if (labels[2][1].equals(tocheck)) {
        if (labels[2][2].equals(tocheck) && (labels[2][0].equals(tocheck))) 
          answer = tocheck;
        if (labels[1][1].equals(tocheck) && (labels[0][1].equals(tocheck))) 
          answer = tocheck;
      } else if ((labels[0][2].equals(tocheck)) 
              && (labels[1][1].equals(tocheck)) 
              && (labels[2][0].equals(tocheck)) ) 
        answer = tocheck;
      tocheck = tocheck.equals("eks")? "owe" : "";
    }
    return(answer);
  }

  public boolean pressed(int index) {
    // returns true if a refresh is needed.
  
    int row = index/3;
    int col = index%3;

    if (turnsmade==9) gameover = true;
    if (labels[index/3][index%3].equals("")) {
      if (gameover) 
        message = "What are you doing?!  Press 'Reset' to play another game.";
      else {
        String content = eksturn?  "eks" : "owe";
        eksturn = !eksturn;
        labels[row][col] = content;
        turnsmade++;
        String winner = (turnsmade<5)? "" : checkwin();
        if (winner.equals("")) {
          message = (turnsmade==9)?
            "The game is a tie.  Press 'Reset' to play another game."
           :"An "+content+" was placed in the "
           +description(row,col)+".  It is now "
           +(eksturn? "eks'" : "owe's")+" turn.";
        } else {
          message = winner+" is the winner.  Press "
                   +"'Reset' to play another game.";
          gameover = true;
        }
      }
    } else {
      message = gameover? 
        "I said, press 'Reset' to play another game."
      : "That cell is already occupied by "
         + labels[index/3][index%3] + ".  It is still "
         +(eksturn? "eks'" : "owe's")+" turn.";
    }
    return(true);
  }

}

class QuitListener implements ActionListener {
  private static void Quit() {
    System.out.println("Searching for Bobby Fischer, eh?");
    System.exit(0);                     // terminate application normally
  }

  public void actionPerformed(ActionEvent evt) {
    Quit();
  }
}
 
public class TicTacToe extends Applet {

  protected Vector2D buttonlist = new Vector2D();
  protected TTTgame game = new TTTgame();
  protected Label message = new Label();

  private void labelbuttons() {
    for(int lcv=0;lcv<game.numlabels;lcv++) {
      ((Button)(buttonlist.elementAt(lcv))).setLabel(game.getlabel(lcv));
    }    
    message.setText(game.getmessage());
  }

  private class MyListener implements ActionListener {
    public void actionPerformed(ActionEvent evt) {
      Button b = (Button)evt.getSource();
      int index = buttonlist.indexOf(b);
      if (index == 9) {
        // reset game;
        game.reset();
        labelbuttons();
      } else if (game.pressed(index))
        labelbuttons();
    }
  }

  private void makebutton(String name,
                            GridLayout grid,
                            ActionListener l,
                            Panel place) {
    Button button = new Button(name);
    button.addActionListener(l);
    place.add(button);
    buttonlist.addElement(button);
  }

  public void myinit() {
      Panel playfield = new Panel();
      GridLayout grid = new GridLayout(3,3);
      grid.setHgap(10);
      grid.setVgap(10);
      playfield.setLayout(grid);
      MyListener listen = new MyListener();
      makebutton("Buton1",grid,listen,playfield);
      makebutton("Buton2",grid,listen,playfield);
      makebutton("Buton3",grid,listen,playfield);
      makebutton("Buton4",grid,listen,playfield);
      makebutton("Buton5",grid,listen,playfield);
      makebutton("Buton6",grid,listen,playfield);
      makebutton("Buton7",grid,listen,playfield);
      makebutton("Buton8",grid,listen,playfield);
      makebutton("Buton9",grid,listen,playfield);
   
      Panel infobar = new Panel();
      FlowLayout flow = new FlowLayout(FlowLayout.LEFT,20,20);
      infobar.setLayout(flow);
      Button button = new Button("Reset");
      button.addActionListener(listen);
      infobar.add(button);
      buttonlist.addElement(button);
      infobar.add(message);

    setLayout(new BorderLayout());
    add("Center",playfield);
    add("North",infobar);

    labelbuttons();
    setSize(600,1200);
  }

  public TicTacToe() {
    myinit();
  }  

  // Exerything below is for application only.


  // This nested class listens for window close events and handles them:
  private static class WinCloser extends WindowAdapter
  {
    public void windowClosing(WindowEvent e)
    {
      System.out.println("Searching for Bobby Fischer, eh?");
      System.exit(0);                     // terminate application normally
    }
  }

  public static void main(String[] args) {
    Frame mainWindow = new Frame("Wei-Hwa Huang: CS3 Lab 2");
    mainWindow.addWindowListener(new WinCloser());
    mainWindow.setLayout(new BorderLayout());
    mainWindow.add("Center", new TicTacToe());
    Button qbutton = new Button("Quit");
    qbutton.addActionListener(new QuitListener());
    mainWindow.add("South", qbutton);
    mainWindow.pack();
    mainWindow.setSize(800, 400);
    mainWindow.setVisible(true);
  }
}

