/*
Copyright (C) 1996-1997 Id Software, Inc.

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.

*/
// cmd.c -- Quake script command processing module

#include "quakedef.h"

void Cmd_ForwardToServer (void);

#define    MAX_ALIAS_NAME    32

typedef struct cmdalias_s
{
    struct cmdalias_s    *next;
    char    name[MAX_ALIAS_NAME];
    char    *value;
} cmdalias_t;

cmdalias_t    *cmd_alias;

int trashtest;
int *trashspot;

qboolean    cmd_wait;

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

/*
============
Cmd_Wait_f

Causes execution of the remainder of the command buffer to be delayed until
next frame.  This allows commands like:
bind g "impulse 5 ; +attack ; wait ; -attack ; impulse 2"
============
*/
void Cmd_Wait_f (void)
{
    cmd_wait = true;
}

/*
=============================================================================

                        COMMAND BUFFER

=============================================================================
*/

sizebuf_t    cmd_text;

/*
============
Cbuf_Init
============
*/
void Cbuf_Init (void)
{
    SZ_Alloc (&cmd_text, 8192);        // space for commands and script files
}


/*
============
Cbuf_AddText

Adds command text at the end of the buffer
============
*/
void Cbuf_AddText (const char *text)
{
    int        l;

    l = Q_strlen (text);

    if (cmd_text.cursize + l >= cmd_text.maxsize)
    {
        Con_Printf ("Cbuf_AddText: overflow\n");
        return;
    }

    SZ_Write (&cmd_text, text, Q_strlen (text));
}


/*
============
Cbuf_InsertText

Adds command text immediately after the current command
Adds a \n to the text
FIXME: actually change the command buffer to do less copying
============
*/
void Cbuf_InsertText (const char *text)
{
    char    *temp;
    int        templen;

// copy off any commands still remaining in the exec buffer
    templen = cmd_text.cursize;
    if (templen)
    {
        temp = (char*) Z_Malloc (templen);
        Q_memcpy (temp, cmd_text.data, templen);
        SZ_Clear (&cmd_text);
    }
    else
        temp = NULL;    // shut up compiler

// add the entire text of the file
    Cbuf_AddText (text);

// add the copied off data
    if (templen)
    {
        SZ_Write (&cmd_text, temp, templen);
        Z_Free (temp);
    }
}

/*
============
Cbuf_Execute
============
*/
void Cbuf_Execute (void)
{
    int        i;
    char    *text;
    char    line[1024];
    int        quotes;

    while (cmd_text.cursize)
    {
// find a \n or ; line break
        text = (char *)cmd_text.data;

        quotes = 0;
        for (i=0 ; i< cmd_text.cursize ; i++)
        {
            if (text[i] == '"')
                quotes++;
            if ( !(quotes&1) &&  text[i] == ';')
                break;    // don't break if inside a quoted string
            if (text[i] == '\n' || text[i] == '\r')
                break;
        }


        memcpy (line, text, i);
        line[i] = 0;

// delete the text from the command buffer and move remaining commands down
// this is necessary because commands (exec, alias) can insert data at the
// beginning of the text buffer

        if (i == cmd_text.cursize)
            cmd_text.cursize = 0;
        else
        {
            i++;
            cmd_text.cursize -= i;
            Q_memcpy (text, text+i, cmd_text.cursize);
        }

// execute the command line
        Cmd_ExecuteString (line, src_command);

        if (cmd_wait)
        {    // skip out while text still remains in buffer, leaving it
            // for next frame
            cmd_wait = false;
            break;
        }
    }
}

/*
==============================================================================

                        SCRIPT COMMANDS

==============================================================================
*/

/*
===============
Cmd_StuffCmds_f

Adds command line parameters as script statements
Commands lead with a +, and continue until a - or another +
quake +prog jctest.qp +cmd amlev1
quake -nosound +cmd amlev1
===============
*/
void Cmd_StuffCmds_f (void)
{
    int        i, j;
    int        s;
    char    *text, *build, c;

    if (Cmd_Argc () != 1)
    {
        Con_Printf ("stuffcmds : execute command line parameters\n");
        return;
    }

// build the combined string to parse from
    s = 0;
    for (i=1 ; i<com_argc ; i++)
    {
        if (!com_argv[i])
            continue;        // NEXTSTEP nulls out -NXHost
        s += Q_strlen (com_argv[i]) + 1;
    }
    if (!s)
        return;

    text = (char*) Z_Malloc (s+1);
    text[0] = 0;
    for (i=1 ; i<com_argc ; i++)
    {
        if (!com_argv[i])
            continue;        // NEXTSTEP nulls out -NXHost
        Q_strcat (text,com_argv[i]);
        if (i != com_argc-1)
            Q_strcat (text, " ");
    }

// pull out the commands
    build = (char*) Z_Malloc (s+1);
    build[0] = 0;

    for (i=0 ; i<s-1 ; i++)
    {
        if (text[i] == '+')
        {
            i++;

            for (j=i ; (text[j] != '+') && (text[j] != '-') && (text[j] != 0) ; j++)
                ;

            c = text[j];
            text[j] = 0;

            Q_strcat (build, text+i);
            Q_strcat (build, "\n");
            text[j] = c;
            i = j-1;
        }
    }

    if (build[0])
        Cbuf_InsertText (build);

    Z_Free (text);
    Z_Free (build);
}


