/*
Copyright (C) 1996-2001 Id Software, Inc.
Copyright (C) 2002-2009 John Fitzgibbons and others
Copyright (C) 2010-2014 QuakeSpasm developers
Copyright (C) 2026 iikorni

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

*/

#pragma once

// cmd.h -- Command buffer and command execution

//===========================================================================


typedef void (*xcommand_t)();

namespace command {
    namespace buffer {
        void init();

        void add_text(const std::string &text);

        void insert_text(const std::string &text);

        void execute();
    }

    enum class source {
        client,
        command
    };

    extern source last_source;

    struct alias {
        std::string name;
        std::string value;
    };

    struct definition {
        std::string name{};
        xcommand_t func{nullptr};

        definition(const std::string &name, const xcommand_t func) {
            this->name = name;
            this->func = func;
        }
    };

    using definition_view = std::ranges::elements_view<std::ranges::ref_view<std::map<std::string, definition, std::less
        <> > >, 1>;
    using alias_view = std::ranges::elements_view<std::ranges::ref_view<std::map<std::string, alias, std::less<> > >, 1>
    ;


    void init();

    void add(const std::string &name, xcommand_t cmd);

    std::optional<std::string> complete(const std::string &partial);

    bool exists(std::string_view lookup);

    int argc();

    std::optional<std::string> argv(int arg);

    std::string args();

    int check_parm(const std::string &parm);

    void tokenize_string(const std::string &text);

    void execute_string(const std::string &text, source src);

    void forward_to_server();

    definition_view get_commands();

    alias_view get_aliases();
}
