/* Copyright (c) 2002
 *	Marko Boomstra (m.boomstra@chello.nl).  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */
#include <conf.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <ncurses.h>
#include <panel.h>
#include "mudix.h"

typedef struct cmd_table CMDTAB;

/* global argument for all commands */
char gl_arg[MAX_STRING];

void cmd_alias(int index, char *args);
void cmd_delalias(int index, char *args);
void cmd_delpath(int index, char *args);
void cmd_deltab(int index, char *args);
void cmd_deltrig(int index, char *args);
void cmd_delvar(int index, char *args);
void cmd_distrig(int index, char *args);
void cmd_enatrig(int index, char *args);
void cmd_if(int index, char *args);
void cmd_log(int index, char *args);
void cmd_nmalias(int index, char *args);
void cmd_path(int index, char *args);
void cmd_read(int index, char *args);
void cmd_save(int index, char *args);
void cmd_status(int index, char *args);
void cmd_tab(int index, char *args);
void cmd_trigger(int index, char *args);
void cmd_variable(int index, char *args);
void cmd_write(int index, char *args);

const struct cmd_table_type cmd_table[] = {
    { "alias", cmd_alias, 	"Syntax: #alias Fkey {response}" },
    { "delalias", cmd_delalias,	"Syntax: #delalias {alias name}" },
    { "delpath", cmd_delpath,	"Syntax: #delpath {path name}" },
    { "deltab", cmd_deltab,	"Syntax: #deltab {tab name}" },
    { "deltrig", cmd_deltrig,	"Syntax: #deltrig number" },
    { "delvar", cmd_delvar,	"Syntax: #delvar {variable name}" },
    { "distrig", cmd_distrig,	"Syntax: #distrig level" },
    { "enatrig", cmd_enatrig,	"Syntax: #enatrig level" },
    { "if", cmd_if,		"Syntax: #if {expression} {commands}" },
    { "log", cmd_log, 		"Syntax: #log {filename} OR #log (stop log)" },
    { "nmalias", cmd_nmalias, 	"Syntax: #nmalias {alias name} {response}" },
    { "path", cmd_path, 	"Syntax: #path {path name} {path}" },
    { "read", cmd_read, 	"Syntax: #read {filename}" },
    { "save", cmd_save, 	"Syntax: #save {filename.usr}" },
    { "status", cmd_status, 	"Syntax: #status on/off" },
    { "tab", cmd_tab, 		"Syntax: #tab {tab name}" },
    { "trigger", cmd_trigger, 	"Syntax: #trigger level {trigger} {response}" },
    { "variable", cmd_variable,	"Syntax: #variable {variable name} {value}" },
    { "write", cmd_write, 	"Syntax: #write {filename.cmd}" },
    { NULL, NULL, NULL }
};

int cmd_lookup(char *cmd)
{
    int i = 0;

    while (cmd_table[i].cmd) {
	if (!strncmp(cmd, cmd_table[i].cmd, strlen(cmd)))
	    return i;
	i++;
    }

    return -1;
}

void do_command(char *cmdline)
{
    char *pCmd;
    int   index;

    pCmd = get_arg(cmdline, gl_arg);
    index = cmd_lookup(gl_arg);
    if (index == -1)
	return;

    (*(cmd_table[index].function))(index, pCmd); 
    return;
}

void cmd_alias(int index, char *arglist)
{
    settings->state = STATE_ALIAS_1;
    while (settings->state != STATE_READY) {
	arglist = get_arg(arglist, gl_arg);
    	if (set_settings(gl_arg) == STATE_ILLPARM) {
	    do_status(cmd_table[index].help, 6);
	    break;
	}
    }

    return;
}

void cmd_delalias(int index, char *arglist)
{
    settings->state = STATE_NDELETE;
    while (settings->state != STATE_READY) {
	arglist = get_arg(arglist, gl_arg);
    	if (set_settings(gl_arg) == STATE_ILLPARM) {
	    do_status(cmd_table[index].help, 6);
	    break;
	}
    }

    return;
}

void cmd_delpath(int index, char *arglist)
{
    settings->state = STATE_PDELETE;
    while (settings->state != STATE_READY) {
	arglist = get_arg(arglist, gl_arg);
    	if (set_settings(gl_arg) == STATE_ILLPARM) {
	    do_status(cmd_table[index].help, 6);
	    break;
	}
    }

    return;
}

void cmd_deltab(int index, char *arglist)
{
    settings->state = STATE_TABSDELETE;
    while (settings->state != STATE_READY) {
	arglist = get_arg(arglist, gl_arg);
    	if (set_settings(gl_arg) == STATE_ILLPARM) {
	    do_status(cmd_table[index].help, 6);
	    break;
	}
    }

    return;
}

void cmd_deltrig(int index, char *arglist)
{
    settings->state = STATE_TDELETE;
    while (settings->state != STATE_READY) {
	arglist = get_arg(arglist, gl_arg);
    	if (set_settings(gl_arg) == STATE_ILLPARM) {
	    do_status(cmd_table[index].help, 6);
	    break;
	}
    }

    return;
}

void cmd_delvar(int index, char *arglist)
{
    settings->state = STATE_VDELETE;
    while (settings->state != STATE_READY) {
	arglist = get_arg(arglist, gl_arg);
    	if (set_settings(gl_arg) == STATE_ILLPARM) {
	    do_status(cmd_table[index].help, 6);
	    break;
	}
    }

    return;
}

