/*********************************************
Header file for ICQ protocol structres and
constants

This software is provided AS IS to be used in
whatever way you see fit and is placed in the
public domain.

Author : Jeremy Wise <jwise@pathwaynet.com>
**********************************************/

#include "datatype.h"
#include <stdlib.h>
#include <stdio.h>

#ifdef HAVE_CONFIG_H
	#include <config.h>
#endif

#include <gtk/gtk.h>

#include "gtkfunc.h"

#include "dialog.h"

#ifndef _GTKICQ_H
#define _GTKICQ_H

#define AUTO_AWAY 10 /* Turn to away mode after 10 minutes */
#define AUTO_NA   20 /* Turn to n/a mode after 20 minutes */

#define ICQ_VER 0x0004

#define STDIN 0
#define STDOUT 1
#define STDERR 2

#define PACKET_TYPE_TCP          1
#define PACKET_TYPE_UDP          2

#define PACKET_DIRECTION_SEND    4
#define PACKET_DIRECTION_RECEIVE 8

typedef struct _ProgressData {
  GtkWidget *pbar;
  int timer;
} ProgressData;

   typedef struct
   {
      BYTE dummy[2]; /* to fix alignment problem */
      BYTE ver[2];
      BYTE rand[2];
      BYTE zero[2];
      BYTE cmd[2];
      BYTE seq[2];
      BYTE seq2[2];
      BYTE  UIN[4];
      BYTE checkcode[4];
   } ICQ_pak, *ICQ_PAK_PTR;

   typedef struct
   {
      WORD dummy; /* to fix alignment problem */
      BYTE ver[2];
      BYTE cmd[2];
      BYTE seq[2];
      BYTE seq2[2];
      BYTE UIN[4];
      BYTE check[4];
   } SRV_ICQ_pak, *SRV_ICQ_PAK_PTR;

typedef struct
{
   ICQ_pak  head;
   unsigned char  data[1024];
} net_icq_pak, *NET_ICQ_PTR;

typedef struct
{
   SRV_ICQ_pak  head;
   unsigned char  data[1024];
} srv_net_icq_pak, *SRV_NET_ICQ_PTR;

#define CMD_ACK                0x000A 
#define CMD_SENDM              0x010e
#define CMD_LOGIN              0x03e8
#define CMD_CONT_LIST          0x0406
#define CMD_SEARCH_UIN         0x041a
#define CMD_SEARCH_USER        0x0424
#define CMD_KEEP_ALIVE         0x042e
#define CMD_KEEP_ALIVE2        0x051e
#define CMD_SEND_TEXT_CODE     0x0438
#define CMD_LOGIN_1            0x044c
#define CMD_INFO_REQ           0x0460
#define CMD_EXT_INFO_REQ       0x046a
#define CMD_CHANGE_PW          0x049c
#define CMD_STATUS_CHANGE      0x04d8
#define CMD_LOGIN_2            0x0528
#define CMD_UPDATE_INFO        0x050a
#define CMD_UPDATE_EXT_INFO    0x04b0
#define CMD_ADD_TO_LIST        0x053c
#define CMD_REQ_ADD_LIST       0x0456
#define CMD_QUERY_SERVERS      0x04ba
#define CMD_QUERY_ADDONS       0x04c4
#define CMD_NEW_USER_1         0x04eC
#define CMD_NEW_USER_REG       0x03fC
#define CMD_NEW_USER_INFO      0x04a6
#define CMD_ACK_MESSAGES       0x0442
#define CMD_MSG_TO_NEW_USER    0x0456
#define CMD_REG_NEW_USER       0x03fc
#define CMD_VIS_LIST           0x06ae
#define CMD_INVIS_LIST         0x06a4
#define CMD_WEBPRESENCE_1      0x064a
#define CMD_WEBPRESENCE_2      0x04d8

