/*******************************************************************************
 * Copyright (c) 2001, 2006 Mathew Nelson and Robocode contributors
 * All rights reserved. This program and the accompanying materials 
 * are made available under the terms of the Common Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.robocode.net/license/CPLv1.0.html
 * 
 * Contributors:
 *     Mathew Nelson - initial API and implementation
 *******************************************************************************/
package robocode.dialog;


import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.io.*;
import robocode.battleview.*;
import robocode.manager.*;
import robocode.util.*;


/**
 * This type was generated by a SmartGuide.
 */
public class RobocodeFrame extends JFrame {
	EventHandler eventHandler = new EventHandler();

	private RobocodeMenuBar robocodeMenuBar = null;
	
	private JPanel robocodeContentPane = null;
	private JPanel statusBarPanel = null;
	private JLabel statusLabel = null;
	private BattleView battleView;
	public String version = null;
	public java.lang.Thread appThread;
	private JScrollPane robotButtonsScrollPane = null;
	private JPanel mainPanel = null;
	private JPanel battleViewPanel = null;
	private java.lang.String battleFilename = null;
	private JPanel robotButtonsPanel = null;
	private JToolBar toolBar = null;
	private JButton pauseResumeButton = null;
	private JButton stopButton = null;
	private boolean iconified = false;
	private RobocodeManager manager = null;
	private boolean exitOnClose = false;
	
	private boolean slave = false;

	class EventHandler implements java.awt.event.KeyListener, java.awt.event.ActionListener, java.awt.event.ComponentListener, java.awt.event.ContainerListener, java.awt.event.WindowListener {
		public void actionPerformed(java.awt.event.ActionEvent e) {
			if (e.getSource() == RobocodeFrame.this.getPauseResumeButton()) { 
				pauseResumeButtonActionPerformed();
			} else if (e.getSource() == RobocodeFrame.this.getStopButton()) {
				stopButtonActionPerformed();
			}
		}
		;
		public void componentHidden(java.awt.event.ComponentEvent e) {}
		;
		public void componentMoved(java.awt.event.ComponentEvent e) {}
		;
		public void componentResized(java.awt.event.ComponentEvent e) {
			if (e.getSource() == RobocodeFrame.this.getBattleView()) { 
				RobocodeFrame.this.battleViewResized();
			}
			if (e.getSource() == RobocodeFrame.this.getBattleViewPanel()) { 
				RobocodeFrame.this.battleViewPanelResized();
			}
		}
		;
		public void componentShown(java.awt.event.ComponentEvent e) {}
		;
		public void componentRemoved(java.awt.event.ContainerEvent e) {
			if (e.getChild() instanceof RobotButton) {
				((RobotButton) e.getChild()).cleanup();
			}
		}
		;
		public void componentAdded(java.awt.event.ContainerEvent e) {}
		;

		public void keyPressed(KeyEvent e) {
			// log("Key pressed: " + e.getKeyCode() + "," + e.getModifiers());
			if (e.getKeyCode() == KeyEvent.VK_F4 && e.getModifiers() == KeyEvent.ALT_MASK) {
				;
			}
			// log("close?");
		}
		;
		public void keyReleased(KeyEvent e) {}
		;
		public void keyTyped(KeyEvent e) {}
		;
		
		public void windowActivated(java.awt.event.WindowEvent e) {}
		;
		public void windowClosed(java.awt.event.WindowEvent e) {
			if (exitOnClose) {
				System.exit(0);
			}
		}
		;
		public void windowClosing(java.awt.event.WindowEvent e) {
			exitOnClose = true;
			if (manager.getListener() != null) {
				Utils.message("If you wish to exit Robocode, please exit the program controlling it.");
				exitOnClose = false;
				return;
			}
			if (windowManager.closeRobocodeEditor()) {
				Utils.saveWindowPositions();
				dispose();
			}
		}
		;
		public void windowDeactivated(java.awt.event.WindowEvent e) {}
		;
		public void windowDeiconified(java.awt.event.WindowEvent e) {
			setIconified(false);
		}
		;
		public void windowIconified(java.awt.event.WindowEvent e) {
			setIconified(true);
		}
		;
		public void windowOpened(java.awt.event.WindowEvent e) {}
		;

	}


	;
	private WindowManager windowManager = null;

	/**
	 * RobocodeFrame constructor
	 */
	public RobocodeFrame(RobocodeManager manager) {
		super();
		this.windowManager = manager.getWindowManager();
		this.manager = manager;
		manager.getImageManager().initialize(this);
		initialize();
	}