/*
===============
Cmd_Exec_f
===============
*/
void Cmd_Exec_f (void)
{
    char    *f;
    int        mark;

    if (Cmd_Argc () != 2)
    {
        Con_Printf ("exec <filename> : execute a script file\n");
        return;
    }

    mark = Hunk_LowMark ();
    f = (char *)COM_LoadHunkFile (Cmd_Argv(1));
    if (!f)
    {
        Con_Printf ("couldn't exec %s\n",Cmd_Argv(1));
        return;
    }
    Con_Printf ("execing %s\n",Cmd_Argv(1));

    Cbuf_InsertText (f);
    Hunk_FreeToLowMark (mark);
}


/*
===============
Cmd_Echo_f

Just prints the rest of the line to the console
===============
*/
void Cmd_Echo_f (void)
{
    int        i;

    for (i=1 ; i<Cmd_Argc() ; i++)
        Con_Printf ("%s ",Cmd_Argv(i));
    Con_Printf ("\n");
}

/*
===============
Cmd_Alias_f

Creates a new command that executes a command string (possibly ; seperated)
===============
*/

char *CopyString (const char *in)
{
    char    *out;

    out = (char*) Z_Malloc (strlen(in)+1);
    strcpy (out, in);
    return out;
}

void Cmd_Alias_f (void)
{
    cmdalias_t    *a;
    char        cmd[1024];
    int            i, c;
    const char        *s;

    if (Cmd_Argc() == 1)
    {
        Con_Printf ("Current alias commands:\n");
        for (a = cmd_alias ; a ; a=a->next)
            Con_Printf ("%s : %s\n", a->name, a->value);
        return;
    }

    s = Cmd_Argv(1);
    if (strlen(s) >= MAX_ALIAS_NAME)
    {
        Con_Printf ("Alias name is too long\n");
        return;
    }

    // if the alias allready exists, reuse it
    for (a = cmd_alias ; a ; a=a->next)
    {
        if (!strcmp(s, a->name))
        {
            Z_Free (a->value);
            break;
        }
    }

    if (!a)
    {
        a = (cmdalias_t*) Z_Malloc (sizeof(cmdalias_t));
        a->next = cmd_alias;
        cmd_alias = a;
    }
    strcpy (a->name, s);

// copy the rest of the command line
    cmd[0] = 0;        // start out with a null string
    c = Cmd_Argc();
    for (i=2 ; i< c ; i++)
    {
        strcat (cmd, Cmd_Argv(i));
        if (i != c)
            strcat (cmd, " ");
    }
    strcat (cmd, "\n");

    a->value = CopyString (cmd);
}

/*
=============================================================================

                    COMMAND EXECUTION

=============================================================================
*/

typedef struct cmd_function_s
{
    struct cmd_function_s    *next;
    char                    *name;
    xcommand_t                function;
} cmd_function_t;


#define    MAX_ARGS        80

static    int            cmd_argc;
static    char        *cmd_argv[MAX_ARGS];
static    char        *cmd_null_string = (char*) "";
static    char        *cmd_args = NULL;

cmd_source_t    cmd_source;


static    cmd_function_t    *cmd_functions;        // possible commands to execute

/*
============
Cmd_Init
============
*/
void Cmd_Init (void)
{
//
// register our commands
//
    Cmd_AddCommand ("stuffcmds",Cmd_StuffCmds_f);
    Cmd_AddCommand ("exec",Cmd_Exec_f);
    Cmd_AddCommand ("echo",Cmd_Echo_f);
    Cmd_AddCommand ("alias",Cmd_Alias_f);
    Cmd_AddCommand ("cmd", Cmd_ForwardToServer);
    Cmd_AddCommand ("wait", Cmd_Wait_f);
}

/*
============
Cmd_Argc
============
*/
int        Cmd_Argc (void)
{
    return cmd_argc;
}

/*
============
Cmd_Argv
============
*/
char    *Cmd_Argv (int arg)
{
    if ( arg >= cmd_argc )
        return cmd_null_string;
    return cmd_argv[arg];
}

/*
============
Cmd_Args
============
*/
char        *Cmd_Args (void)
{
    return cmd_args;
}


