/**
 *  This class is the main class of the "World of Zuul" application. 
 *  "World of Zuul" is a very simple, text based adventure game.  Users 
 *  can walk around some scenery. That's all. It should really be extended 
 *  to make it more interesting!
 * 
 *  To play this game, create an instance of this class and call the "play"
 *  method.
 * 
 *  This main class creates and initialises all the others: it creates all
 *  rooms, creates the parser and starts the game.  It also evaluates and
 *  executes the commands that the parser returns.
 * 
 * ---------------------------------------------------------------------------
 * ---------------------------------------------------------------------------
 * This was updated in several ways:
 * 1) The class was renamed GameModel since it is now just a model of the
 *    game and must be controlled by some external force to do anything.
 * 2) The play method was removed because now this class is just a model,
 *    and is controlled externally.
 * 3) Parser was removed since the GUI is taking care of the input, including
 *    parsing it properly.
 * 4) Several methods that used to print now return String objects instead
 *    so the controller can decide how to display them.
 * 5) The quit method has changed so it returns the string "EXIT" if the
 *    user wants to quit.  It cannot handle quitting since it is just a model
 *    and has to let the controller decide what to do about quitting.
 * 6) The if-then-else clauses of processCommand were replaced with a
 *    switch statement since switches are really nice with enums.
 * ---------------------------------------------------------------------------
 * ---------------------------------------------------------------------------
 *    
 * @author  Michael Kolling and David J. Barnes
 * @version 2006.03.30
 * 
 * @author modified by Charles Cusack, October 2008
 */

public class GameModel 
{
    private Room currentRoom;
        
    /**
     * Create the game and initialise its internal map.
     */
    public GameModel() 
    {
        createRooms();
    }

    /**
     * Create all the rooms and link their exits together.
     */
    private void createRooms()
    {
        Room outside, theatre, pub, lab, office;
      
        // create the rooms
        outside = new Room("outside the main entrance of the university");
        theatre = new Room("in a lecture theatre");
        pub = new Room("in the campus pub");
        lab = new Room("in a computing lab");
        office = new Room("in the computing admin office");
        office.setItem(new Item("A desk", 100));
        
        // initialise room exits
        outside.addExit("east", theatre);
        outside.addExit("south", lab);
        outside.addExit("west", pub);

        theatre.addExit("west", outside);

        pub.addExit("east", outside);

        lab.addExit("north", outside);
        lab.addExit("east", office);

        office.addExit("west", lab);

        currentRoom = outside;  // start game outside
    }

    /**
     * Print out the opening message for the player.
     */
    public String getWelcomeMessage()
    {
        StringBuilder sb = new StringBuilder("");
        sb.append("Welcome to the World of Zuul!\n");
        sb.append("World of Zuul is a new, incredibly boring adventure game.\n");
        sb.append("Type '" + CommandWord.HELP + "' if you need help.\n\n");
        sb.append(currentRoom.getLongDescription()+"\n");
        return sb.toString();
    }

    /**
     * Given a command, process (that is: execute) the command.
     * @param command The command to be processed.
     * @return A string with the results of what happened.
     *        EXIT if the user wants to quit
     */
    public String processCommand(Command command) 
    {
        CommandWord commandWord = command.getCommandWord();
        
        switch(commandWord) {
            case HELP:
                return(getHelpMessage());
            case GO:
                return goRoom(command);
            case QUIT:
                return quit(command);
            case UNKNOWN:
            default:
                return("I don't know what you mean...");
        }
    }

    // implementations of user commands:

    /**
     * Return a helpful message.
     * Here we print some stupid, cryptic message and a list of the 
     * command words.
     */
    public String getHelpMessage() 
    {
        StringBuilder sb = new StringBuilder("");
        sb.append("You are lost. You are alone. You wander\n");
        sb.append("around at the university.\n\n");
        sb.append("Your command words are:\n");
        sb.append(CommandWord.getAllCommandWords()+"\n");
        return sb.toString();
    }

    /** 
     * Try to go to one direction. If there is an exit, enter the new
     * room, otherwise print an error message.
     */
    private String goRoom(Command command) 
    {
        if(!command.hasSecondWord()) {
            // if there is no second word, we don't know where to go...
            return("Go where?");
        }

        String direction = command.getSecondWord();

        // Try to leave current room.
        Room nextRoom = currentRoom.getExit(direction);

        if (nextRoom == null) {
            return("There is no door!");
        }
        else {
            currentRoom = nextRoom;
            return(currentRoom.getLongDescription());
        }
    }

    /** 
     * "Quit" was entered. Check the rest of the command to see
     * whether we really quit the game.
     * @return true, if this command quits the game, false otherwise.
     */
    private String quit(Command command) 
    {
        if(command.hasSecondWord()) {
            return("Quit what?");
        }
        else {
            return("EXIT");  // signal that we want to quit
        }
    }
}
