import java.awt.*;import java.awt.event.*;import javax.swing.*;import javax.swing.border.*;import javax.swing.event.*;import java.net.*;import java.io.*;/**   UpPanel.java   This class implements top panel of the userinterface. It deals   with the buttons needed to play the game.
   @author Sugiharto Widjaja (Contribution from Toan with testing and debugging)   @version November 30, 2001   */
public class UpPanel extends JPanel implements ActionListener{
   // The start button
   private JButton start;
   // The players' chat messages will be displayed here
   private JTextArea textArea;
   // The button to make the move list visible / invisible
   private JButton moveList;
   // The button to request a pass
   private JButton pass;
   // The button to request a forfeit
   private JButton forfeit;
   // The button to request a take back
   private JButton takeBack;
   // The downPanel panel
   private DownPanel downPanel;
   // The BoardPanel panel
   private BoardPanel boardPanel;
   // The history list window   private HistList histFrame;
   /**         Display the buttons in GridBag layout, and add them to
         action listener
         @param none
         <dt><b>Postcondition:</b><dd
         Buttons will be displayed on the frame. Initially, all them
         will be disabled.
      */

   public UpPanel()   {
      // Setting the layout
      setLayout(new GridBagLayout());
      GridBagConstraints gbc = new GridBagConstraints();
      gbc.insets.top = 5;
      gbc.insets.left = 10;
      gbc.insets.bottom = 5;
      gbc.insets.right = 10;
      // Creating the buttons and add them to action listener
      start = new JButton("Start");
      start.addActionListener(this);
      pass = new JButton("Pass");
      pass.addActionListener(this);
      takeBack = new JButton("Take Back");
      takeBack.addActionListener(this);
      forfeit = new JButton("Forfeit");
      forfeit.addActionListener(this);
      moveList = new JButton("Move List");
      moveList.addActionListener(this);
      // All buttons are initially disabled
      disableButtons();
      gbc.fill = GridBagConstraints.VERTICAL;
      // Add the buttons to UpPanel
      add(start, gbc);
      add(pass, gbc);
      add(takeBack, gbc);
      add(forfeit, gbc);
      add(moveList, gbc);
   }
   public HistList getHisList()
   {
   	  return histFrame;
   }

   /**
         Establishing the communication between UpPanel and DownPanel
         @param thePanel - The DownPanel panel
         <dt><b>Precondition:</b><dd>
         thePanel is a valid DownPanel
         <dt><b>Postcondition:</b><dd>
         Establishing communication between UpPanel and DownPanel.
      */

   public void addDownPanel(DownPanel thePanel)
   {
      downPanel = thePanel;
   }
   /**
         Establishing the communication between UpPanel and BoardPanel
         @param thePanel - The BoardPanel panel
         <dt><b>Precondition:</b><dd>
         thePanel is a valid BoardPanel
         <dt><b>Postcondition:</b><dd>
         Establishing communication between UpPanel and BoardPanel
      */
   public void addBoardPanel(BoardPanel thePanel)
   {
      boardPanel = thePanel;
      histFrame = new HistList();
   }
   /**
         Disabling the start, pass, takeback, forfeit, and moveList buttons
         @param none
         <dt><b>Postcondition:</b><dd>
         All buttons are disabled
         @see enableButtons()
         @see enableStart()
         @see disableStart()
      */

   public void disableButtons()
   {
      disableStart();
      pass.setEnabled(false);
      takeBack.setEnabled(false);
      forfeit.setEnabled(false);
      moveList.setEnabled(false);
   }
   /**
         Enabling the pass, takeback, forfeit, and moveList buttons
         @param none
         <dt><b>Postcondition:</b><dd>
         Pass, takeback, forfeit, and moveList buttons are enabled
         @see disableButtons()
         @see enableStart()
         @see disableStart()
      */

   public void enableButtons()
   {
      pass.setEnabled(true);
      takeBack.setEnabled(true);
      forfeit.setEnabled(true);
      moveList.setEnabled(true);
   }
   /**
         Enabling the start button
         @param none
         <dt><b>Postcondition:</b><dd>
         Start button is enabled
         @see disableStart();
      */

