/*
*  XmNap  A Motif napster client
*
*  Copyright (C) 2000 Mats Peterson
*
*  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; see the file COPYING.  If not, write to
*  the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
*  Boston, MA 02111-1307, USA.
*
*  Please send any comments/bug reports to
*  [email protected]  (Mats Peterson)
*/

#include <Xm/Xm.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <errno.h>
#include <time.h>

#include "main.h"
#include "configwin.h"
#include "connect.h"
#include "transfer.h"
#include "command.h"
#include "shared.h"
#include "chat.h"
#include "chnlist.h"
#include "ullist.h"
#include "linklist.h"
#include "hotlist.h"
#include "banlist.h"
#include "search.h"
#include "whois.h"
#include "message.h"
#include "srvstats.h"
#include "msgbox.h"
#include "util.h"


AUTOCOMMAND *autoCommands = NULL;


void CmdParse(String s)
{
   String cmd, data, tmp, channel, level, nick, reason, topic, port;
   String server, portString, metaString;
   CHAN *curChan;

   if (strlen(s) < 2) {
       ErrMsg("Invalid command");
       return;
   }

   if (s[0] != '/') {
       ErrMsg("Invalid command");
       return;
   }

   cmd = strtok(s + 1, " \t");
   if (! (data = strtok(NULL, "\0")))
       data = "";
   else {
       while (isspace(*data))
           data++;
   }

   if (CmdMatch(cmd, "ban", 2)) {
       if (! srvConn)
           return;
       if (! strlen(data)) {
           ErrMsg("Missing parameters");
           return;
       }
       if (! (nick = strtok(data, " "))) {
           ErrMsg("Missing parameters");
           return;
       }
       if (! (reason = strtok(NULL, "\0")))
           reason = "";
       tmp = XtMalloc(strlen(nick) + strlen(reason) + 4);
       sprintf(tmp, "%s \"%s\"", nick, reason);
       if (SendMsg(MSG_CLIENT_BAN, tmp))
           Disconnect(strerror(errno));
       XtFree(tmp);

   } else if (CmdMatch(cmd, "browse", 2)) {
       if (! srvConn)
           return;
       if (! strlen(data)) {
           ErrMsg("Missing parameters");
           return;
       }
       Browse(data);

   } else if (CmdMatch(cmd, "chlevel", 3)) {
       if (! srvConn)
           return;
       if (! strlen(data)) {
           ErrMsg("Missing parameters");
           return;
       }
       if (! (channel = strtok(data, " "))) {
           ErrMsg("Missing parameters");
           return;
       }
       if (! (level = strtok(NULL, " ")))
           level = "";
       tmp = XtMalloc(strlen(channel) + strlen(level) + 3);
       sprintf(tmp, "%s %s", channel, level);
       if (SendMsg(MSG_CLIENT_CHANNEL_LEVEL, tmp))
           Disconnect(strerror(errno));
       XtFree(tmp);

   } else if (CmdMatch(cmd, "clear", 3)) {
       if (! srvConn)
           return;
       if (! strlen(data)) {
           ErrMsg("Missing parameters");
           return;
       }
       if (! (channel = strtok(data, " "))) {
           ErrMsg("Missing parameters");
           return;
       }
       if (! (reason = strtok(NULL, "\0")))
           reason = "";
       tmp = XtMalloc(strlen(channel) + strlen(reason) + 5);
       sprintf(tmp, "%s \"%s\"", channel, reason);
       if (SendMsg(MSG_CLIENT_CLEAR_CHANNEL, tmp))
           Disconnect(strerror(errno));
       XtFree(tmp);

   } else if (CmdMatch(cmd, "cloak", 3)) {
       if (! srvConn)
           return;
       if (SendMsg(MSG_CLIENT_CLOAK, ""))
           Disconnect(strerror(errno));

   } else if (CmdMatch(cmd, "config", 4)) {
       ConfigWin(USER_PAGE);

   } else if (CmdMatch(cmd, "connect", 4)) {
       if (srvConn)
           return;
       if (! curServer.name) {
           ErrMsg("Define servers first");
           return;
       }
       tmp = XtNewString(curServer.name);
       Connect(tmp, curServer.port, curServer.meta, 1);
       XtFree(tmp);

   } else if (CmdMatch(cmd, "dataport", 2)) {
       if (! srvConn)
           return;
       if (! strlen(data)) {
           ErrMsg("Missing parameters");
           return;
       }
       if (! (nick = strtok(data, " "))) {
           ErrMsg("Missing parameters");
           return;
       }
       if (! (port = strtok(NULL, " "))) {
           ErrMsg("Missing parameters");
           return;
       }
       tmp = XtMalloc(strlen(nick) + strlen(port) + 2);
       sprintf(tmp, "%s %s", nick, port);
       if (SendMsg(MSG_CLIENT_ALTER_PORT, tmp))
           Disconnect(strerror(errno));
       XtFree(tmp);

   } else if (CmdMatch(cmd, "deop", 2)) {
       if (! srvConn)
           return;
       if (! strlen(data)) {
           ErrMsg("Missing parameters");
           return;
       }
       if (! (channel = strtok(data, " "))) {
           ErrMsg("Missing parameters");
           return;
       }
       if (! (nick = strtok(NULL, " "))) {
           ErrMsg("Missing parameters");
           return;
       }
       tmp = XtMalloc(strlen(channel) + strlen(nick) + 2);
       sprintf(tmp, "%s %s", channel, nick);
       if (SendMsg(MSG_CLIENT_DEOP, tmp))
           Disconnect(strerror(errno));
       XtFree(tmp);

   } else if (CmdMatch(cmd, "disconnect", 2)) {
       if (! srvConn)
           return;
       Disconnect("");

   } else if (CmdMatch(cmd, "gmsg", 1)) {
       if (! srvConn)
           return;
       if (! strlen(data)) {
           ErrMsg("Missing parameters");
           return;
       }
       if (SendMsg(MSG_CLIENT_ANNOUNCE, data))
           Disconnect(strerror(errno));

   } else if (CmdMatch(cmd, "join", 1)) {
       if (! srvConn)
           return;
       if (! strlen(data)) {
           ErrMsg("Missing parameters");
           return;
       }
       JoinChannel(data);

   } else if (CmdMatch(cmd, "kick", 3)) {
       if (! srvConn)
           return;
       if (! strlen(data)) {
           ErrMsg("Missing parameters");
           return;
       }
       if (! (channel = strtok(data, " "))) {
           ErrMsg("Missing parameters");
           return;
       }
       if (! (nick = strtok(NULL, " "))) {
           ErrMsg("Missing parameters");
           return;
       }
       if (! (reason = strtok(NULL, "\0")))
           reason = "";
       tmp = XtMalloc(strlen(channel) + strlen(nick) + strlen(reason) + 5);
       sprintf(tmp, "%s %s \"%s\"", channel, nick, reason);
       if (SendMsg(MSG_CLIENT_KICK_USER, tmp))
           Disconnect(strerror(errno));
       XtFree(tmp);

   } else if (CmdMatch(cmd, "kill", 3)) {
       if (! srvConn)
           return;
       if (! strlen(data)) {
           ErrMsg("Missing parameters");
           return;
       }
       if (! (nick = strtok(data, " "))) {
           ErrMsg("Missing parameters");
           return;
       }
       if (! (reason = strtok(NULL, "\0")))
           reason = "";
       tmp = XtMalloc(strlen(nick) + strlen(reason) + 4);
       sprintf(tmp, "%s \"%s\"", nick, reason);
       if (SendMsg(MSG_CLIENT_KILL, tmp))
           Disconnect(strerror(errno));
       XtFree(tmp);

   } else if (CmdMatch(cmd, "level", 2)) {
       if (! srvConn)
           return;
       if (! strlen(data)) {
           ErrMsg("Missing parameters");
           return;
       }
       if (! (nick = strtok(data, " "))) {
           ErrMsg("Missing parameters");
           return;
       }
       if (! (level = strtok(NULL, "\0"))) {
           ErrMsg("Missing parameters");
           return;
       }
       tmp = XtMalloc(strlen(nick) + strlen(level) + 4);
       sprintf(tmp, "%s %s", nick, level);
       if (SendMsg(MSG_CLIENT_SETUSERLEVEL, tmp))
           Disconnect(strerror(errno));
       XtFree(tmp);

   } else if (CmdMatch(cmd, "links", 3)) {
       if (! srvConn)
           return;
       ListLinks();

   } else if (! strcmp(cmd, "list")) {
       if (! srvConn)
           return;
       ListChannels();

   } else if (CmdMatch(cmd, "listbans", 5)) {
       if (! srvConn)
           return;
       ListBans();

   } else if (! strcmp(cmd, "me")) {
       if (! srvConn)
           return;
       if (! strlen(data)) {
           ErrMsg("Missing parameters");
           return;
       }
       if (! (curChan = FindChanByWin(curWin)))
           return;
       tmp = XtMalloc(strlen(curChan->name) + strlen(data) + 4);
       sprintf(tmp, "%s \"%s\"", curChan->name, data);
       if (SendMsg(MSG_CLIENT_EMOTE, tmp))
           Disconnect(strerror(errno));
       XtFree(tmp);

   } else if (CmdMatch(cmd, "motd", 2)) {
       if (! srvConn)
           return;
       if (SendMsg(MSG_CLIENT_MOTD, ""))
           Disconnect(strerror(errno));

   } else if (CmdMatch(cmd, "msg", 2)) {
       if (! srvConn)
           return;
       if (! strlen(data)) {
           ErrMsg("Missing parameters");
           return;
       }
       if (SendMsg(MSG_CLIENT_PRIVMSG, data))
           Disconnect(strerror(errno));

   } else if (CmdMatch(cmd, "muzzle", 2)) {
       if (! srvConn)
           return;
       if (! strlen(data)) {
           ErrMsg("Missing parameters");
           return;
       }
       if (! (nick = strtok(data, " "))) {
           ErrMsg("Missing parameters");
           return;
       }
       if (! (reason = strtok(NULL, "\0")))
           reason = "";
       tmp = XtMalloc(strlen(nick) + strlen(reason) + 4);
       sprintf(tmp, "%s \"%s\"", nick, reason);
       if (SendMsg(MSG_CLIENT_MUZZLE, tmp))
           Disconnect(strerror(errno));
       XtFree(tmp);

   } else if (CmdMatch(cmd, "online", 2)) {
       if (! srvConn)
           return;
       ListOnLine();

   } else if (! strcmp(cmd, "op")) {
       if (! srvConn)
           return;
       if (! strlen(data)) {
           ErrMsg("Missing parameters");
           return;
       }
       if (SendMsg(MSG_CLIENT_OP, data))
           Disconnect(strerror(errno));

   } else if (CmdMatch(cmd, "opmsg", 3)) {
       if (! srvConn)
           return;
       if (! strlen(data)) {
           ErrMsg("Missing parameters");
           return;
       }
       if (SendMsg(MSG_CLIENT_WALLOP, data))
           Disconnect(strerror(errno));

   } else if (CmdMatch(cmd, "part", 3)) {
       if (! srvConn)
           return;
       if (! strlen(data)) {
           ErrMsg("Missing parameters");
           return;
       }
       PartChannel(data);

   } else if (CmdMatch(cmd, "ping", 2)) {
       if (! srvConn)
           return;
       if (! strlen(data)) {
           ErrMsg("Missing parameters");
           return;
       }
       Ping(data);

   } else if (CmdMatch(cmd, "quit", 1)) {
       Quit();

   } else if (CmdMatch(cmd, "search", 3)) {
       if (! srvConn)
           return;
       if (! strlen(data))
           Search();
       else {
           XtFree(search.artist);
           XtFree(search.title);
           search.artist = XtNewString(data);
           search.title = XtNewString("");
           Search2();
       }

   } else if (CmdMatch(cmd, "server", 3)) {
       if (! strlen(data)) {
           ConfigWin(SERVER_PAGE);
       } else {
           if (! SplitServer(data, &server, &portString, &metaString)) {
               ErrMsg("Invalid format");
               return;
           }
           if (srvConn)
               Disconnect("");
           Connect(server, atoi(portString), atoi(metaString), 1);
       }

   } else if (CmdMatch(cmd, "stats", 2)) {
       ShowServerStats();

   } else if (CmdMatch(cmd, "topic", 2)) {
       if (! srvConn)
           return;
       if (! strlen(data)) {
           ErrMsg("Missing parameters");
           return;
       }
       if (! (channel = strtok(data, " "))) {
           ErrMsg("Missing parameters");
           return;
       }
       if (! (topic = strtok(NULL, "\0"))) {
           ErrMsg("Missing parameters");
           return;
       }
       tmp = XtMalloc(strlen(channel) + strlen(topic) + 4);
       sprintf(tmp, "%s %s", channel, topic);
       if (SendMsg(MSG_SERVER_TOPIC, tmp))
           Disconnect(strerror(errno));
       XtFree(tmp);

   } else if (CmdMatch(cmd, "ullist", 2)) {
       ListUploads();

   } else if (CmdMatch(cmd, "unban", 3)) {
       if (! srvConn)
           return;
       if (! strlen(data)) {
           ErrMsg("Missing parameters");
           return;
       }
       if (SendMsg(MSG_CLIENT_UNBAN, data))
           Disconnect(strerror(errno));

   } else if (CmdMatch(cmd, "unmuzzle", 3)) {
       if (! srvConn)
           return;
       if (! strlen(data)) {
           ErrMsg("Missing parameters");
           return;
       }
       if (SendMsg(MSG_CLIENT_UNMUZZLE, data))
           Disconnect(strerror(errno));

   } else if (CmdMatch(cmd, "usermode", 5)) {
       if (! srvConn)
           return;
       if (SendMsg(MSG_CLIENT_USER_MODE, data))
           Disconnect(strerror(errno));

   } else if (CmdMatch(cmd, "version", 1)) {
       if (! srvConn)
           return;
       if (SendMsg(MSG_CLIENT_SERVER_VERSION, ""))
           Disconnect(strerror(errno));

   } else if (CmdMatch(cmd, "whois", 1)) {
       if (! srvConn)
           return;
       if (! strlen(data)) {
           ErrMsg("Missing parameters");
           return;
       }
       Whois(data);

   } else {
       ErrMsg("Invalid or ambiguous command");
   }
}


void SendAutoCommands(void)
{
   AUTOCOMMAND *ac;
   String tmp = XtMalloc(256);

   for (ac = autoCommands; ac; ac = ac->next) {
       sprintf(tmp, "/%s", ac->data);
       CmdParse(tmp);
   }
   XtFree(tmp);
}