	/**
	 * Insert the method's description here.
	 * Creation date: (8/24/2001 11:15:48 AM)
	 */
	public void addRobotButton(JButton b) {
		getRobotButtonsPanel().add(b);
		b.setVisible(true);
		getRobotButtonsPanel().validate();
	}

	/**
	 * Comment
	 */
	private void battleViewResized() {
		battleView.setInitialized(false);
		battleView.repaint();
		return;
	}

	/**
	 * Rather than use a layout manager for the battleview panel,
	 * we just calculate the proper aspect ratio and set the battleview's
	 * size.
	 * We could use a layout manager if someone wants to write one...
	 */
	public void battleViewPanelResized() {
		Dimension preferredSize = getBattleView().getPreferredSize();

		battleView.setLocation(0, 0);
		if (getBattleViewPanel().getWidth() >= preferredSize.width
				&& getBattleViewPanel().getHeight() >= preferredSize.height) {
			battleView.setSize(battleView.getPreferredSize());
		} else {
			double widthRatio = (double) getBattleViewPanel().getWidth() / (double) preferredSize.width;
			double heightRatio = (double) getBattleViewPanel().getHeight() / (double) preferredSize.height;
			double scale = Math.min(widthRatio, heightRatio);

			battleView.setSize((int) (scale * preferredSize.width), (int) (scale * preferredSize.height));
		}
		return;
	}

	/**
	 * Insert the method's description here.
	 * Creation date: (8/24/2001 11:15:08 AM)
	 */
	public void clearRobotButtons() {
		getRobotButtonsPanel().removeAll();
		getRobotButtonsPanel().repaint();
	}

	/**
	 * Insert the method's description here.
	 * Creation date: (1/22/2001 11:51:54 AM)
	 * @return java.lang.String
	 */
	public java.lang.String getBattleFilename() {
		return battleFilename;
	}

	/**
	 * Return the BattleView.
	 * @return robocode.BattleView
	 */
	public BattleView getBattleView() {
		if (battleView == null) {
			try {
				battleView = new BattleView(manager, this, manager.getImageManager());
				battleView.setName("battleView");
				battleView.setPreferredSize(new Dimension(800, 600));
				battleView.addComponentListener(eventHandler);
			} catch (java.lang.Throwable e) {
				log(e);
			}
		}
		return battleView;
	}

	/**
	 * Return the MainPanel (which contains the BattleView and the robot buttons)
	 * @return javax.swing.JPanel
	 */
	private javax.swing.JPanel getMainPanel() {
		if (mainPanel == null) {
			try {
				mainPanel = new javax.swing.JPanel();
				mainPanel.setName("JMainPanel");
				mainPanel.setLayout(new java.awt.BorderLayout());
				mainPanel.add(getRobotButtonsScrollPane(), "East");
				mainPanel.add(getBattleViewPanel(), "Center");
			} catch (java.lang.Throwable e) {
				log(e);
			}
		}
		return mainPanel;
	}

	/**
	 * Return the BattleViewMainPanel
	 *  (which contains the BattleView and a spacer)
	 * @return javax.swing.JPanel
	 */
	private javax.swing.JPanel getBattleViewPanel() {
		if (battleViewPanel == null) {
			try {
				battleViewPanel = new javax.swing.JPanel();
				battleViewPanel.setName("BattleViewPanel");
				battleViewPanel.setLayout(null); //
				// new BoxLayout(battleViewPanel,BoxLayout.Y_AXIS));
			
				battleViewPanel.add(getBattleView());
				battleViewPanel.setPreferredSize(getBattleView().getPreferredSize());
				battleViewPanel.addComponentListener(eventHandler);
			} catch (java.lang.Throwable e) {
				log(e);
			}
		}
		return battleViewPanel;
	}

	/**
	 * Return the pauseResumeButton
	 * @return javax.swing.JButton
	 */
	public javax.swing.JButton getPauseResumeButton() {
		if (pauseResumeButton == null) {
			try {
				pauseResumeButton = new javax.swing.JButton();
				pauseResumeButton.setName("PauseResumeButton");
				pauseResumeButton.setText("Pause");
				pauseResumeButton.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
				pauseResumeButton.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
				pauseResumeButton.setIcon(null);
				pauseResumeButton.addActionListener(eventHandler);
			} catch (java.lang.Throwable e) {
				log(e);
			}
		}
		return pauseResumeButton;
	}