   public void enableStart()
   {
      start.setEnabled(true);
   }
   /**
         Disabling the start button
         @param none
         <dt><b>Postcondition:</b><dd>
         Start button is disabled
         @see enableStart();
      */

   public void disableStart()
   {
      start.setEnabled(false);
   }
   /**
         Performing several tasks depending on the button that is clicked on
         There are five buttons: start, forfeit, takeback,
         pass, and move list. Start button will initialize the data structure
         of the game, and start the game. The forfeit button will let user to
         declare forfeit. The takeback button will let user to negotiate number
         of takebacks with opponent. The pass button will let user to pass on his
         next movel. The move list button, if clicked on, will create a frame of
         history of moves visible.
         @param evt - The action event
         <dt><b>Postcondition:</b><dd>
         Several taks will be performed depending on the button that is clicked on.
      */

   public void actionPerformed(ActionEvent evt)
   {
      Object source = evt.getSource();
      if (source == start)
      {
         boardPanel.startGame();
         boardPanel.repaint();
         enableButtons();
         disableStart();
         // send message to other player that game has started
	     downPanel.sendMsg("09");
      }
      else if (source == forfeit)
	  {
	     // Confirmation of forfeit
		 int selection = JOptionPane.showConfirmDialog(null,
						   "Are you sure you want to forfeit?",
						   "Forfeit Confirmation", JOptionPane.YES_NO_OPTION,
						   JOptionPane.QUESTION_MESSAGE);
		 if (selection == JOptionPane.NO_OPTION)   // No is selected
			;
		 else
		 {
			 boardPanel.stopGame();   // Stop the game
			 boardPanel.losingTrue(); // Losing the game
			 downPanel.sendMsg("08");
			 disableButtons();        // Disable all buttons
			 downPanel.enableAssign(); // Enable assign button is enabled
		 }
	  }
	  else if (source == takeBack)
	  {
	     String num = JOptionPane.showInputDialog("Number of takebacks : ");
	     downPanel.sendMsg("01", num);
	     histFrame.update_t();
	  }
	  else if(source == moveList)
	  {
		 histFrame.show();
	  }
	  else	     ;
	  // check whether is it my turn
	  if (!downPanel.returnTurn())
	     ;
	  else
	  {
	     if (source == pass)
	     {
			 // Confirmation of pass
			 int selection = JOptionPane.showConfirmDialog(null,
							    "Are you sure you want to pass?",
								"Pass Confirmation", JOptionPane.YES_NO_OPTION,
								JOptionPane.QUESTION_MESSAGE);
			 if (selection == JOptionPane.NO_OPTION)
			    ;
			 else
		     {
			    int color = downPanel.getColorRole();
			    boardPanel.move(-1, -1, color);
			    downPanel.sendMsg("10");
			    boardPanel.repaint();
			 }
		 }
      }
   }
   /**
      Returns the text area containing the moves by player who plays black stone.
      @param none
      <dt><b>Precondition:</b><dd>
      The HistList is not null
      @return the text area containing the moves by player who plays black stone.
      */

   public JTextArea getBlackFrame()
   {
	   return (histFrame.getBlack());
   }
   /**
         Returns the text area containing the moves by player who plays white stone.
         @param none
         <dt><b>Precondition:</b><dd>
         The HistList is not null
         @return the text area containing the moves by player who plays white stone.
      */

   public JTextArea getWhiteFrame()
   {
	   return (histFrame.getWhite());
   }
   /**
      Method that will append the coordinate of moves by both players on the text area.
      @param moves - the coordinate of moves
             color - who does the move? Player who plays white stone or player who plays
                     black stone?
      <dt><b>Postcondition:</b><dd>
      The coordinate of moves will be appended to the text area.
      */

   public void appendMoves(String moves, int color)
   {
	   if(color == 0)   // Black player
	      getBlackFrame().append(moves + "\n");
	   else
	      getWhiteFrame().append(moves + "\n");
   }
   /**
      This class deals with the history list window. The history list
      window will be consisted of two text areas. One text area contains
      all moves by player who plays black stone. The other text area for
      all moves by player who playw shite stone. The text areas will have
      both vertical and horizontal scroll bars.
      */

