/*
 * This file handles command interpreting
 */
#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

/* include main header file */
#include "mud.h"

void handle_cmd_input(D_SOCKET *dsock, char *arg)
{
    D_MOBILE *dMob;
    char command[MAX_BUFFER];
    bool found_cmd = FALSE;
    int i;
    char logline[MAX_BUFFER];

    if ((dMob = dsock->player) == NULL)
        return;

    strcpy (logline, arg);
    if (!isalpha (arg[0]) && !isdigit (arg[0]))
    {
        command[0] = arg[0];
        command[1] = '\0';
        arg++;
        while (isspace (*arg))
            arg++;
    }
    else
    {
        arg = one_arg(arg, command);
    }

  for (i = 0; tabCmd[i].cmd_name[0] != '\0' && !found_cmd; i++)
  {
    if (tabCmd[i].level > dMob->level) continue;

    if (is_prefix(command, tabCmd[i].cmd_name))
    {
      found_cmd = TRUE;
      (*tabCmd[i].cmd_funct)(dMob, arg);
    }
  }

  if (!found_cmd)
    text_to_mobile(dMob, "No such command.\n\r");
}

/*
 * The command table, very simple, but easy to extend.
 */
const struct typCmd tabCmd [] =
{
        /* command               function        Req. Level     */
        /* -------------------------------------------------- */
        { "'",                  cmd_say,         LEVEL_GUEST    },
        /* Movement Commands */
        { "north",              cmd_north,       LEVEL_GUEST    },
        { "south",              cmd_south,       LEVEL_GUEST    },
        { "east",               cmd_east,        LEVEL_GUEST    },
        { "west",               cmd_west,        LEVEL_GUEST    },
        { "up",                 cmd_up,          LEVEL_GUEST    },
        { "down",               cmd_down,        LEVEL_GUEST    },
        { "open",               cmd_open,        LEVEL_GUEST    },
        { "close",              cmd_close,       LEVEL_GUEST    },
        { "/",                  cmd_recall,      LEVEL_GUEST    },
        { "recall",             cmd_recall,      LEVEL_GUEST    },
        { "where",              cmd_where,       LEVEL_GUEST    },
        { "location",           cmd_location,    LEVEL_GUEST    },
        { "look",               cmd_look,        LEVEL_GUEST    },
        /* Communcations */
        { "say",                cmd_say,        LEVEL_GUEST     },
        { "chat",               cmd_chat,       LEVEL_GUEST     },
        { "config",             cmd_config,     LEVEL_GUEST     },
        { "title",              cmd_title,      LEVEL_GUEST     },
        { "note",               cmd_note,       LEVEL_GUEST     },
        { "score",              cmd_score,      LEVEL_GUEST     },
        { "train",              cmd_train,      LEVEL_GUEST     },
        { "changes",            do_changes,     LEVEL_GUEST     },
        /* Other crap */
        { "skills",             cmd_skills,     LEVEL_GUEST     },
        { "commands",           cmd_commands,   LEVEL_GUEST     },
        { "compress",           cmd_compress,   LEVEL_GUEST     },
        { "help",               cmd_help,       LEVEL_GUEST     },
        { "save",               cmd_save,       LEVEL_GUEST     },
        { "quit",               cmd_quit,       LEVEL_GUEST     },
        { "who",                cmd_who,        LEVEL_GUEST     },
        { "time",               cmd_time,       LEVEL_GUEST     },
        /* Admin/Builder Commands */
        { "linkdead",           cmd_linkdead,   LEVEL_ADMIN     },
        { "displaybits",        cmd_display_bits,LEVEL_ADMIN    },
        { "omniview",           cmd_omni_view,  LEVEL_ADMIN     },
        { "passdoor",           cmd_pass_door,  LEVEL_ADMIN     },
        { "copyover",           cmd_copyover,   LEVEL_ADMIN     },
        { "echo",               cmd_echo,       LEVEL_ADMIN     },
        { "pset",               cmd_pset,       LEVEL_ADMIN     },
        { "edit",               cmd_leave_trail,LEVEL_ADMIN     },
        { "goto",               cmd_goto,       LEVEL_ADMIN     },
        { "sector_number",      cmd_number_here,LEVEL_ADMIN     },
        { "make_box",           cmd_edit_box,   LEVEL_ADMIN     },
        /* Thri's Commands */
        { "addchange",          do_addchange,   LEVEL_GOD       },
        { "delchange",          do_delchange,   LEVEL_GOD       },
        { "clearchanges",       cmd_clearchanges,LEVEL_GOD      },
        { "shutdown",           cmd_shutdown,   LEVEL_GOD       },
        { "advance",            cmd_advance,    LEVEL_GOD       },
        { "saveworld",          cmd_save_world, LEVEL_GOD       },
        { "loadimage",          cmd_load_image, LEVEL_GOD       },
        { "loadimagesm",        cmd_load_small, LEVEL_GOD       },
        { "saveimage",          cmd_save_image, LEVEL_GOD       },
        { "addarea",            cmd_add_area,   LEVEL_GOD       },
        { "scrye",              cmd_scrye,      LEVEL_GOD       },
        { "mobiles",            cmd_mobiles,    LEVEL_GOD       },

  /* end of table */
  { "", 0 }
};

/*
 * is_number
 *
 * true if its a number
 * false if its not
 */
bool is_number (char *arg)
{

    if (*arg == '\0')
        return FALSE;

    if (*arg == '+' || *arg == '-')
        arg++;

    for (; *arg != '\0'; arg++)
    {
        if (!isdigit (*arg))
            return FALSE;
    }

    return TRUE;
}