	/**
	 * Return the JFrameContentPane.
	 * @return javax.swing.JPanel
	 */
	public JPanel getRobocodeContentPane() {
		if (robocodeContentPane == null) {
			try {
				robocodeContentPane = new javax.swing.JPanel();
				robocodeContentPane.setName("RobocodeContentPane");
				robocodeContentPane.setLayout(new java.awt.BorderLayout());
				// robocodeContentPane.add(getStatusBarPanel(), "South");
				robocodeContentPane.add(getToolBar(), "South");
				robocodeContentPane.add(getMainPanel(), "Center");
			} catch (java.lang.Throwable e) {
				log(e);
			}
		}
		return robocodeContentPane;
	}

	/**
	 * Return the menu bar.
	 * @return javax.swing.JMenuBar
	 */
	public RobocodeMenuBar getRobocodeMenuBar() {
		if (robocodeMenuBar == null) {
			try {
				robocodeMenuBar = new RobocodeMenuBar(manager, this);
				robocodeMenuBar.setName("RobocodeMenuBar");
			} catch (java.lang.Throwable e) {
				log(e);
			}
		}
		return robocodeMenuBar;
	}

	/**
	 * Return the robotButtons panel.
	 * @return javax.swing.JPanel
	 */
	private javax.swing.JPanel getRobotButtonsPanel() {
		if (robotButtonsPanel == null) {
			try {
				robotButtonsPanel = new javax.swing.JPanel();
				robotButtonsPanel.setName("robotButtonsPanel");
				robotButtonsPanel.setLayout(new javax.swing.BoxLayout(robotButtonsPanel, javax.swing.BoxLayout.Y_AXIS));
				// robotButtonsPanel.setLocation(0, 0);
				robotButtonsPanel.addContainerListener(eventHandler);
			} catch (java.lang.Throwable e) {
				log(e);
			}
		}
		return robotButtonsPanel;
	}

