package edu.ohio.cs450.assignment4;

import java.util.Set;
import java.util.HashMap;
import java.util.ArrayList;
import java.util.Iterator;

/**
 * "Room" represents one location in the scenery of the game.  It is
 * connected to at most four other rooms via exits.  The exits are labeled
 * north, east, south, west.  For each direction, the room stores a reference
 * to the neighbouring room, or null if there is no exit in that direction.
 */
public enum Room implements Inventory{
	GARDEN("garden", "/edu/ohio/cs450/assignment4/garden.png"),
	FOYER("foyer", "/edu/ohio/cs450/assignment4/foyer.png"),
	BALLROOM("ballroom", "/edu/ohio/cs450/assignment4/ballroom.png"),
	PARLOR("parlor", "/edu/ohio/cs450/assignment4/parlor.png"),
	GREATHALL("great hall", "/edu/ohio/cs450/assignment4/greatHall.png"),
	KITCHEN("kitchen", "/edu/ohio/cs450/assignment4/kitchen.png"),
	TRANSPORTERROOM("transporter room", "/edu/ohio/cs450/assignment4/transporterRoom.png"),
	HALLWAY("hallway", "/edu/ohio/cs450/assignment4/hallway.png"),
	LIBRARY("library", "/edu/ohio/cs450/assignment4/library.png"),
	STUDY("study", "/edu/ohio/cs450/assignment4/study.png"),
	DRAWINGROOM("drawing room", "/edu/ohio/cs450/assignment4/drawingRoom.png"),
	GUESTROOM("guest room", "/edu/ohio/cs450/assignment4/guestRoom.png"),
	BATHROOM("bathroom", "/edu/ohio/cs450/assignment4/bathroom.png"),
	BEDROOM("bedroom", "/edu/ohio/cs450/assignment4/bedroom.png"),
	CELLAR("cellar", "/edu/ohio/cs450/assignment4/cellar.png"),
	DUNGEON("dungeon", "/edu/ohio/cs450/assignment4/dungeon.png");

	private String description;
	private HashMap exits;			// stores exits in the room
	private ArrayList<Item> items;	// stores items in the room
	private String imageName;

	/**
	 * Create a room described "description". Initially, it has no exits.
	 * "description" is something like "a Stocker lab 107" or "an open yard".
	 */
	private Room(String description, String imageName){
		this.description = description;
		this.exits = new HashMap();
		this.items = new ArrayList<Item>();
		this.imageName = imageName;
	}

	/**
	 * Return the description of the room defined in the constructor.
	 * @return this.description
	 */
	public String shortDescription(){
		return(this.description);
	}

	/**
	 * Return a long description of this room, on the form:
	 *     You are in the lab.
	 * @return a verbose description
	 */
	public String longDescription(){
		return("You are in the " + this.description + ".");
	}

	/**
	 * Define the exits of this room.  Every direction either leads to
	 * another room or is null (no exit there).
	 * @param north the Room to the north
	 * @param east the Room to the east
	 * @param south the Room to the south
	 * @param west the Room to the west
	 */
	public void setExits(Room north, Room east, Room south, Room west){
		if(north != null){
			this.exits.put("north", north);
		}
		if(east != null){
			this.exits.put("east", east);
		}
		if(south != null){
			this.exits.put("south", south);
		}
		if(west != null){
			this.exits.put("west", west);
		}

		return;
	}

	/**
	 * Return a string describing the room's exits, for example
	 * "Exits: north west ".
	 * @return a string listing of exit names
	 */
	public String exitString(){
		String returnString = "Exits:";
		Set keys = this.exits.keySet();

		for(Iterator iter = keys.iterator(); iter.hasNext();){
			returnString += " " + iter.next();
		}

		return(returnString);
	}

	/**
	 * Return the room that is reached if we go from this room in direction
	 * "direction". If there is no room in that direction, return null.
	 */
	public Room nextRoom(String direction){
		return((Room)this.exits.get(direction));
	}

	//Interface implementations
	/**
	 * Returns an Item from the inventory
	 * @param itemName the name of the Item to return
	 * @return if inventory contains an item with the description itemName, returns that item; otherwise returns null
	 */
	public Item getItem(String itemName){
		for(Iterator iter = this.items.iterator(); iter.hasNext();){
			Item item = ((Item)iter.next());
			if(item.getDescription().equals(itemName)){
				return(item);
			}
		}
		return(null);
	}

	/**
	 *
	 * @param item
	 * @return
	 */
	public boolean containsItem(String item){
		if(!this.items.isEmpty()){
			for(Iterator iter = this.items.iterator(); iter.hasNext();){
				if(((Item)iter.next()).getDescription().equals(item)){
					return(true);
				}
			}
		}
		return(false);
	}

	/**
	 * Accessor to return Item weight
	 * @param itemName the name of the Item to return the weight for
	 * @return the weight of itemName
	 */
	public int getItemWeight(String itemName){
		return(this.getItem(itemName).getWeight());
	}

	/**
	 * Accessor to return the total weight of all Items in inventory.
	 * @return The total weight of the current inventory.
	 * @author CAH
	 */
	public int getInventoryWeight(){
		int total = 0;

		if(!this.items.isEmpty()){
			for(Iterator iter = this.items.iterator(); iter.hasNext();){
				total += ((Item)iter.next()).getWeight();
			}
		}

		return(total);
	}

	/**
	 * Returns whether or not an Item can be picked up.
	 * @param itemName the description of the Item
	 * @return whether or not the Item can be picked up
	 */
	public boolean canPickUp(String itemName){
		return(this.getItem(itemName).canPickUp());
	}

	/**
	 * Adds an item to the inventory.
	 * @param the Item to add
	 */
	public void addItem(Item item){
		if(item != null){
			this.items.add(item);
		}

		return;
	}

	/**
	 * Removes an item from the inventory and returns it.
	 * @param the description of the Item to remove
	 * @return the item removed
	 */
	public Item removeItem(String itemName){
		int index = this.items.indexOf(this.getItem(itemName));

		return(this.items.remove(index));
	}

	/**
	 * Returns a description of the items in the inventory, e.g.:
	 * "Items: [key] [wine bottle] [hat]"
	 * @return a bracketed string list of Item descriptions
	 */
	public String itemsString(){
		String returnString = "Items:";
		if(this.items.isEmpty()){
			returnString += " <none>";
		}else{
			for(Iterator iter = this.items.iterator(); iter.hasNext();){
				returnString += " [" + ((Item)iter.next()).getDescription() + "]";
			}
		}

		return(returnString);
	}

	public String getImageName(){
		return(imageName);
	}
}