#define SRV_ACK                0x000a
#define SRV_LOGIN_REPLY        0x005a
#define SRV_USER_ONLINE        0x006e
#define SRV_USER_OFFLINE       0x0078
#define SRV_USER_FOUND         0x008c
#define SRV_RECV_MESSAGE       0x00dc
#define SRV_END_OF_SEARCH      0x00a0
#define SRV_INFO_REPLY         0x0118
#define SRV_EXT_INFO_REPLY     0x0122
#define SRV_STATUS_UPDATE      0x01a4
#define SRV_X1                 0x021c
#define SRV_X2                 0x00e6
#define SRV_UPDATE             0x01e0
#define SRV_UPDATE_EXT         0x00c8
#define SRV_NEW_UIN            0x0046
#define SRV_NEW_USER           0x00b4
#define SRV_QUERY              0x0082
#define SRV_SYSTEM_MESSAGE     0x01c2
#define SRV_SYS_DELIVERED_MESS 0x0104
#define SRV_GO_AWAY            0x00f0
#define SRV_TRY_AGAIN          0x00fa
#define SRV_FORCE_DISCONNECT   0x0028
#define SRV_MULTI_PACKET       0x0212
#define SRV_WEBPRESENCE_ACK    0x03de
#define SRV_BAD_PASSWORD       0x0064

#define STATUS_OFFLINE         (-1L)
#define STATUS_ONLINE          0x00
#define STATUS_INVISIBLE       0x100
#define STATUS_NA_99A          0x04
#define STATUS_NA              0x05
#define STATUS_FREE_CHAT       0x20
#define STATUS_OCCUPIED_MAC    0x10
#define STATUS_OCCUPIED        0x11
#define STATUS_AWAY            0x01
#define STATUS_DND             0x13

#define NORM_MESSAGE           0x0001
#define URL_MESS	       0x0004
#define AUTH_REQ_MESS          0x0006
#define AUTH_MESSAGE           0x0008
#define USER_ADDED_MESS        0x000c
#define CONTACT_MESSAGE        0x0013

   typedef struct
   {
      BYTE time[4];
      BYTE port[4];
      BYTE len[2];
   } login_1, *LOGIN_1_PTR;

   typedef struct
   {
      BYTE X1[4];
      BYTE ip[4];
      BYTE  X2[1];
      BYTE  status[4];
      BYTE X3[4];
   /*   BYTE seq[2];*/
      BYTE  X4[4];
      BYTE X5[4];
   } login_2, *LOGIN_2_PTR;

   /* those behind the // are for the spec on
    http://www.student.nada.kth.se/~d95-mih/icq/
    they didn't work for me so I changed them
    to values that did work.
    *********************************/
   /*#define LOGIN_X1_DEF 0x00000078 */
   #define LOGIN_X1_DEF 0x00000098
/*   #define LOGIN_X2_DEF 0x04*/
   #define LOGIN_X2_DEF 0x04
   /*#define LOGIN_X3_DEF 0x00000002*/
   #define LOGIN_X3_DEF 0x00000003
   /*#define LOGIN_X4_DEF 0x00000000*/
   #define LOGIN_X4_DEF 0x00000000
   /*#define LOGIN_X5_DEF 0x00780008*/
   #define LOGIN_X5_DEF 0x00980000

typedef struct
{
   BYTE   uin[4];
   BYTE year[2];
   BYTE  month;
   BYTE  day;
   BYTE  hour;
   BYTE  minute;
   BYTE type[2];
   BYTE len[2];
} RECV_MESSAGE, *RECV_MESSAGE_PTR;

typedef struct
{
   BYTE uin[4];
   BYTE type[2]; 
   BYTE len[2];
} SIMPLE_MESSAGE, *SIMPLE_MESSAGE_PTR;

