import java.util.Set;
import java.util.HashMap;
import java.util.Scanner;

/**
 * Class Room - a room in an adventure game.
 *
 * This class is part of the "World of Zuul" application. 
 * "World of Zuul" is a very simple, text based adventure game.  
 *
 * A "Room" represents one location in the scenery of the game.  It is 
 * connected to other rooms via exits.  For each existing exit, the room 
 * stores a reference to the neighboring room.
 * 
 * @author  Michael Kolling and David J. Barnes
 * modified by Andrew Harrington to use FileUtil and ResourceUtil,
 * and to take all data from a file.
 * @version 2018.09.20
 */

public class Room 
{
    private String description;
    private HashMap<String, Room> exits; // stores exits of this room.

    /**
     * Create a room, given its description. Initially, it has
     * no exits. Description is something like "a kitchen" or
     * "an open court yard\nwith flowers all around".
     * @param description The room's description.
     */
    public Room(String description) 
    {
        this.description = description;
        exits = new HashMap<String, Room>(); // added to later
    }
    
    /**
     * Create rooms and their interconnections by taking room names, exit data
     * and descriptions from a file Scanner, and return a map of room names
     * to rooms.  File format for each room:  <br>
     * First line:  room name (one word) <br>
     * Second line: pairs of exit direction and neighbor room name  <br>
     * Remaining paragraph: room description, blank line terminated 
     * @param in is the Scanner delivering all the room data
     * @return A map of room names to rooms
     */
    public static HashMap<String, Room> createRooms(Scanner in)
    {
       // Map to return
       HashMap<String, Room> rooms = new HashMap<String, Room>();
       
       // temporary Map to delay recording exits until all rooms exist
       HashMap<String, String> exitStrings = new HashMap<String, String>();
       
       while (in.hasNext()) {
           String name = FileUtil.getNonCommentLine(in);
           String exitPairs = FileUtil.getNonCommentLine(in);
           String description = FileUtil.readParagraph(in);
           rooms.put(name, new Room(description));
           exitStrings.put(name, exitPairs);
       }
       in.close(); 
       
       // need rooms before you can map exits
       // go back and use exitPairs to map exits:
       for (String name : rooms.keySet()) {
           Room room = rooms.get(name);
           Scanner lineIn = new Scanner(exitStrings.get(name));
           // extract direction and neighbor pairs
           while (lineIn.hasNext()) {
               String direction = lineIn.next();
               String neighbor = lineIn.next();
               room.setExit(direction, rooms.get(neighbor));
           }
       }
       return rooms;            
    }

    /**
     * Define an exit from this room.
     * @param direction The direction of the exit.
     * @param neighbor  The room to which the exit leads.
     */
    public void setExit(String direction, Room neighbor) 
    {
        exits.put(direction, neighbor);
    }

    /**
     * @return The short description of the room
     * (the one that was defined in the constructor).
     */
    public String getShortDescription()
    {
        return description;
    }

    /**
     * Return a description of the room in the form:
     *     You are in the kitchen.
     *     Exits: north west
     * @return A long description of this room
     */
    public String getLongDescription()
    {
        return "You are " + description + "\n" + getExitString();
    }

    /**
     * Return a string describing the room's exits, for example
     * "Exits: north west".
     * @return Details of the room's exits.
     */
    private String getExitString()
    {
        String returnString = "Exits:";
        Set<String> keys = exits.keySet();
        for(String exit : keys) {
            returnString += " " + exit;
        }
        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.
     * @param direction The exit's direction.
     * @return The room in the given direction.
     */
    public Room getExit(String direction) 
    {
        return exits.get(direction);
    }
}

