#ifndef SIMULATOR_COMMANDLIST_H
#define SIMULATOR_COMMANDLIST_H

#include <vector>
#include <cstdint>
#include <mentalEntity.h>

namespace smo {
namespace simulator {

/**
 * @brief Base class for all commands, storing a reference to a mental entity ID.
 * 
 * Derived classes can extend this to include additional command-specific
 * data and behavior.
 */
class Command
{
public:
    Command(const MentalEntity::Id menty) : menty(menty) {}

public:
    const MentalEntity::Id menty;
};

class CommandList
{
public:
    CommandList() = default;

    /**
     * @brief Used by Scene to point to the currently executing command.
     * 
     * simulator::Scene maintains an internal cursor. As it executes commands
     * from its internal command list, it advances the cursor to the current
     * command before executing it.
     */
    class Cursor
    {
    public:
        Cursor(CommandList& commandList)
        : commandList(commandList), iter(commandList.commands.begin())
        {}

        void reset() { iter = commandList.commands.begin(); }
        bool hasNext() const { return iter != commandList.commands.end(); }
        Cursor next() { return ++(*this); }

        Cursor& operator++() {
            ++iter;
            return *this;
        }

    private:
        Cursor(
            CommandList& commandList,
            std::vector<Command>::iterator iter)
        : commandList(commandList), iter(iter)
        {}

    public:
        CommandList& commandList;
        std::vector<Command>::iterator iter;
    };

    Cursor getCursor() { return Cursor(*this); }
    void addCommand(const Command& command)
    {
        commands.push_back(command);
    }

public:
    std::vector<Command> commands;
};

} // namespace simulator
} // namespace smo

#endif // SIMULATOR_COMMANDLIST_H