   class HistList extends JFrame
   {
	   // The text area for moves of player who plays black stone
	   private JTextArea black;
	   // The text area for moves of player who plays white stone
	   private JTextArea white;
	   // The scroll pane of black moves
	   private JScrollPane scrollPaneblack;
	   // The scroll pane of white moves
	   private JScrollPane scrollPanewhite;
	   // The scroll bar for black scroll pane	   private JScrollBar wscrollbar;	   // The scroll bar for white scroll pane
	   private JScrollBar bscrollbar;

	   /**
	      Constructor for HistList class
	      This will construct the windows of the history of moves in a seperate frame.
	      Upon the creation of the window, it will read all current moves from the
	      history list in Game class, and will append them to either one of the two text
	      areas.
	      @param none
	      */

	   public HistList()
	   {
		   setSize(200,200);
		   setTitle("History List Window");
		   setResizable(false);
		   Container contentPane = getContentPane();
		   black = new JTextArea(50, 8);
		   white = new JTextArea(40,8);
		   black.setEditable(false);
		   white.setEditable(false);
		   scrollPaneblack = new JScrollPane(black);
		   bscrollbar = scrollPaneblack.getVerticalScrollBar();
		   scrollPanewhite = new JScrollPane(white);
		   wscrollbar = scrollPanewhite.getVerticalScrollBar();
		   contentPane.add(scrollPaneblack, BorderLayout.WEST);
		   contentPane.add(scrollPanewhite, BorderLayout.EAST);
		   Game tempGame = boardPanel.getCurrentGame();
		   int counter = (tempGame.getHistory()).getCounter();		   black.append("    Black");
		   white.append("    White");
		   int i = 0;
		   while (i < counter)
		   {
			   black.append((counter / 2) + "  " + (tempGame.getHistory()).getMoveAt(i) + "\n");
			   i++;
			   if(i < counter)
			   {
				   white.append((counter / 2) + "  " + (tempGame.getHistory()).getMoveAt(i) + "\n");
				   i++;
			   }
		   }
	   }
	   /**
	      Returns the text area designated for moves by player who plays black stone.
	      @param none
	      @return the text area designated for moves by player who plays black stone.
	      */

	   public JTextArea getBlack()
	   {
		   return black;
	   }
       /**
	   	      Returns the text area designated for moves by player who plays white stone.
	   	      @param none
	   	      @return the text area designated for moves by player who plays white stone.
	      */

	   public JTextArea getWhite()
	   {
		   return white;
	   }
	   /**
	      Method to update the move lists on both text areas. This is called whenever
	      a player requests takeback(s). It will first clear out all moves in both
	      text areas, and then it will get all moves from current history list in Game
	      class
	      @param none
	      <dt><b>Precondition:</b><dd>
	      The number of takeback requests does not exceed the length of the history list
	      */

	   public void update_t()
	   {
		   // Clear out the contents of both text areas
		   black.setText("");
		   white.setText("");
		   // Get the current game from BoardPanel class
		   Game tempGame = boardPanel.getCurrentGame();
		   int counter = (tempGame.getHistory()).getCounter();
		   int i = 0;
		   // Append all moves to their corresponding text areas.
		   while (i < counter)
		   {
			   black.append((counter / 2) + "  " + (tempGame.getHistory()).getMoveAt(i) + "\n");
			   i++;
			   if(i < counter)
			   {
				   white.append((counter / 2) + "  " +(tempGame.getHistory()).getMoveAt(i) + "\n");
				   i++;
			   }
		   }
	   }
	   /**
	      This method will update the vertical scroll bars for each scroll panes
	      @param none
	      */

	   public void update_ChatArea()
	   {
		   wscrollbar.setValues(wscrollbar.getMaximum(),
								wscrollbar.getVisibleAmount(),
								wscrollbar.getMinimum(),
								wscrollbar.getMaximum());
		   bscrollbar.setValues(bscrollbar.getMaximum(),
		                        bscrollbar.getVisibleAmount(),
								bscrollbar.getMinimum(),
								bscrollbar.getMaximum());
		}
	}
}

