package gizmoball.ui;

import gizmoball.xml.GizmoballReader;
import gizmoball.xml.GizmoballWriter;

import java.awt.event.KeyListener;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.io.File;
import java.io.IOException;

/**
 * The abstract base class for all control interfaces for the
 * the UI.  AbstractInteractionModes are responsible for handling
 * keypresses, mouse clicks, and all other interface-related
 * interactions. <p>
 * 
 * Subclasses of AbstractInteractionMode will implement the various
 * methods to extend or limit the options available to the user in each
 * mode. <p>
 * 
 * Keypresses are handled in a similar manner to that used in
 * staffui.MagicKeyListener. <p>
 * 
 * @author Albert Leung
 * @version 1.0
 * 
 */

abstract public class AbstractInteractionMode 
	implements MouseListener, MouseMotionListener, KeyListener {

	private AbstractGameBoardComponent gameboardComponent;

	public AbstractInteractionMode(AbstractGameBoardComponent component) {
		this.gameboardComponent = component;
	}

	/**
	 * Loads a gizmoball board from a file.
	 * 
	 * @param file a file containing a gizmoball board
	 * @return if the load was successful
	 * 
	 */
	public boolean load(File file) {
		try {
			gameboardComponent.setGameBoard(GizmoballReader.load(file));
		}
		catch (IOException e) {
			return false;
		}
		return true;
	}

	/**
	 * Saves a gizmoball board to a file.
	 * 
	 * @param file a file to which to export the current board
	 * @return if the save was successful
	 * 
	 */
	public boolean save(File file) {
		try {
			GizmoballWriter.save(file, gameboardComponent.getGameBoard());
		}
		catch (IOException e) {
			return false;
		}
		return true;
	}

	/**
	 * Undoes the last change made in the editor.
	 *
	 */
	abstract public void undo();

	/**
	 * Sets the snap-to-grid option for gizmo placement onto
	 * the board.  When activated, gizmos moved over the board
	 * area will fall onto L by L squares, as is a requirement
	 * of the editor.
	 * 
	 * @param value a boolean indicating whether snap to grid should
	 * be active
	 * 
	 */
	abstract public void setSnapToGrid(boolean value);

	/**
	 * Sets the visibility of incoming connections (connections
	 * to gizmos that trigger the gizmo in focus).  When activated,
	 * directional arrows will be drawn between the selected gizmo
	 * and gizmos that trigger it.
	 * 
	 * @param value a boolean indicating whether incoming connections
	 * should be visible
	 * 
	 */
	abstract public void setShowIncomingConnections(boolean value);
	
	/**
	 * Sets the visibility of outgoing connections (connections
	 * to gizmos triggered by the gizmo in focus).  When activated,
	 * directional arrows will be drawn between the selected gizmo
	 * and gizmos that are triggered by it.
	 * 
	 * @param value a boolean indicating whether outgoing connections
	 * should be visible
	 * 
	 */
	abstract public void setShowOutgoingConnections(boolean value);
	
	/**
	 * Accessor for the gameboard component this interaction mode
	 * is monitoring.
	 * 
	 * @return the gameboard component for the current interaction
	 * mode
	 * 
	 */
	public AbstractGameBoardComponent getGameBoardComponent() {
		return gameboardComponent;
	}

	/**
	 * Mutator for the gameboard component this interaction mode
	 * is monitoring.
	 * 
	 * @param component the new component to set as the gameboard
	 * component for this interaction mode
	 */
	public void setGameBoardComponent(AbstractGameBoardComponent component) {
		gameboardComponent = component;
	}

}
