/* --------------------------------------------------------------------

SolverApplet class

Copyright (c) 1996 by Christopher R. Waterson. All Rights Reserved.
Permission to use, copy, modify, and distribute this software
and its documentation for NON-COMMERCIAL purposes and without
fee is hereby granted provided that this copyright notice
appears in all copies.

File:		SolverApplet.java
Synopsis:	An eight-puzzle solver applet
Author:		Christopher R. Waterson <waterson@eecs.umich.edu>
Created:	27 January 1996
Updated:	Christopher R. Waterson <waterson@eecs.umich.edu>
Last Modified:	31 October 1996

-------------------------------------------------------------------- */

package eightpuzzle;

import java.awt.*;
import java.applet.*;

/**
 * An applet that displays an eight puzzle and the search tree
 * of a process used to solve it.
 */

public class SolverApplet
extends java.applet.Applet {

	/** The layout manager */
	GridBagLayout m_layoutManager;

	// Buttons to control the applet
	Button m_shuffleButton;
	Button m_solveButton;
	Button m_haltButton;

	/** A canvas for the eight puzzle */
	PuzzleCanvas m_eightPuzzleCanvas;

	/** A panel for the search tree */
	SearchTreePanel m_searchTreePanel;

	/**
	 * A solver thread used to solve the puzzle
	 * contained in the PuzzleCanvas
	 */

	Solver m_solver;


	/**
	 * Initialize the eight puzzle applet
	 */

	public void
	init() {
		// Set up the top-level layout
		m_layoutManager = new GridBagLayout();
		setLayout(m_layoutManager);

		// For later...
		GridBagConstraints constraint;

		// The viewer canvases
		Dimension d = size();

		m_eightPuzzleCanvas	= new PuzzleCanvas();
		m_searchTreePanel	= new SearchTreePanel();

		// Create the buttons and canvases
		m_shuffleButton	= new Button("Shuffle");
		m_solveButton	= new Button("Solve");
		m_haltButton	= new Button("Halt");

		// Add the items to the top-level applet layout
		addComponent(m_eightPuzzleCanvas, 0, 0, 6, 6, GridBagConstraints.BOTH, 1, 1);
		addComponent(m_searchTreePanel,   6, 0, 6, 6, GridBagConstraints.BOTH, 1, 1);
		addComponent(m_shuffleButton,     3, 6, 2, 1, GridBagConstraints.NONE, 1, 0);
		addComponent(m_solveButton,       5, 6, 2, 1, GridBagConstraints.NONE, 1, 0);
		addComponent(m_haltButton,        7, 6, 2, 1, GridBagConstraints.NONE, 1, 0);

		// Enable/disable the appropriate UI controls.
		enableUserInterface(true);
	}


	/**
	 * Adds a component to the screen, setting up GridBagConstraints
	 * appropriately
	 */

	private void
	addComponent(Component comp,
							int gridx, int gridy,
							int gridwidth, int gridheight,
							int fill,
							int weightx,
							int weighty) {

		GridBagConstraints constraints = new GridBagConstraints();

		constraints.gridx		= gridx;
		constraints.gridy		= gridy;
		constraints.gridwidth	= gridwidth;
		constraints.gridheight	= gridheight;
		constraints.fill		= fill;
		constraints.weightx     = weightx;
		constraints.weighty     = weighty;

		m_layoutManager.setConstraints(comp, constraints);
		add(comp);
	}



	/**
	 * Starts or re-starts the application
	 */

	public void
	start() {
		// If the solver thread has been suspended,
		// then restart it.
		if (m_solver != null && m_solver.isAlive())
			m_solver.resume();
	}

	/**
	 * Suspends the application's execution
	 */

	public void
	stop() {
		// If the solver thread is running, suspend
		// it.
		if (m_solver != null && m_solver.isAlive())
			m_solver.suspend();
	}


	/**
	 * Handles user input
	 */

	public boolean
	action(Event event, Object arg) {
		if (event.target == m_shuffleButton) {

			// Clicked the shuffle button, so shuffle
			// up the puzzle a bit...
			m_eightPuzzleCanvas.shuffle();

		} else if (event.target == m_solveButton) {

			// Clicked the solve button, so kick off
			// a thread to do just that. Note that the
			// solver takes care of dealing with the UI.
			m_solver = new Solver(this);
			m_solver.start();

		} else if (event.target == m_haltButton) {

			// Clicked the halt button, so halt the
			// solver thread.
			m_solver.stop();
			enableUserInterface(true);

		}

		return true;
	}



	/**
	 * Returns the PuzzleCanvas that belongs to the applet
	 */

	public PuzzleCanvas
	getPuzzleCanvas() {
		return m_eightPuzzleCanvas;
	}


	/**
	 * Returns the SearchTreePanel that belongs to the applet
	 */

	public SearchTreePanel
	getSearchTreePanel() {
		return m_searchTreePanel;
	}


	/**
	 * Enables or disables the user interface controls
	 */

	public void
	enableUserInterface(boolean on) {
		if (on) {
			m_eightPuzzleCanvas.enable();
			m_shuffleButton.enable();
			m_solveButton.enable();
			m_haltButton.disable();
		} else {
			m_eightPuzzleCanvas.disable();
			m_shuffleButton.disable();
			m_solveButton.disable();
			m_haltButton.enable();
		}
	}
}



