/*
 * Maze
 * Copyright (C) 2000  Paul Davis, pdavis@lpccomp.bc.ca
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

import java.util.*;

/**
 * The model for a maze.
 * Known implementations: Maze
 */
public interface MazeModel {

	/**
	 * Bitmap value for all walls (no passages).
	 */
	public final static byte WALLS = 0;
	/**
	 * Bitmap value for an exit in the X+ direction.
	 */
	public final static byte XPL = 01;
	/**
	 * Bitmap value for an exit in the X- direction.
	 */
	public final static byte XMI = 02;
	/**
	 * Bitmap value for an exit in the Y+ direction.
	 */
	public final static byte YPL = 04;
	/**
	 * Bitmap value for an exit in the Y- direction.
	 */
	public final static byte YMI = 010;
	/**
	 * Bitmap value for an exit in the Z+ direction.
	 */
	public final static byte ZPL = 020;
	/**
	 * Bitmap value for an exit in the Z- direction.
	 */
	public final static byte ZMI = 040;
	/**
	 * Bitmap value for an "I've been here" mark.
	 */
	public final static byte MARK = 0100;
	/**
	 * Get the size of the maze.
	 * @return The 3D size of the maze.
	 */
	public Coordinate3D getSize();

	/**
	 * Set an "I've been here" mark in the given cell.
	 * @param position The 3D co-ordinate of the cell.
	 * @param mark True to set a mark, false to remove it.
	 */
	public void setMark(Coordinate3D position, boolean mark);

	/**
	 * Get the contents of a cell.
	 * @param x The x co-ordinate.
	 * @param y The y co-ordinate.
	 * @param z The z co-ordinate.
	 * @return A bitmap containing XPL,XMI etc.
	 */
	public byte grid(int x, int y, int z);

	/**
	 * Get the contents of a cell.
	 * @param c The 3D co-ordinate of the cell.
	 * @return A bitmap containing XPL,XMI etc.
	 */
	public byte grid(Coordinate3D c);

	/**
	 * Set the position of the finish or goal cell.
	 * @param finish The 3D co-ordinate of the cell.
	 */
	public void setFinish(Coordinate3D finish);

	/**
	 * Set a random position for the finish cell.
	 */
	public void setRandomFinish();

	/**
	 * Get the finish cell location.
	 * @return The 3D co-ordinate of the cell.
	 */
	public Coordinate3D getFinish();

	/**
	 * Set the current player co-ordinate.
	 * @param current The 3D co-ordinate of the player in the maze.
	 */
	public void setCurrent(Coordinate3D current);

	/**
	 * Get the current player co-ordinate.
	 * @return The 3D co-ordinate of the player in the maze.
	 */
	public Coordinate3D getCurrent();

	/**
	 * Check if the given cell has an "I've been here" marker.
	 * @param position The 3D co-ordinate of the cell to check.
	 * @return True if a marker has been placed.
	 */
	public boolean isMarked(Coordinate3D position);

	/**
	 * Check and see if movement is possible.
	 * @param current The 3D co-ordinate to start from.
	 * @param direction The direction to go, one of XPL,XMI etc.
	 * @return True if movement possible, false if blocked by a wall.
	 */
	public boolean isOpen(Coordinate3D current,byte direction);

	/**
	 * Solve the maze from a given start position.
	 * @param start The 3D co-ordinate to start from.
	 * @return A Stack of 3D co-ordinates giving the path from
	 *	the given start to the known finish.
	 */
	public Stack solve(Coordinate3D start);

	/**
	 * Add a MazeListener.
	 * An event is fired when the maze is created or when the
	 * finish or current positions change.
	 * @param l A MazeListener to listen for maze changes.
	 */
	public void addMazeListener(MazeListener l);

	/**
	 * Remove a MazeListener.
	 * @param l The MazeListener to remove.
	 */
	public void removeMazeListener(MazeListener l);

}