typedef struct
{
   DWORD uin;
   DWORD status;
   DWORD last_status;
   DWORD true_status;
   DWORD lb_index;
   DWORD last_time; /* last time online or when came online */
   DWORD current_ip;
   DWORD port;
   int tcp_gdk_input;
   int chat_gdk_input;
   FILE *chat_file;
   GtkWidget *chat_local_text;
   GtkWidget *chat_remote_text;
   SOK_T sok;
   SOK_T chat_sok;
   BYTE chat_active;
   BYTE chat_active2;
   DWORD chat_seq;
   int chat_port;
   BYTE chat_fg_red, chat_fg_green, chat_fg_blue;
   BYTE chat_bg_red, chat_bg_green, chat_bg_blue;
   BYTE nick[20];
   GtkWidget *list_item;
   GdkPixmap *icon_p;
   GdkBitmap *icon_b;
   WORD messages;
   BYTE **message;
   GtkWidget *log_window;
   GtkWidget *log_list;
   BOOL invis_list;
   BOOL vis_list;
   GtkWidget *info_uin;
   GtkWidget *info_ip;
   GtkWidget *info_nick;
   GtkWidget *info_city;
   GtkWidget *info_state;
   GtkWidget *info_sex;
   GtkWidget *info_phone;
   GtkWidget *info_homepage;
   GtkWidget *info_about;
   GtkWidget *info_fname;
   GtkWidget *info_lname;
   GtkWidget *info_email;
   GtkWidget *info_auth;
   GtkWidget *read_next;
   int wait;
   ProgressData *pdata;
   int need_update;
   int gdk_input_tag;
} Contact_Member, *CONTACT_PTR;

typedef struct
{
   char *nick;
   char *first;
   char *last;
   char *email;
   BOOL auth;
} USER_INFO_STRUCT, *USER_INFO_PTR;

void configure_window( GtkWidget *widget, struct sokandlb *data );
void toggle_switch( GtkWidget *widget, int *toggle_me );
void Keep_Alive( int sok );
void snd_got_messages( int sok );
void snd_contact_list( int sok );
void snd_invis_list( int sok );
void snd_vis_list( int sok );
void snd_login_1( int sok );
void Status_Update( int sok, srv_net_icq_pak pak );
void Login( int sok, int UIN, char *pass, int ip, int port );
void ack_srv( int sok, int seq );
void User_Offline( int sok, srv_net_icq_pak pak );
void User_Online( int sok, srv_net_icq_pak pak );
char *Convert_Status_2_Str( int status );
char *Convert_Status_2_Short( int status );
void Print_Status( DWORD new_status );
char *Print_Status_Short( DWORD new_status );
int Save_RC( void );

void Get_Input( struct sokandlb *data );

void Quit_ICQ( SOK_T sok );
void icq_sendmsg( SOK_T sok, DWORD uin, char *text, struct sokandlb *data, int forced );
void icq_sendurl( GtkWidget *widget, struct URLInfo *data );
void Recv_Message( SOK_T sok, srv_net_icq_pak pak, struct sokandlb *data );
int Print_UIN_Name( DWORD uin );
char *Get_UIN_Name( DWORD uin, char *buf );
void icq_change_status( SOK_T sok, DWORD status, struct sokandlb *data );
DWORD nick2uin( char * nick );
S_DWORD Echo_On( void );
S_DWORD Echo_Off( void );
void send_info_req( SOK_T sok, DWORD uin );
void send_ext_info_req( SOK_T sok, DWORD uin );
void Print_IP( DWORD uin );
void Display_Info_Reply( int sok, srv_net_icq_pak pak, struct sokandlb *data );
WORD Chars_2_Word( unsigned char *buf );
DWORD Chars_2_DW( unsigned char *buf );
DWORD Get_Port( DWORD uin );
void log_window_add( char *statement, int stamped, int uin );

int Show_Quick_Status( struct sokandlb *data );
int Build_Main_Window( struct sokandlb *data );

void icq_sendauthmsg( SOK_T sok, DWORD uin);
int Do_Msg( DWORD type, char *data, DWORD uin, struct sokandlb *sldata, char message_type );
int Do_Chat( DWORD type, char *data, DWORD uin, struct sokandlb *sldata, DWORD seq );
void DW_2_Chars( unsigned char *buf, DWORD num );
void Word_2_Chars( unsigned char *buf, WORD num );
void Prompt( void );
void Time_Stamp( void );
void Add_User( SOK_T sok, DWORD uin, char *name );
void start_search( SOK_T sok, char *email, char *nick, char* first, char* last, DWORD uin );
void Display_Search_Reply( int sok, srv_net_icq_pak pak );
void rus_conv(char to[4],char *t_in);
void reg_new_user( SOK_T sok, char *pass);
void clrscr(void);
void auto_away( struct sokandlb *data );
int flash_messages( struct sokandlb *data );
GtkWidget *main_menu( struct sokandlb *data );
void add_incoming_to_history( int uin, char *statement );
void add_outgoing_to_history( int uin, char *statement );
void toggle_sound( GtkWidget *widget, gpointer data );
void toggle_packet( GtkWidget *widget, gpointer data );
void packet_print( BYTE *packet, int size, int type );
int show_wait( char *label_str, ProgressData *pdata );
int Connect_Remote( char *hostname, int port, FD_T aux );
void progress_bar_make( void );
void NewUserSignup( void );
void Update_User_Info( SOK_T sok, USER_INFO_PTR user);
size_t SOCKWRITE( SOK_T sok, void *ptr, size_t len );
size_t SOCKREAD( SOK_T sok, void *ptr, size_t len );
void ready_set( void );

