/*
*  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 <unistd.h>
#include <errno.h>

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


/* #define DEBUG */


int SendMsg(int type, String msg)
{
   unsigned short slen, stype;

   slen = BSWAP16((unsigned short)strlen(msg));
   stype = BSWAP16((unsigned short)type);

   memcpy(Buf, &slen, 2);
   memcpy(Buf + 2, &stype, 2);
   strcpy(Buf + 4, msg);

   return(WriteSock(Buf, strlen(msg) + 4));
}


void GetMsg(XtPointer closure, int *sock, XtInputId *id)
{
   unsigned short type, len;
   int n;
   char tmp[1024], *p;
   XmString xms;

   if ((n = ReadChars(srvSock, &len, 2)) < 2) {
       if (autoReconnect)
           WaitReconnect();
       else
           Disconnect("Server EOF");
       return;
   }
   len = BSWAP16(len);

   if ((n = ReadChars(srvSock, &type, 2)) < 2) {
       if (autoReconnect)
           WaitReconnect();
       else
           Disconnect("Server EOF");
       return;
   }
   type = BSWAP16(type);

   memset(Buf, 0, sizeof(Buf));
   if ((n = ReadChars(srvSock, Buf, len)) < len) {
       if (autoReconnect)
           WaitReconnect();
       else
           Disconnect("Server EOF");
       return;
   }

#ifdef DEBUG
   printf("type: %d  message: %s\n", type, Buf);
#endif

   switch(type) {
       case MSG_SERVER_ERROR:
           if (autoReconnect)
               ShowMiscInfo(Buf, 0);
           else
               ErrMsg(Buf);
           break;

       case MSG_SERVER_EMAIL:
           xms = XmStringCreateLocalized(realSrvName);
           XtVaSetValues(statusLbl1, XmNlabelString, xms, NULL);
           XmStringFree(xms);
           XtAppAddTimeOut(appCon, 50,
                   (XtTimerCallbackProc)DoLoginStuff, NULL);
           break;

       case MSG_SERVER_REGISTER_OK:
           sprintf(tmp, "%s %s %04d \"%s\" %d %s",
                   userInfo.userName, userInfo.passWord,
                   userInfo.dataPort, client, userInfo.linkType,
                   userInfo.eMail);

           if (SendMsg(MSG_CLIENT_LOGIN_REGISTER, tmp)) {
               Disconnect(strerror(errno));
               return;
           }
           userInfo.registered = 1;
           WriteConfig();
           break;

       case MSG_SERVER_REGISTER_FAIL:
           Disconnect("Nick name already registered");
           break;

       case MSG_SERVER_BAD_NICK:
           Disconnect("Invalid nick name");
           break;

       case MSG_SERVER_PASS_OK:

           break;

       case MSG_SERVER_SEARCH_RESULT:
           AddResult(Buf, 0);
           break;

       case MSG_SERVER_SEARCH_END:
           ShowResults(0);
           break;

       case MSG_SERVER_FILE_READY:
           (void)strtok(Buf, " ");
           destIp = BSWAP32(strtoul(strtok(NULL, " "), NULL, 10));
           destPort = atoi(strtok(NULL, " "));
           break;

       case MSG_CLIENT_PRIVMSG:
           RcvGlobal(type, Buf);
           break;

       case MSG_SERVER_SEND_ERROR:

           break;

       case MSG_SERVER_USER_SIGNON:
           UserSignOn(Buf);
           break;

       case MSG_SERVER_USER_SIGNOFF:
           UserSignOff(Buf);
           break;

       case MSG_SERVER_BROWSE_RESPONSE:
           AddResult(Buf, 1);
           break;

       case MSG_SERVER_BROWSE_END:
           ShowResults(1);
           break;

       case MSG_SERVER_STATS:
           p = strtok(Buf, " ");
           sprintf(tmp, "Users: %s", p);
           p = strtok(NULL, " ");
           sprintf(tmp, "%s  Files: %s", tmp, p);
           xms = XmStringCreateLocalized(tmp);
           XtVaSetValues(statusLbl2, XmNlabelString, xms, NULL);
           XmStringFree(xms);
           break;

       case MSG_SERVER_HOTLIST_ACK:

           break;

       case MSG_SERVER_IGNORE_ENTRY:

           break;

       case MSG_SERVER_NOT_IGNORED:

           break;

       case MSG_SERVER_ALREADY_IGNORED:

           break;

       case MSG_CLIENT_PART:
           DoPartChannel(Buf);
           break;

       case MSG_SERVER_PUBLIC:
           RcvChannel(type, Buf);
           break;

       case MSG_SERVER_NOSUCH:
           ShowMiscInfo(Buf, 0);
           break;

       case MSG_SERVER_JOIN_ACK:
           DoJoinChannel(Buf);
           break;

       case MSG_SERVER_JOIN:
           UpdateUserList(type, Buf);
           break;

       case MSG_SERVER_PART:
           UpdateUserList(type, Buf);
           break;

       case MSG_SERVER_CHANNEL_USER_LIST:
           UpdateUserList(type, Buf);
           break;

       case MSG_SERVER_CHANNEL_USER_LIST_END:

           break;

       case MSG_SERVER_TOPIC:
           RcvChannel(type, Buf);
           break;

       case MSG_SERVER_CHANNEL_BAN_LIST:

           break;

       case MSG_SERVER_UPLOAD_FIREWALL:
           FwUpload(Buf);
           break;

       case MSG_SERVER_USER_SPEED:

           break;

       case MSG_SERVER_WHOIS_RESPONSE:
           ShowWhois(Buf);
           break;

       case MSG_SERVER_WHOWAS:
           ShowWhowas(Buf);
           break;

       case MSG_SERVER_UPLOAD_REQUEST:
           p = strtok(Buf, " ");
           strcpy(tmp, p);
           p = strtok(NULL, "\"");
           sprintf(tmp, "%s \"%s\"", tmp, p);
           if (SendMsg(MSG_CLIENT_UPLOAD_OK, tmp))
               Disconnect(strerror(errno));
           break;

       case MSG_CLIENT_ALTER_PORT:
           SetDataPort(atoi(Buf), 0);
           break;

       case MSG_CLIENT_BANLIST:
           DoListBans();
           break;

       case MSG_SERVER_IP_BANLIST:
           AddBan(Buf);
           break;

       case MSG_SERVER_CHANNEL_LIST_END:
           DoListChannels();
           break;

       case MSG_SERVER_CHANNEL_LIST:
           AddChannel(Buf);
           break;

       case MSG_SERVER_LIMIT:

           break;

       case MSG_SERVER_MOTD:
           ShowMiscInfo(Buf, 1);
           break;

       case MSG_SERVER_DATA_PORT_ERROR:

           break;

       case MSG_SERVER_WALLOP:
           RcvGlobal(type, Buf);
           break;

       case MSG_SERVER_ANNOUNCE:
           RcvGlobal(type, Buf);
           break;

       case MSG_SERVER_NICK_BANLIST:

           break;

       case MSG_SERVER_PING:
           RcvGlobal(type, Buf);
           break;

       case MSG_SERVER_PONG:
           RcvGlobal(type, Buf);
           break;

       case MSG_SERVER_NAMES_LIST:

           break;

       case MSG_SERVER_FULL_CHANNEL_INFO:

           break;

       case MSG_SERVER_NAMES_LIST_END:

           break;

       case MSG_SERVER_GLOBAL_USER_LIST:

           break;

       case MSG_CLIENT_EMOTE:
           RcvChannel(type, Buf);
           break;

       case MSG_SERVER_LINKS:
           if (! strlen(Buf))
               DoListLinks();
           else
               AddLink(Buf);
           break;

       case MSG_SERVER_USAGE_STATS:
           DoShowServerStats(Buf);
           break;

       case MSG_SERVER_USER_MODE:
           ShowMiscInfo(Buf, 0);
           break;
   }

   usleep(1000);
}