	/**
	 * Return the robotButtonsScrollPane
	 * @return javax.swing.JScrollPane
	 */
	private javax.swing.JScrollPane getRobotButtonsScrollPane() {
		if (robotButtonsScrollPane == null) {
			try {
				robotButtonsScrollPane = new javax.swing.JScrollPane();
				robotButtonsScrollPane.setName("robotButtonsScrollPane");
				robotButtonsScrollPane.setAutoscrolls(false);
				robotButtonsScrollPane.setVerticalScrollBarPolicy(javax.swing.JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
				robotButtonsScrollPane.setHorizontalScrollBarPolicy(javax.swing.JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
				robotButtonsScrollPane.setAlignmentY(java.awt.Component.TOP_ALIGNMENT);
				robotButtonsScrollPane.setMaximumSize(new java.awt.Dimension(113, 32767));
				robotButtonsScrollPane.setPreferredSize(new java.awt.Dimension(113, 28));
				robotButtonsScrollPane.setAlignmentX(java.awt.Component.CENTER_ALIGNMENT);
				robotButtonsScrollPane.setMinimumSize(new java.awt.Dimension(113, 53));
				robotButtonsScrollPane.setViewportView(getRobotButtonsPanel());
			} catch (java.lang.Throwable e) {
				log(e);
			}
		}
		return robotButtonsScrollPane;
	}

	/**
	 * Return the StatusMsg1 property value.
	 * @return javax.swing.JLabel
	 */
	public javax.swing.JLabel getStatusLabel() {
		if (statusLabel == null) {
			try {
				statusLabel = new javax.swing.JLabel();
				statusLabel.setName("StatusMsg1");
				// statusLabel.setBorder(new javax.swing.border.EtchedBorder());
				statusLabel.setText("");
			} catch (java.lang.Throwable e) {
				log(e);
			}
		}
		return statusLabel;
	}

	/**
	 * Return the pauseResumeButton
	 * @return javax.swing.JButton
	 */
	public javax.swing.JButton getStopButton() {
		if (stopButton == null) {
			try {
				stopButton = new javax.swing.JButton();
				stopButton.setName("StopButton");
				stopButton.setText("Stop");
				stopButton.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
				stopButton.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
				stopButton.setIcon(null);
				stopButton.addActionListener(eventHandler);
			} catch (java.lang.Throwable e) {
				log(e);
			}
		}
		return stopButton;
	}

	/**
	 * Return the toolBar.
	 * @return javax.swing.JToolBar
	 */
	private javax.swing.JToolBar getToolBar() {
		if (toolBar == null) {
			try {
				toolBar = new javax.swing.JToolBar();
				toolBar.setName("toolBar");
				// toolBar.setLayout(new BorderLayout());
				toolBar.add(getPauseResumeButton()); // ,BorderLayout.WEST);
				toolBar.add(getStopButton()); // ,BorderLayout.WEST);
				toolBar.add(new JLabel(" "));
				toolBar.add(getStatusLabel());
				Utils.setDefaultStatusLabel(getStatusLabel());	
			} catch (java.lang.Throwable e) {
				log(e);
			}
		}
		return toolBar;
	}

	/**
	 * Initialize the class.
	 */
	private void initialize() {
		try {
			setName("RobocodeFrame");
			setSize(500, 500);
			setDefaultCloseOperation(javax.swing.WindowConstants.DO_NOTHING_ON_CLOSE);
			setTitle("Robocode");
			setIconImage(Toolkit.getDefaultToolkit().getImage(getClass().getResource("/resources/icons/icon.jpg")));
			setResizable(true);
			setContentPane(getRobocodeContentPane());
			setJMenuBar(getRobocodeMenuBar());
			addKeyListener(eventHandler);
			addWindowListener(eventHandler);
			setVisible(false);
			if (manager.isSlave()) {
				getRobocodeMenuBar().getBattleMenu().setEnabled(false);
				getRobocodeMenuBar().getRobotMenu().setEnabled(false);
				getStopButton().setEnabled(false);
				getPauseResumeButton().setEnabled(false);
			}
		} catch (java.lang.Throwable e) {
			log(e);
		}
	}

	/**
	 * Insert the method's description here.
	 * Creation date: (1/18/2001 3:43:41 PM)
	 */
	public void loadVersionFile() {
		String versionString = null;

		try {
			BufferedReader in = new BufferedReader(new FileReader(new File(Constants.cwd(), "versions.txt")));

			versionString = in.readLine();
			while (versionString != null && !versionString.substring(0, 8).equalsIgnoreCase("Version ")) {
				versionString = in.readLine();
			}
		} catch (FileNotFoundException e) {
			log("No version.txt file.");
			versionString = "unknown";

		} catch (IOException e) {
			log("IO Exception reading version.txt" + e);
			versionString = "unknown";
		}

		this.version = "";
		if (versionString != null) {
			try {
				this.version = versionString.substring(8);
			} catch (Exception e) {}
		} else {
			versionString = "unknown";
		}

	}

	/**
	 * Insert the method's description here.
	 * Creation date: (8/22/2001 1:41:21 PM)
	 * @param e java.lang.Exception
	 */
	public void log(String s) {
		Utils.log(s);
	}

	/**
	 * Insert the method's description here.
	 * Creation date: (8/22/2001 1:41:21 PM)
	 * @param e java.lang.Exception
	 */
	public void log(Throwable e) {
		Utils.log(e);
	}

	/**
	 * Comment
	 */
	public void pauseResumeButtonActionPerformed() {
		if (getPauseResumeButton().getText().equals("Pause")) {
			getPauseResumeButton().setText("Resume");
			manager.getBattleManager().pauseBattle();
		} else if (getPauseResumeButton().getText().equals("Resume")) {
			getPauseResumeButton().setText("Pause");
			manager.getBattleManager().resumeBattle();
		}
		return;
	}

	/**
	 * Insert the method's description here.
	 * Creation date: (9/3/2001 5:14:06 PM)
	 */
	public void sizeToPreferred() {
		Utils.packCenterShow(this);

		/*
		 Dimension oldSize = getSize();
		 
		 pack();
		 
		 Dimension d = getPreferredSize();
		 if (d.equals(oldSize) && isVisible())
		 return;

		 Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
		 if (d.width > screenSize.width - 20)
		 d.width = screenSize.width - 20;
		 if (d.height > screenSize.height - 20)
		 d.height = screenSize.height - 20;

		 int l = (screenSize.width - d.width) / 2;
		 int t = (screenSize.height - d.height) / 2;
		 setLocation(l,t);

		 pack();

		 d = getSize();

		 if (d.width > screenSize.width - 20)
		 d.width = screenSize.width - 20;
		 if (d.height > screenSize.height - 20)
		 d.height = screenSize.height - 20;

		 setSize(d);

		 // An extra call to setVisible to fix a bug in some JREs with menus
		 setVisible(true);
		 */
	}

	/**
	 * Comment
	 */
	public void stopButtonActionPerformed() {
		windowManager.getManager().getBattleManager().stop(true);
		return;
	}

	/**
	 * Gets the iconified.
	 * @return Returns a boolean
	 */
	public boolean isIconified() {
		return iconified;
	}

	/**
	 * Sets the iconified.
	 * @param iconified The iconified to set
	 */
	public void setIconified(boolean iconified) {
		this.iconified = iconified;
	}

}