/*
============
Cmd_TokenizeString

Parses the given string into command line tokens.
============
*/
void Cmd_TokenizeString (char *text)
{
    int        i;

// clear the args from the last string
    for (i=0 ; i<cmd_argc ; i++)
        Z_Free (cmd_argv[i]);

    cmd_argc = 0;
    cmd_args = NULL;

    while (1)
    {
// skip whitespace up to a /n
        while (*text && *text <= ' ' && *text != '\n')
        {
            text++;
        }

        if (*text == '\n')
        {    // a newline seperates commands in the buffer
            text++;
            break;
        }

        if (!*text)
            return;

        if (cmd_argc == 1)
             cmd_args = text;

        text = COM_Parse (text);
        if (!text)
            return;

        if (cmd_argc < MAX_ARGS)
        {
            cmd_argv[cmd_argc] = (char*) Z_Malloc (Q_strlen(com_token)+1);
            Q_strcpy (cmd_argv[cmd_argc], com_token);
            cmd_argc++;
        }
    }

}


/*
============
Cmd_AddCommand
============
*/
void    Cmd_AddCommand (const char *cmd_name, xcommand_t function)
{
    cmd_function_t    *cmd;

    if (host_initialized)    // because hunk allocation would get stomped
        Sys_Error ("Cmd_AddCommand after host_initialized");

// fail if the command is a variable name
    if (Cvar_VariableString(cmd_name)[0])
    {
        Con_Printf ("Cmd_AddCommand: %s already defined as a var\n", cmd_name);
        return;
    }

// fail if the command already exists
    for (cmd=cmd_functions ; cmd ; cmd=cmd->next)
    {
        if (!Q_strcmp (cmd_name, cmd->name))
        {
            Con_Printf ("Cmd_AddCommand: %s already defined\n", cmd_name);
            return;
        }
    }

    cmd = (cmd_function_t*) Hunk_Alloc (sizeof(cmd_function_t));
    cmd->name = (char*) cmd_name;
    cmd->function = function;
    cmd->next = cmd_functions;
    cmd_functions = cmd;
}

/*
============
Cmd_Exists
============
*/
qboolean    Cmd_Exists (const char *cmd_name)
{
    cmd_function_t    *cmd;

    for (cmd=cmd_functions ; cmd ; cmd=cmd->next)
    {
        if (!Q_strcmp (cmd_name,cmd->name))
            return true;
    }

    return false;
}



/*
============
Cmd_CompleteCommand
============
*/
const char *Cmd_CompleteCommand (const char *partial)
{
    cmd_function_t    *cmd;
    int                len;

    len = Q_strlen(partial);

    if (!len)
        return NULL;

// check functions
    for (cmd=cmd_functions ; cmd ; cmd=cmd->next)
        if (!Q_strncmp (partial,cmd->name, len))
            return cmd->name;

    return NULL;
}

/*
============
Cmd_ExecuteString

A complete command line has been parsed, so try to execute it
FIXME: lookupnoadd the token to speed search?
============
*/
void    Cmd_ExecuteString (char *text, cmd_source_t src)
{
    cmd_function_t    *cmd;
    cmdalias_t        *a;

    cmd_source = src;
    Cmd_TokenizeString (text);

// execute the command line
    if (!Cmd_Argc())
        return;        // no tokens

// check functions
    for (cmd=cmd_functions ; cmd ; cmd=cmd->next)
    {
        if (!Q_strcasecmp (cmd_argv[0],cmd->name))
        {
            cmd->function ();
            return;
        }
    }

// check alias
    for (a=cmd_alias ; a ; a=a->next)
    {
        if (!Q_strcasecmp (cmd_argv[0], a->name))
        {
            Cbuf_InsertText (a->value);
            return;
        }
    }

// check cvars
    if (!Cvar_Command ())
        Con_Printf ("Unknown command \"%s\"\n", Cmd_Argv(0));

}

void    Cmd_ExecuteString2 (const char *text, cmd_source_t src)
{
    char buf[100];
    Q_strncpy(buf, text, sizeof(buf));
    buf[sizeof(buf)-1] = 0;
    Cmd_ExecuteString(buf, src);
}

/*
===================
Cmd_ForwardToServer

Sends the entire command line over to the server
===================
*/
void Cmd_ForwardToServer (void)
{
    if (cls.state != ca_connected)
    {
        Con_Printf ("Can't \"%s\", not connected\n", Cmd_Argv(0));
        return;
    }

    if (cls.demoplayback)
        return;        // not really connected

    MSG_WriteByte (&cls.message, clc_stringcmd);
    if (Q_strcasecmp(Cmd_Argv(0), "cmd") != 0)
    {
        SZ_Print (&cls.message, Cmd_Argv(0));
        SZ_Print (&cls.message, " ");
    }
    if (Cmd_Argc() > 1)
        SZ_Print (&cls.message, Cmd_Args());
    else
        SZ_Print (&cls.message, "\n");
}


/*
================
Cmd_CheckParm

Returns the position (1 to argc-1) in the command's argument list
where the given parameter apears, or 0 if not present
================
*/

int Cmd_CheckParm (const char *parm)
{
    int i;

    if (!parm)
        Sys_Error ("Cmd_CheckParm: NULL");

    for (i = 1; i < Cmd_Argc (); i++)
        if (! Q_strcasecmp (parm, Cmd_Argv (i)))
            return i;

    return 0;
}
