//////////////////////////////////////////////////////
//
// LuaConsole:
//
// Used to parse commands that are being interactively typed
// in by a user.  The common usage pattern is:
//
//    1. Print the prompt suggested by 'get_prompt'.
//    2. Read a line of text from stdin.
//    3. Add the line to the LuaConsole using 'add'.
//    4. Get the command word using get_command.
//    5. If the command is empty, do nothing.
//    6. If the command is nonempty, get the args and execute it.
//
// The LuaConsole expects you to type a lua command, or one
// of the following slash-commands:
//
//    /quit               - exit the program
//    /view               - display the nearby tangibles
//    /menu [tanid]       - display the menu for tangible 
//    /tick [timevalue]   - advance the simulation clock
//    /choose [number]    - choose menu item number
//    /1234               - choose menu item 1234
//
// If you type anything else, the LuaConsole will generate a
// syntax error.  Note that not all of the commands above are
// supported in all interpreters.
//
// Lua commands can be one of the following:
//
// <expression>       - invoke "<expression>""
// = <expression>     - invoke "return <expression>"
// ? <expression>     - probe "<expression>"
// ?= <expression>    - probe "return <expression>"
//
// Once a command has been typed (or a syntax error has been
// typed), the LuaConsole will return the command.  The command
// can be fetched using command(), int_arg(), and str_arg()
//
//////////////////////////////////////////////////////

#ifndef LUACONSOLE_HPP
#define LUACONSOLE_HPP

#include "wrap-string.hpp"
#include "wrap-vector.hpp"

#include "luastack.hpp"

class LuaConsole : public eng::nevernew {
public:
    using StringVec = eng::vector<eng::string>;

private:
    lua_State *lua_state_;
    eng::string raw_input_;
    int lines_;
    eng::string prompt_;
    StringVec words_;

    void clear_raw_input();
    void simplify(const StringVec &words);
    void synerr(const eng::string &msg);

public:
    LuaConsole();
    ~LuaConsole();

    // Fetch the recommended prompt.
    //
    // You should update the prompt immediately after 'add'.
    //
    const eng::string &get_prompt() { return prompt_; }
    
    // Get the command words.
    //
    // Note that the command words may not be exactly what
    // the user typed.  Typically, the LuaConsole simplifies
    // the command before returning it to the caller.
    //
    StringVec get_command();
    
    // Add a line of text that was just read from the console.
    //
    void add(eng::string line);

};

#endif // LUACONSOLE_HPP