void Get_Unix_Config_Info( void );

extern void Display_Ext_Info_Reply( int sok, srv_net_icq_pak pak );
extern void Handle_Server_Response( struct sokandlb *data );
extern GdkPixmap *GetIcon_p( DWORD status );
extern GdkBitmap *GetIcon_b( DWORD status );

extern Contact_Member Contacts[ 200 ]; /* no more than 100 contacts max */
extern int Num_Contacts;
extern BOOL serv_mess[ 1024 ];
extern BOOL Int_End;
extern DWORD UIN; /* current User Id Number */
extern char nickname[30];
extern BOOL Contact_List;
extern WORD last_cmd[ 1024 ]; /* command issued for the first 1024 SEQ #'s */
/******************** should use & 0x3ff on all references to this */
extern WORD seq_num;  /* current sequence number */
extern DWORD our_ip;
extern DWORD our_port; /* the port to make tcp connections on */
extern BOOL Quit;
extern BOOL Verbose;
extern DWORD Current_Status;
extern DWORD last_recv_uin;
extern char passwd[100];
extern char server[100];
extern DWORD remote_port;
extern DWORD set_status;
extern char Away_Message[256];
extern BOOL Done_Login;
extern int connecting;

extern BOOL Russian;
extern BOOL Logging;

extern BOOL search_in_progress;
extern GtkWidget *log_list;
extern GtkWidget *log_window;

extern int sound_toggle;
extern int beep_toggle;
extern int packet_toggle;
extern int force_toggle;
extern int webpresence_toggle;

/* Sound variables added by Paul Laufer [PEL] */
extern int UserOnline;
extern char UserOnlineSound[256];
extern int UserOffline;
extern char UserOfflineSound[256];
extern int RecvMessage;
extern char RecvMessageSound[256];
extern int RecvChat;
extern char RecvChatSound[256];
/* end sound vars */

#if 0
extern WORD system_messages;
extern BYTE **system_message;
#endif

extern BYTE chat_fg_red, chat_fg_green, chat_fg_blue;
extern BYTE chat_bg_red, chat_bg_green, chat_bg_blue;

extern GtkWidget *statusbar;
extern unsigned int sound_pid;

extern GtkWidget *progress_indicator;
extern GtkTooltips *status_tooltip;

extern int is_new_user;

extern USER_INFO_STRUCT our_user_info;

extern char WindowTitle[256];
extern int WindowWidth, WindowHeight;

extern char configfilename[256];

extern int tcp_gdk_input;
extern int udp_gdk_input;

extern unsigned int next_resend;

extern struct sokandlb *MainData;

extern int Connected;

extern GdkFont *ChatFont;
extern char ChatFontString[256];

void strip_quote( char *string );
int Read_RC_File( void ) ;
int Initalize_RC_File( void );
int Create_RC_File( void );

void toggle_log_window( GtkWidget *widget, gpointer data );
extern GdkColor color_online, color_offline, color_away, color_na, color_ffc, color_occ, color_dnd, color_inv;
extern int color_online_set, color_offline_set, color_away_set, color_na_set, color_ffc_set, color_occ_set, color_dnd_set, color_inv_set;
void init_colors( struct sokandlb *data );
void restart( struct sokandlb *data );
void Do_Resend( SOK_T sok );

void icq_sendwebpresence( SOK_T sok );
void icq_finishwebpresence( SOK_T sok );

#endif
