import java.util.Vector;

/**
 * <b>Don't panic! You don't have to understand the implementation of
 * this class; just see the documentation of method
 * <code>moveToDirection</code></b>.<p>Class <code>Room</code>
 * describes a room that may contain some objects and that may be
 * connected to other rooms by doors. The implementation of the class
 * is rather complicated.  */
public class Room {
    String name;
    Room neighbours[];
    Vector containedObjects;
    
    /**
     * Constructs a new room.
     * @param name	The name of the room.  May be any string.
     */
    public Room(String name) {
	this.name = name;
	neighbours = new Room[4];
	containedObjects = new Vector();
    }

    /**
     * Connects two rooms.
     * @param other	the other room that is connected to this room.
     * @param direction the <a
     * href="Robot.html#direction">direction</a> of the connection.  */
    public void connect(Room other, int direction) {
	neighbours[direction%4] = other;
	other.neighbours[(direction + 2) % 4] = this;
    }

    /**
     * Is this room connected to another room in the given <a
     * href="Robot.html#direction">direction</a>?
     * @param direction the <a
     * href="Robot.html#direction">direction</a> of the connection.
     * @return <code>true</code> if there is door to another room in
     * the given <a href="Robot.html#direction">direction</a> and
     * <code>false</code> if there is no such door.  */
    public boolean possibleDirection(int direction) {
	return neighbours[direction%4] != null;
    }

    /**
     * Inserts an object to a room. The room may contain many objects, for
     * instance, robots.
     * @param item the object that we insert to this room.  */
    public void addObject(Object item) {
	containedObjects.addElement(item);
    }

    /**
     * Removes an object from a room.
     * @param item the object that we remove from this room.
     * @return <code>true</code> if the room contained the given
     * object and <code>false</code> if it did not.  */
    public boolean removeObject(Object item) {
	return containedObjects.removeElement(item);
    }

    /**
     * Does this room contain the given object?
     * @param item the object that we check.
     * @return <code>true</code> if the room contained the given
     * object and <code>false</code> if it did not.
     */
    public boolean containsObject(Object item) {
	return containedObjects.contains(item);
    }

    /**
     * Retrieves the n'th object in this room.
     * @param index the index of the object.
     * @return the object if the room contained enough objects
     * and <code>null</code> if it did not.
     */
    public Object getObjectAt(int index) {
	if (containedObjects.size() <= index) {
	    return null;
	} else {
	    return containedObjects.elementAt(index);
	}
    }

    /**
     * Tries to move a robot to the given <a
     * href="Robot.html#direction">direction</a>. Note that the robot
     * must initially be in this room and there must be a connection
     * to another room in the given <a
     * href="Robot.html#direction">direction</a>.
     * @param robot	the robot to be moved
     * @param direction the <a
     * href="Robot.html#direction">direction</a> of the move
     * @return <code>true</code> if the move was possible and
     * <code>false</code> otherwise.  */

    public boolean moveToDirection(Robot robot, int direction) {
	if (containsObject(robot) && neighbours[direction%4] != null) {
	    removeObject(robot);
	    Room next = neighbours[direction%4];
	    next.addObject(robot);
	    robot.setRoom(next);
	    return true;
	} else {
	    return false;
	}
    }

    /**
     * Redefine the predefined <code>toString</code> method.
     * @return a string describing this room
     */
    public String toString() {
	return "Room(" + name + ")";
    }
}