void cmd_distrig(int index, char *arglist)
{
    TRIGGER *trig;
    int      level;

    get_arg(arglist, gl_arg);
    level = atoi(gl_arg);
    for (trig = settings->trigger_list; trig; trig = trig->next) {
	if (trig->level == level)
	    trig->enabled = FALSE;
    }
    do_status("All triggers of that level disabled.", 3);

    return;
}

void cmd_enatrig(int index, char *arglist)
{
    TRIGGER *trig;
    int      level;

    get_arg(arglist, gl_arg);
    level = atoi(gl_arg);
    for (trig = settings->trigger_list; trig; trig = trig->next) {
	if (trig->level == level)
	    trig->enabled = TRUE;
    }
    do_status("All triggers of that level enabled.", 3);

    return;
}

void cmd_if(int index, char *arglist)
{
    process_if(arglist);
    return;
}

void cmd_log(int index, char *arglist)
{
    get_arg(arglist, gl_arg);
    if (gl_arg[0]) {
	if (!init_log(gl_arg))
	    do_status(cmd_table[index].help, 6);
	else
	    do_status("Log started.", 3);
    }
    else { 
	if (!close_log())
	    do_status(cmd_table[index].help, 6);
	else
	    do_status("Log closed.", 3);
    }

    return;
}

void cmd_nmalias(int index, char *arglist)
{
    settings->state = STATE_NAMING_1;
    while (settings->state != STATE_READY) {
	arglist = get_arg(arglist, gl_arg);
    	if (set_settings(gl_arg) == STATE_ILLPARM) {
	    do_status(cmd_table[index].help, 6);
	    break;
	}
    }

    return;
}

void cmd_path(int index, char *arglist)
{
    PATH *path;
    char *orig_arg = arglist;

    arglist = get_arg(arglist, gl_arg);
    for (path = settings->path_list; path; path = path->next) {
	if (!strcmp(gl_arg, path->name))
	    break;
    }

    arglist = get_arg(arglist, gl_arg);
    if (!gl_arg[0]) {
	if (!path) {
	    do_status("Path not found!", 3);
	    return;
	}
	process_path(path->path);
        return;
    }
    
    if (path) {
    	do_status("Path already exists!", 3);
	return;
    }

    arglist = orig_arg;
    settings->state = STATE_PCREATE_1;
    while (settings->state != STATE_READY) {
	arglist = get_arg(arglist, gl_arg);
    	if (set_settings(gl_arg) == STATE_ILLPARM) {
	    do_status(cmd_table[index].help, 6);
	    break;
	}
    }

    return;
}

void cmd_read(int index, char *arglist)
{
    FILE *fp;
    char *line;

    get_arg(arglist, gl_arg);
    if (!gl_arg[0]) {
	do_status(cmd_table[index].help, 6);
	return;
    }

    if (!(fp = fopen(gl_arg, "r"))) {
	do_status("Failed to open file.", 3);
	return;
    }

    while ((line = fread_to_eol(fp))) {
	if (*line == '\0')
	    break;
	process_input(line, NULL, TRUE);	
	if (send_buffer[0])
	    write_desc(settings->sock);		/* flush the out buffer */
    }

    fclose(fp);
    return;
}

void cmd_save(int index, char *arglist)
{
    settings->state = STATE_SAVE;
    while (settings->state != STATE_READY) {
	arglist = get_arg(arglist, gl_arg);
    	if (set_settings(gl_arg) == STATE_ILLPARM) {
	    do_status(cmd_table[index].help, 6);
	    break;
	}
    }

    return;
}

void cmd_status(int index, char *arglist)
{
    get_arg(arglist, gl_arg);
    if (!strcmp(gl_arg, "off")) {
        do_status("Status reports disabled.", 3);
        fStatusReport = FALSE;
    }
    else {
    	fStatusReport = TRUE;
        do_status("Status reports enabled.", 3);
    }
	
    return;
}

void cmd_tab(int index, char *arglist)
{
    settings->state = STATE_TABSCREATE;
    while (settings->state != STATE_READY) {
	arglist = get_arg(arglist, gl_arg);
    	if (set_settings(gl_arg) == STATE_ILLPARM) {
	    do_status(cmd_table[index].help, 6);
	    break;
	}
    }

    return;
}

void cmd_trigger(int index, char *arglist)
{
    settings->state = STATE_TCREATE_1;
    while (settings->state != STATE_READY) {
	arglist = get_arg(arglist, gl_arg);
    	if (set_settings(gl_arg) == STATE_ILLPARM) {
	    do_status(cmd_table[index].help, 6);
	    break;
	}
    }

    return;
}

void cmd_variable(int index, char *arglist)
{
    settings->state = STATE_VCREATE_1;
    while (settings->state != STATE_READY) {
	arglist = get_arg(arglist, gl_arg);
    	if (set_settings(gl_arg) == STATE_ILLPARM) {
	    do_status(cmd_table[index].help, 6);
	    break;
	}
    }

    return;
}

void cmd_write(int index, char *arglist)
{
    settings->state = STATE_WRITE;
    while (settings->state != STATE_READY) {
	arglist = get_arg(arglist, gl_arg);
    	if (set_settings(gl_arg) == STATE_ILLPARM) {
	    do_status(cmd_table[index].help, 6);
	    break;
	}
    }

    return;
}



syntax highlighted by Code2HTML, v. 0.9.1