/*ProfiPacket - packet radio terminal program
  Copyright (C) 1999  Alexander Feigl

  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; if not, write to the Free Software
  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

  Author:

  Alexander Feigl
  Burachstraße 51

  D-88250 Weingarten

  Mail : Alexander.Feigl@gmx.de
*/


#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include "GUIProtos.h"
#include "global.h"
#include "QSO.h"
#include "Preferences.h"
#include "Server.h"

#include <libraries/mui.h>

#include <libraries/asl.h>

#include <devices/timer.h>

#include <exec/lists.h>
#include <exec/memory.h>
#include <dos/exall.h>


#include <clib/muimaster_protos.h>
#include <clib/exec_protos.h>
#include <clib/dos_protos.h>
#include <clib/alib_protos.h>
#include <clib/intuition_protos.h>
#include <clib/utility_protos.h>

#ifdef __GNUC__


extern void *DOSBase;
extern void *SysBase;
extern void *IntuitionBase;
extern void *UtilityBase;
extern void *MUIMasterBase;

#define NO_INLINE_STDARG
#include <inline/muimaster.h>
#include <inline/dos.h>
#include <inline/exec.h>
#include <inline/intuition.h>
#include <inline/utility.h>

#endif

extern Object *ConnectMsgWindow;

#ifndef MAKE_ID
#define MAKE_ID(a,b,c,d) ((ULONG) (a)<<24 | (ULONG) (b)<<16 | (ULONG) (c)<<8 | (ULONG) (d))
#endif

void FillHook(struct Hook *MyHook,void (*Function)(),void *FunctionData);


void GUIMISC_SaveBufferClose(struct Hook *MyHook,unsigned long *Param,void *Object,
                         void *Data);

void GUIMISC_ConnectHook(struct Hook *MyHook,unsigned long *Param,void *Object,
                         void *Data);

void GUIMISC_SpyHook(struct Hook *MyHook,unsigned long *Param,void *Object,
                         void *Data);


void GUIMISC_ConnectMsgHook(struct Hook *MyHook,unsigned long *Param,void *Object,
                         void *Data);


void GUIMISC_UserDataHook(struct Hook *MyHook,unsigned long *Param,void *Object,
                         void *Data);


void GUIMISC_EncryptionHook(struct Hook *MyHook,unsigned long *Param,void *Object,
                         void *Data);



#define sbobject(xx) GlobalArraysP->SaveBObjects[xx]
#define coobject(xx) GlobalArraysP->ConnectObjects[xx]
#define cmobject(xx) GlobalArraysP->ConnectMsgObjects[xx]
#define spobject(xx) GlobalArraysP->SpyObjects[xx]
#define udobject(xx) GlobalArraysP->UserDataObjects[xx]
#define enobject(xx) GlobalArraysP->EncryptionObjects[xx]

void GUIMISC_AboutMUI(void)
{
 DoMethod(Application,MUIM_Application_AboutMUI,MainWindow);
}

void GUIMISC_ConfigMUI(void)
{
 DoMethod(Application,MUIM_Application_OpenConfigWindow,0);
}

void GUIMISC_SaveBuffers(void)
{

  if (SaveBufferWindow==NULL)
   {

     GlobalArraysP->SaveBArray1[0]=GUI_String(450);
     GlobalArraysP->SaveBArray1[1]=GUI_String(451);
     GlobalArraysP->SaveBArray1[2]=NULL;

     GlobalArraysP->SaveBArray2[0]=GUI_String(453);
     GlobalArraysP->SaveBArray2[1]=GUI_String(454);
     GlobalArraysP->SaveBArray2[2]=NULL;

     GlobalArraysP->SaveBArray3[0]=GUI_String(456);
     GlobalArraysP->SaveBArray3[1]=GUI_String(457);
     GlobalArraysP->SaveBArray3[2]=GUI_String(458);
     GlobalArraysP->SaveBArray3[3]=NULL;

     GlobalArraysP->SaveBArray4[0]=GUI_String(460);
     GlobalArraysP->SaveBArray4[1]=GUI_String(461);
     GlobalArraysP->SaveBArray4[2]=GUI_String(462);
     GlobalArraysP->SaveBArray4[3]=NULL;


     FillHook(&HooksP->SaveBufferClose,(void *) GUIMISC_SaveBufferClose,NULL);


     SaveBufferWindow =
                 WindowObject,
                     MUIA_Window_Title, GUI_String(463),
                     MUIA_Window_ID   , MAKE_ID('S','B','U','F'),

                     WindowContents,

                       VGroup,
                         Child,ColGroup(2),

                               Child,Label2(GUI_String(448)),
                               Child,sbobject(0)=PopaslObject,
                                       MUIA_Popstring_String,String(Preferences.SaveDir,196),
                                       MUIA_Popstring_Button,PopButton(MUII_PopFile),
                                       ASLFR_TitleText,GUI_String(463),
                                       End,

                               Child,Label(GUI_String(449)),
                               Child,sbobject(1)=Cycle(GlobalArraysP->SaveBArray1),

                               Child,Label(GUI_String(452)),
                               Child,sbobject(2)=Cycle(GlobalArraysP->SaveBArray2),

                               Child,Label(GUI_String(455)),
                               Child,sbobject(3)=Cycle(GlobalArraysP->SaveBArray3),

                               Child,Label(GUI_String(459)),
                               Child,sbobject(4)=Cycle(GlobalArraysP->SaveBArray4),


                               End,
                         Child,HGroup,
                               Child,sbobject(5)=SimpleButton(GUI_String(262)),
                               End,
                         End,
                     End;

    if (SaveBufferWindow==NULL)
        {
            GUI_LowMemory();
            return;
        }

    DoMethod(Application,OM_ADDMEMBER,SaveBufferWindow);

    {
     unsigned long i;
     for (i=0;i<6;++i)
      {
       set(sbobject(i),MUIA_CycleChain,1);
      }

    }

    DoMethod(SaveBufferWindow,MUIM_Notify,MUIA_Window_CloseRequest,TRUE,
             SaveBufferWindow,3,MUIM_CallHook,&HooksP->SaveBufferClose,FALSE);

    DoMethod(sbobject(5),MUIM_Notify,MUIA_Pressed,FALSE,
             SaveBufferWindow,3,MUIM_CallHook,&HooksP->SaveBufferClose,TRUE);

   }


  {
   unsigned long status;

   get(SaveBufferWindow,MUIA_Window_Open,&status);
   if (status==TRUE) return;
  }



 set(SaveBufferWindow,MUIA_Window_Open,TRUE);
 return;
}

void GUIMISC_SaveBufferClose(struct Hook *MyHook,unsigned long *Param,void *Object,
                         void *Data)
{

 unsigned long buffertype;
 unsigned long area;
 unsigned long outputformat;
 unsigned long linefeedtype;

 unsigned char *filename;

 unsigned long mode,marked,page;

 void *bufferobject;

 set (SaveBufferWindow,MUIA_Window_Open,FALSE);
 if (*(Param)==FALSE) return;

 get(sbobject(0),MUIA_String_Contents,&filename);
 get(sbobject(1),MUIA_Cycle_Active,&buffertype);
 get(sbobject(2),MUIA_Cycle_Active,&area);
 get(sbobject(3),MUIA_Cycle_Active,&outputformat);
 get(sbobject(4),MUIA_Cycle_Active,&linefeedtype);

 mode=0;

 switch (outputformat)
  {
   case 0:
     mode|=MUIV_Editor_ImExMode_NoANSI|MUIV_Editor_ImExMode_AmChar;
     break;
   case 1:
     mode|=MUIV_Editor_ImExMode_NoANSI|MUIV_Editor_ImExMode_PCChar;
     break;
   case 2:
     mode|=MUIV_Editor_ImExMode_AmChar;
     break;
  }

 switch (linefeedtype)
  {
   case 0:
     mode|=MUIV_Editor_ImExMode_LF;
     break;
   case 1:
     mode|=MUIV_Editor_ImExMode_CRLF;
     break;
   case 2:
     mode|=MUIV_Editor_ImExMode_CR;
     break;
  }

 marked= (area==0)?FALSE:TRUE;

 page=0;
 bufferobject=NULL;

 if (ActiveChannel==0)
  {
   bufferobject=GlobalArraysP->MainObjects[15];
   page=0;
  }

 if (ActiveChannel>0)
  {
   bufferobject=GlobalArraysP->MainObjects[14];
   page=ActiveChannel-1;
  }
 if (ActiveChannel<0)
  {
   bufferobject=GlobalArraysP->MainObjects[14];
   page=(-ActiveChannel-1)+MaxChannel;
  }

 if (buffertype==1)
  {
   bufferobject=GlobalArraysP->MainObjects[15];
   page=0;
  }

  {
   BPTR file;
   signed long Error;
   Error=0;
   file=Open(filename,MODE_NEWFILE);
   if (file==NULL)
    {
     Error=MUIV_Editor_Return_Disk_DiskError;
    }
    else
    {
     Error=DoMethod(bufferobject,MUIM_Editor_ExportPage,file,page,mode,marked);
     Close (file);
    }
   if (Error!=0) GUI_DisplayEventWindow(GUI_String(464));

  }

}

void GUIMISC_MakeConnect(void)
{
  unsigned long i,j;
  if (ConnectWindow==NULL)
   {

     j=0;
     for (i=0;i<8;++i)
      {
       struct TNCDevice *dev;
       dev=&(Preferences.Devices[i]);
       if ( (dev->ExecDevice[0]=='\0') || (dev->GlobalMycall[0]=='\0') ||
            (dev->Channels==0) ) continue;
       GlobalArraysP->ConnectArray1[j]=dev->Description;
       ++j;
      }
     GlobalArraysP->ConnectArray1[j]=NULL;


     j=0;
     for (i=0;i<8;++i)
      {
       struct Callset *cals;
       cals=&(Preferences.Callsets[i]);
       if (cals->MyCall[0]=='\0') continue;
       GlobalArraysP->ConnectArray2[j]=cals->MyCall;
       ++j;
      }
     GlobalArraysP->ConnectArray2[j]=NULL;


     FillHook(&HooksP->ConnectHook,(void *) GUIMISC_ConnectHook,NULL);


     ConnectWindow =
                 WindowObject,
                     MUIA_Window_Title, GUI_String(465),
                     MUIA_Window_ID   , MAKE_ID('C','O','N','N'),

                     WindowContents,

                       VGroup,
                          Child,ColGroup(2),
                            Child,Label2(GUI_String(466)),
                            Child,coobject(1)=String(NULL,12),

                            Child,Label2(GUI_String(467)),
                            Child,coobject(2)=String(NULL,256),

                            Child,Label(GUI_String(468)),
                            Child,coobject(3)=Cycle(GlobalArraysP->ConnectArray1),

                            Child,Label(GUI_String(469)),
                            Child,coobject(4)=Cycle(GlobalArraysP->ConnectArray2),

                            End,

                         Child,coobject(0)=SimpleButton(GUI_String(470)),

                         End,
                     End;

    if (ConnectWindow==NULL)
        {
            GUI_LowMemory();
            return;
        }


    set(coobject(1),MUIA_String_AdvanceOnCR,TRUE);
    set(coobject(2),MUIA_String_AdvanceOnCR,TRUE);


    DoMethod(Application,OM_ADDMEMBER,ConnectWindow);


    {
     unsigned long i;
     for (i=0;i<5;++i)
      {
       set(coobject(i),MUIA_CycleChain,1);
      }

    }

    DoMethod(ConnectWindow,MUIM_Notify,MUIA_Window_CloseRequest,TRUE,
             ConnectWindow,3,MUIM_CallHook,&HooksP->ConnectHook,0);

    DoMethod(coobject(0),MUIM_Notify,MUIA_Pressed,FALSE,
             ConnectWindow,3,MUIM_CallHook,&HooksP->ConnectHook,1);

    DoMethod(coobject(1),MUIM_Notify,MUIA_String_Acknowledge,MUIV_EveryTime,
             coobject(1),3,MUIM_CallHook,&HooksP->ConnectHook,2);

    DoMethod(coobject(2),MUIM_Notify,MUIA_String_Acknowledge,MUIV_EveryTime,
             ConnectWindow,3,MUIM_CallHook,&HooksP->ConnectHook,1);

   }


  {
   unsigned long status;

   get(ConnectWindow,MUIA_Window_Open,&status);
   if (status==TRUE) return;
  }


 set(ConnectWindow,MUIA_Window_ActiveObject,(ULONG) coobject(1));
 set(ConnectWindow,MUIA_Window_Open,TRUE);
 return;
}

void GUIMISC_ConnectHook(struct Hook *MyHook,unsigned long *Param,void *Object,
                         void *Data)
{
 switch (*Param)
  {
   case 0:
     set (ConnectWindow,MUIA_Window_Open,FALSE);
     break;
   case 1:
     {
     unsigned long hardunit;
     unsigned long callset;
     unsigned char *callptr;
     unsigned char *connectpathptr;

     get (coobject(1),MUIA_String_Contents,&callptr);
     get (coobject(2),MUIA_String_Contents,&connectpathptr);
     get (coobject(3),MUIA_Cycle_Active,&hardunit);
     get (coobject(4),MUIA_Cycle_Active,&callset);

     if ( (callptr[0]=='N') && (callptr[1]=='O') && (callptr[2]=='C') &&
          (callptr[3]=='H') && (callptr[4]=='A') && (callptr[5]=='N') &&
          (callptr[6]=='N') && (callptr[7]=='E') && (callptr[8]=='L') )
       break;


     if (!MAIN_EstablishLink(callptr,connectpathptr,hardunit,callset))
      {
       set(coobject(1),MUIA_String_Contents,(ULONG) "NOCHANNEL");
       set(ConnectWindow,MUIA_Window_ActiveObject,(ULONG) coobject(1));
       break;
      }
     set (ConnectWindow,MUIA_Window_Open,FALSE);

     break;
     }
   case 2:
      {
       struct User *user;
       unsigned char call[16];
       unsigned char *callptr,*callxptr;
       get (Object,MUIA_String_Contents,(void *) &callptr);

       if ( (callptr[0]=='N') && (callptr[1]=='O') && (callptr[2]=='C') &&
            (callptr[3]=='H') && (callptr[4]=='A') && (callptr[5]=='N') &&
            (callptr[6]=='N') && (callptr[7]=='E') && (callptr[8]=='L') )
         break;

       callxptr=call;
       do {
         *callxptr=*callptr;
         if ( (*callxptr>='a') && (*callxptr<='z')) (*callxptr)-=32;
         ++callxptr;
        } while ( *(callptr++)!='\0');

       user=QSO_OpenUser(call);
       if (user!=NULL)
        {
         set (coobject(2),MUIA_String_Contents,(ULONG) user->DigiPath);
         QSO_CloseUser(user);
        }
       break;
      }

  }
}



void GUIMISC_Disconnect(void)
{
 if (ActiveChannel>0)
  {
   QSO_ForceTransmit(ActiveChannel);
   QSO_SendCommandUser(1,ActiveChannel,"D");
  }
 return;
}

void GUIMISC_ConnectMsg(void)
{
  unsigned long i;
  if (ConnectMsgWindow==NULL)
   {

     GlobalArraysP->ConnectMsg[0]=GUI_String(235);
     for (i=0;i<16;++i)
      {
       GlobalArraysP->ConnectMsg[i+1]=Preferences.ConnectMsg[i];
      }
     GlobalArraysP->ConnectMsg[17]=NULL;



     FillHook(&HooksP->ConnectMsgHook,(void *) GUIMISC_ConnectMsgHook,NULL);


     ConnectMsgWindow =
                 WindowObject,
                     MUIA_Window_Title, GUI_String(232),
                     MUIA_Window_ID   , MAKE_ID('C','M','S','G'),

                     WindowContents,

                       VGroup,
                           Child,cmobject(0)=MUI_NewObject(MUIC_Listview,
                                  MUIA_Background,MUII_ListBack,
                                  MUIA_Frame,MUIV_Frame_InputList,
                                  MUIA_Listview_List,
                                     MUI_NewObject(MUIC_List,
                                             MUIA_List_Active,CMessageNr,
                                             MUIA_List_SourceArray,GlobalArraysP->ConnectMsg,


                                     End,
                                  End,

                         End,
                     End;

    if (ConnectMsgWindow==NULL)
        {
            GUI_LowMemory();
            return;
        }

    DoMethod(Application,OM_ADDMEMBER,ConnectMsgWindow);

    DoMethod(ConnectMsgWindow,MUIM_Notify,MUIA_Window_CloseRequest,TRUE,
             ConnectMsgWindow,3,MUIM_CallHook,&HooksP->ConnectMsgHook,0);

    DoMethod(cmobject(0),MUIM_Notify,MUIA_Listview_DoubleClick,MUIV_EveryTime,
             ConnectMsgWindow,3,MUIM_CallHook,&HooksP->ConnectMsgHook,0);

    DoMethod(cmobject(0),MUIM_Notify,MUIA_List_Active,MUIV_EveryTime,
             cmobject(0),4,MUIM_CallHook,&HooksP->ConnectMsgHook,1,MUIV_TriggerValue);

   }


  {
   unsigned long status;

   get(ConnectMsgWindow,MUIA_Window_Open,&status);
   if (status==TRUE) return;
  }

 set(ConnectMsgWindow,MUIA_Window_Open,TRUE);
 set(ConnectMsgWindow,MUIA_Window_DefaultObject,(ULONG) cmobject(0));
 return;
}

void GUIMISC_ConnectMsgHook(struct Hook *MyHook,unsigned long *Param,void *Object,
                         void *Data)
{
 switch (*Param)
  {
   case 0:
     set (ConnectMsgWindow,MUIA_Window_Open,FALSE);
     break;
   case 1:
     CMessageNr=*(Param+1);
     LastSysopActivity=CurrentDateStamp;
     GUI_RefreshWindowTitle();
     break;
  }
}

void GUIMISC_SetSpy(void)
{

  if (SpyWindow==NULL)
   {
     unsigned long i,j;

     j=0;
     for (i=0;i<8;++i)
      {
       struct TNCDevice *dev;
       dev=&(Preferences.Devices[i]);
       if ( (dev->ExecDevice[0]=='\0') || (dev->GlobalMycall[0]=='\0') ||
            (dev->Channels==0) ) continue;
       GlobalArraysP->SpyArray2[j]=dev->Description;
       ++j;
      }
     GlobalArraysP->SpyArray2[j]=NULL;



     GlobalArraysP->SpyArray1[0]=GUI_String(47);
     GlobalArraysP->SpyArray1[1]=GUI_String(46);
     GlobalArraysP->SpyArray1[2]=NULL;

     FillHook(&HooksP->SpyHook,(void *) GUIMISC_SpyHook,NULL);


     SpyWindow =
                 WindowObject,
                     MUIA_Window_Title, GUI_String(253),
                     MUIA_Window_ID   , MAKE_ID('S','S','P','Y'),

                     WindowContents,

                       VGroup,
                          Child,ColGroup(2),
                            Child,Label2(GUI_String(506)),
                            Child,spobject(1)=Cycle(GlobalArraysP->SpyArray2),

                            Child,Label2(GUI_String(254)),
                            Child,spobject(2)=Slider(1,8,1),

                            Child,Label(GUI_String(255)),
                            Child,spobject(3)=String(NULL,12),

                            Child,Label(GUI_String(256)),
                            Child,spobject(4)=String(NULL,12),

                            Child,Label(GUI_String(257)),
                            Child,spobject(5)=Cycle(GlobalArraysP->SpyArray1),

                            End,

                         Child,spobject(0)=SimpleButton(GUI_String(258)),

                         End,
                     End;

    if (SpyWindow==NULL)
        {
            GUI_LowMemory();
            return;
        }



    DoMethod(Application,OM_ADDMEMBER,SpyWindow);


    {
     unsigned long i;
     for (i=0;i<6;++i)
      {
       set(spobject(i),MUIA_CycleChain,1);
      }

    }


    set (spobject(5),MUIA_Cycle_Active,1);
    set (spobject(3),MUIA_String_AdvanceOnCR,TRUE);
    set (spobject(4),MUIA_String_AdvanceOnCR,TRUE);

    DoMethod(SpyWindow,MUIM_Notify,MUIA_Window_CloseRequest,TRUE,
             SpyWindow,3,MUIM_CallHook,&HooksP->SpyHook,0);

    DoMethod(spobject(0),MUIM_Notify,MUIA_Pressed,FALSE,
             SpyWindow,3,MUIM_CallHook,&HooksP->SpyHook,1);

   }


  {
   unsigned long status;

   get(SpyWindow,MUIA_Window_Open,&status);
   if (status==TRUE) return;
  }


 set(SpyWindow,MUIA_Window_ActiveObject,(ULONG) spobject(3));
 set(SpyWindow,MUIA_Window_Open,TRUE);
 return;
}

void GUIMISC_SpyHook(struct Hook *MyHook,unsigned long *Param,void *Object,
                         void *Data)
{
 switch (*Param)
  {
   case 0:
     set (SpyWindow,MUIA_Window_Open,FALSE);
     break;
   case 1:
     {
       unsigned char call1[16],call2[16];
       unsigned char *callptr;

       unsigned long hunit,port,compr,spynr;

       get (spobject(3),MUIA_String_Contents,(void *) &callptr);
       CopyStringUpper(call1,callptr);
      
       get (spobject(4),MUIA_String_Contents,(void *) &callptr);
       CopyStringUpper(call2,callptr);
       
       get (spobject(1),MUIA_Cycle_Active,&hunit);
       get (spobject(2),MUIA_Slider_Level,&port);
       get (spobject(5),MUIA_Cycle_Active,&compr);
       spynr=MAIN_SearchFreeSpy();
       if (spynr==0)
        {
         GUI_DisplayEventWindow(GUI_String(501));
         break;
        }
       if (SPY_SetSpy(spynr,hunit,port,compr,call1,call2)!=0)
        {
         GUI_DisplayEventWindow(GUI_String(502));
         break;
        }
       set (SpyWindow,MUIA_Window_Open,FALSE);
       break;
     }
  }
}



void GUIMISC_ClearSpy(void)
{
 if (ActiveChannel>=0) return;
 SPY_ClearSpy(-ActiveChannel);
 return;
}


static int GUIMISC_GetUserDataMakeStatus(void)
 {
  int status;
  status=FALSE;
  while (1)
   {
    unsigned char *sptr;
    get(udobject(0),MUIA_String_Contents,&sptr);
    CopyString(UserBaseHead->ownerfirstname,sptr);
    get(udobject(1),MUIA_String_Contents,&sptr);
    CopyString(UserBaseHead->ownerqth,sptr);
    get(udobject(2),MUIA_String_Contents,&sptr);
    CopyString(UserBaseHead->ownerlocator,sptr);

    if (UserBaseHead->ownerfirstname[0]=='\0') break;
    if (UserBaseHead->ownerqth[0]=='\0') break;
    if (UserBaseHead->ownerlocator[0]=='\0') break;

    if (QSO_ValidateLocator(UserBaseHead->ownerlocator)) break;




    status=TRUE;
    break;
   }

  set(udobject(3),MUIA_Disabled,!status);
  return(status);
 }

void GUI_GetUserData(void)
{
 if (GetUserDataWindow==NULL)
   {
     unsigned long i;




     FillHook(&HooksP->UserDataHook,(void *) GUIMISC_UserDataHook,NULL);


     GetUserDataWindow =
                 WindowObject,
                     MUIA_Window_Title, GUI_String(0),
                     MUIA_Window_ID   , MAKE_ID('G','U','D','A'),
                     MUIA_Window_NoMenus,TRUE,
                     MUIA_Window_Activate,TRUE,

                     WindowContents,

                       VGroup,
                         Child,TextObject,
                                     MUIA_Text_PreParse,"\033c",
                                     MUIA_Text_Contents,GUI_String(552),
                                     End,

                         Child,ColGroup(2),
                                 Child,Label2(GUI_String(553)),
                                 Child,udobject(0)=String(NULL,32),
                                 Child,Label2(GUI_String(554)),
                                 Child,udobject(1)=String(NULL,32),
                                 Child,Label2(GUI_String(555)),
                                 Child,udobject(2)=String(NULL,7),
                                 End,

                         Child,udobject(3)=SimpleButton(GUI_String(163)),







                         End,

                     End;

    if (GetUserDataWindow==NULL)
        {
            GUI_LowMemory();
            return;
        }

    set(udobject(0),MUIA_String_Contents,(ULONG) UserBaseHead->ownerfirstname);
    set(udobject(1),MUIA_String_Contents,(ULONG) UserBaseHead->ownerqth);
    set(udobject(2),MUIA_String_Contents,(ULONG) UserBaseHead->ownerlocator);
    GUIMISC_GetUserDataMakeStatus();

    for (i=0;i<4;++i)
     {
      set(udobject(i),MUIA_CycleChain,1);
      if (i==3) continue;
      set(udobject(i),MUIA_String_AdvanceOnCR,TRUE);
     }

    DoMethod(Application,OM_ADDMEMBER,GetUserDataWindow);

    DoMethod(GetUserDataWindow,MUIM_Notify,MUIA_Window_CloseRequest,TRUE,
             GetUserDataWindow,3,MUIM_CallHook,&HooksP->UserDataHook,0);

    DoMethod(udobject(0),MUIM_Notify,MUIA_String_Acknowledge,MUIV_EveryTime,
             udobject(0),3,MUIM_CallHook,&HooksP->UserDataHook,1);

    DoMethod(udobject(1),MUIM_Notify,MUIA_String_Acknowledge,MUIV_EveryTime,
             udobject(0),3,MUIM_CallHook,&HooksP->UserDataHook,1);

    DoMethod(udobject(2),MUIM_Notify,MUIA_String_Acknowledge,MUIV_EveryTime,
             udobject(0),3,MUIM_CallHook,&HooksP->UserDataHook,1);

    DoMethod(udobject(3),MUIM_Notify,MUIA_Pressed,MUIV_EveryTime,
             GetUserDataWindow,3,MUIM_CallHook,&HooksP->UserDataHook,0);


   }


  {
   unsigned long status;

   get(GetUserDataWindow,MUIA_Window_Open,&status);
   if (status==TRUE) return;
  }

 set(GetUserDataWindow,MUIA_Window_Open,TRUE);
 set(GetUserDataWindow,MUIA_Window_ActiveObject,(ULONG) udobject(0));
 return;
}



void GUI_StartupDone(void);
int QSO_SaveHeader(void);


static void GUIMISC_UserDataHookShiftin(unsigned long value)
 {
  UserBaseHead->identifier=((UserBaseHead->identifier<<6)+((UserBaseHead->identifier>>28) ^ (value))) + 98361521;
 }

void GUIMISC_UserDataHook(struct Hook *MyHook,unsigned long *Param,void *Object,
                         void *Data)
{
 switch (*Param)
  {
   unsigned char *sptr;
   case 0:
     if (!GUIMISC_GetUserDataMakeStatus()) break;
     set (GetUserDataWindow,MUIA_Window_Open,FALSE);
     GUIMISC_UserDataHookShiftin(CurrentDateStamp.ds_Days);
     GUIMISC_UserDataHookShiftin(CurrentDateStamp.ds_Minute);
     GUIMISC_UserDataHookShiftin(CurrentDateStamp.ds_Tick);
     sptr=UserBaseHead->ownerfirstname;
     while (*(sptr)!='\0') GUIMISC_UserDataHookShiftin(*(sptr++));
     sptr=UserBaseHead->ownerqth;
     while (*(sptr)!='\0') GUIMISC_UserDataHookShiftin(*(sptr++));
     sptr=UserBaseHead->ownerlocator;
     while (*(sptr)!='\0') GUIMISC_UserDataHookShiftin(*(sptr++));

     QSO_SaveHeader();
     GUI_StartupDone();
     break;

   case 1:
     GUIMISC_GetUserDataMakeStatus();
     break;
  }
}


void GUIMISC_EncryptionStatus(void)
 {
  int cansp=FALSE,canxp=FALSE,canpp=FALSE,canspecial=FALSE;

  int txsp=FALSE,rxsp=FALSE,txxp=FALSE,rxxp=FALSE,specxp=FALSE,keyok=FALSE;
  int txpp=FALSE,rxpp=FALSE;

  struct QSO *tqso;

  if (EncryptionWindow!=NULL)
  {
   unsigned long status;

   get(EncryptionWindow,MUIA_Window_Open,&status);
   if (status==FALSE) return;
  }
  else
  {
   return;
  }

  tqso=QSOs+(ActiveChannel-1);

  if ( (ActiveChannel>0) && ( tqso->Server!=NULL))
   {


    unsigned long progtype,progversion,progrevision,progsubrevision;

    tqso=QSOs+(ActiveChannel-1);

    txsp=tqso->CompressedMode&1;
    rxsp=tqso->CompressedMode&2;
    txpp=tqso->CompressedMode&4;
    rxpp=tqso->CompressedMode&8;
    txxp=tqso->CompressedMode&16;
    rxxp=tqso->CompressedMode&32;
    specxp=tqso->CompressedMode&64;
    keyok=tqso->CompressedMode&128;

    progtype=tqso->StationID.Program;
    progversion=tqso->StationID.Version;
    progrevision=tqso->StationID.Revision;
    progsubrevision=tqso->StationID.Subrevision;


    switch (progtype)
     {
      case SID_Program_ProfiPacket:
        cansp=TRUE;
        if ( (progversion>0) || ( (progversion==0) && (progrevision>24)) ||
             ( progversion==0) || ((progrevision==24) && (progsubrevision>=1)))
         {
          canxp=TRUE;
         }

        if ( (progversion>0) || ( (progversion==0) && (progrevision>24)) ||
             ( progversion==0) || ((progrevision==24) && (progsubrevision>=8)))
         {
          canspecial=TRUE;
         }
        if ( (progversion>0) || ( (progversion==0) && (progrevision>21)) ||
             (( progversion==0) || ((progrevision=21) && (progsubrevision>=3))))
         {
          canpp=TRUE;
         }

        break;

      case SID_Program_XPacket:
        canxp=TRUE;
        if ( (progversion>1) || ( (progversion==1) && (progrevision>=70) ) )
         {
          canspecial=TRUE;
         }
        if ( (progversion>1) || ( (progversion==1) && (progrevision>=80) ) )
         {
          cansp=TRUE;
         }
        break;

      case SID_Program_FBB:
      case SID_Program_GP:
      case SID_Program_TE:
      case SID_Program_AmiCom:
      case SID_Program_AP:
      case SID_Program_AHP4:
        break;

      case SID_Program_STOP:
      case SID_Program_TOP:
        canxp=TRUE;
        break;

      case SID_Program_SP:
      case SID_Program_WinGT:
        cansp=TRUE;
        break;

      default:
        cansp=TRUE;
        canxp=TRUE;
        break;

     }



   }


  if ( (QSO_GetPacLen(ActiveChannel)>=256) || (HuffmanSpeedup==NULL) )
   {
    cansp=FALSE;
   }

  if (HuffmanSpeedup==NULL)
   {
    canxp=FALSE;
    canspecial=FALSE;
   }

  if ( (QSO_GetPacLen(ActiveChannel)>248) )
   {
    canpp=FALSE;
   }

  if ( txsp || rxsp)
   {
    canxp=FALSE;
    canspecial=FALSE;
   }

  if ( txxp || rxxp) cansp=FALSE;

  set (enobject(0),MUIA_Disabled,!cansp);
  set (enobject(1),MUIA_Disabled,!cansp);
  set (enobject(2),MUIA_Disabled,!canxp);
  set (enobject(3),MUIA_Disabled,!canxp);
  set (enobject(4),MUIA_Disabled,!canspecial);
  set (enobject(5),MUIA_Disabled,!canspecial);
  set (enobject(6),MUIA_Disabled,!canpp);
  set (enobject(7),MUIA_Disabled,!canpp);

  nnset (enobject(0),MUIA_Selected,txsp);
  nnset (enobject(1),MUIA_Selected,rxsp);
  nnset (enobject(2),MUIA_Selected,txxp);
  nnset (enobject(3),MUIA_Selected,rxxp);
  nnset (enobject(4),MUIA_Selected,specxp);
  nnset (enobject(5),MUIA_Selected,keyok);
  nnset (enobject(6),MUIA_Selected,txpp);
  nnset (enobject(7),MUIA_Selected,rxpp);


  set (enobject(8),MUIA_Disabled,(!cansp) || txsp || rxsp || txxp || rxxp);
  set (enobject(9),MUIA_Disabled,(!canxp) || txsp || rxsp || txxp || rxxp);
  set (enobject(10),MUIA_Disabled,(!canspecial) || txsp || rxsp || txxp || rxxp);
  set (enobject(11),MUIA_Disabled,!( (txsp&&rxsp) || (txxp&&rxxp) ));
  set (enobject(12),MUIA_Disabled,!rxxp);
  set (enobject(13),MUIA_Disabled,!txxp);
  set (enobject(14),MUIA_Disabled,(!canpp) || txpp || rxpp);
  set (enobject(15),MUIA_Disabled,(!canpp) || (!txpp) || (!rxpp));
 }

void GUIMISC_Encryption(void)
{
 if (EncryptionWindow==NULL)
   {
     unsigned long i;




     FillHook(&HooksP->EncryptionHook,(void *) GUIMISC_EncryptionHook,NULL);


     EncryptionWindow =
                 WindowObject,
                     MUIA_Window_Title, GUI_String(557),
                     MUIA_Window_ID   , MAKE_ID('E','N','C','R'),
                     MUIA_Window_Activate,TRUE,

                     WindowContents,

                       ColGroup(2),
                          Child,ColGroup(2),
                                   GroupFrameT(GUI_String(558)),
                                   Child,Label(GUI_String(559)),
                                   Child,enobject(0)=CheckMark(FALSE),
                                   Child,Label(GUI_String(560)),
                                   Child,enobject(1)=CheckMark(FALSE),
                                   Child,Label(GUI_String(561)),
                                   Child,enobject(2)=CheckMark(FALSE),
                                   Child,Label(GUI_String(562)),
                                   Child,enobject(3)=CheckMark(FALSE),
                                   Child,Label(GUI_String(563)),
                                   Child,enobject(4)=CheckMark(FALSE),
                                   Child,Label(GUI_String(564)),
                                   Child,enobject(5)=CheckMark(FALSE),
                                   Child,Label(GUI_String(565)),
                                   Child,enobject(6)=CheckMark(FALSE),
                                   Child,Label(GUI_String(566)),
                                   Child,enobject(7)=CheckMark(FALSE),
                                   End,

                          Child,VGroup,
                                   GroupFrameT(GUI_String(567)),
                                   Child,enobject(8)=SimpleButton(GUI_String(568)),
                                   Child,enobject(9)=SimpleButton(GUI_String(569)),
                                   Child,enobject(10)=SimpleButton(GUI_String(570)),
                                   Child,enobject(11)=SimpleButton(GUI_String(571)),
                                   Child,enobject(12)=SimpleButton(GUI_String(574)),
                                   Child,enobject(13)=SimpleButton(GUI_String(575)),
                                   Child,enobject(14)=SimpleButton(GUI_String(572)),
                                   Child,enobject(15)=SimpleButton(GUI_String(573)),


                                   End,




                         End,

                     End;

    if (EncryptionWindow==NULL)
        {
            GUI_LowMemory();
            return;
        }



    for (i=0;i<16;++i)
     {
      set(enobject(i),MUIA_CycleChain,1);
     }

    DoMethod(Application,OM_ADDMEMBER,EncryptionWindow);

    DoMethod(EncryptionWindow,MUIM_Notify,MUIA_Window_CloseRequest,TRUE,
             EncryptionWindow,3,MUIM_CallHook,&HooksP->EncryptionHook,128);

    for (i=0;i<8;++i)
     {
      DoMethod(enobject(i),MUIM_Notify,MUIA_Selected,MUIV_EveryTime,
               enobject(i),4,MUIM_CallHook,&HooksP->EncryptionHook,i,MUIV_TriggerValue);
     }
    for (i=8;i<16;++i)
     {
      DoMethod(enobject(i),MUIM_Notify,MUIA_Pressed,FALSE,
               enobject(i),3,MUIM_CallHook,&HooksP->EncryptionHook,i);
     }
    DoMethod(enobject(0),MUIM_Notify,MUIA_String_Acknowledge,MUIV_EveryTime,
             enobject(0),3,MUIM_CallHook,&HooksP->EncryptionHook,1);

    DoMethod(enobject(1),MUIM_Notify,MUIA_String_Acknowledge,MUIV_EveryTime,
             enobject(0),3,MUIM_CallHook,&HooksP->EncryptionHook,1);

    DoMethod(enobject(2),MUIM_Notify,MUIA_String_Acknowledge,MUIV_EveryTime,
             enobject(0),3,MUIM_CallHook,&HooksP->EncryptionHook,1);

    DoMethod(enobject(3),MUIM_Notify,MUIA_Pressed,MUIV_EveryTime,
             enobject(3),3,MUIM_CallHook,&HooksP->EncryptionHook,0);


   }



  {
   unsigned long status;

   get(EncryptionWindow,MUIA_Window_Open,&status);
   if (status==TRUE) return;
  }

 set(EncryptionWindow,MUIA_Window_Open,TRUE);
 GUIMISC_EncryptionStatus();
 return;
}


void GUIMISC_EncryptionHook(struct Hook *MyHook,unsigned long *Param,void *Object,
                         void *Data)
{
 struct QSO *tqso;

 if (ActiveChannel<=0)
  {
   GUIMISC_EncryptionStatus();
   return;
  }

 tqso=QSOs+(ActiveChannel-1);


 if (*Param>=8) nnset(Object,MUIA_Selected,FALSE);

 switch (*Param)
  {
   case 0:
     if (*(Param+1))
      {
       tqso->CompressedMode|=1;
      }
      else
      {
       tqso->CompressedMode&=0xfffffffe;
      }
     GUI_RefreshConnectHead();
     break;
   case 1:
     if (*(Param+1))
      {
       tqso->CompressedMode|=2;
      }
      else
      {
       tqso->CompressedMode&=0xfffffffd;
      }
      GUI_RefreshConnectHead();
     break;
   case 2:
     if (*(Param+1))
      {
       tqso->CompressedMode|=16;
      }
      else
      {
       tqso->CompressedMode&=0xffffffef;
      }
     GUI_RefreshConnectHead();
     break;
   case 3:
     if (*(Param+1))
      {
       tqso->CompressedMode|=32;
      }
      else
      {
       tqso->CompressedMode&=0xffffffdf;
      }
      GUI_RefreshConnectHead();
     break;
   case 4:
     if (*(Param+1))
      {
       tqso->CompressedMode|=64;
      }
      else
      {
       tqso->CompressedMode&=0xffffffbf;
      }
     GUI_RefreshConnectHead();
     break;
   case 5:
      if (*(Param+1))
       {
        tqso->CompressedMode|=128;
       }
       else
       {
        tqso->CompressedMode&=0xffffff7f;
       }
     GUI_RefreshConnectHead();
     break;
   case 6:
     if (*(Param+1))
      {
       QSO_ControlEncryption(ActiveChannel,2);
      }
      else
      {
       QSO_ControlEncryption(ActiveChannel,4);
      }
     GUIMISC_EncryptionStatus();
     break;
   case 7:
     if (*(Param+1))
      {
       QSO_ControlEncryption(ActiveChannel,3);
      }
      else
      {
       QSO_ControlEncryption(ActiveChannel,5);
      }
     GUIMISC_EncryptionStatus();
     break;
   case 8:
     QSO_SendData(10,ActiveChannel,"\r//COMP 1\r");
     QSO_ForceTransmit(ActiveChannel);
     QSO_CompressionOn(ActiveChannel);
     GUIMISC_EncryptionStatus();
     break;
   case 9:
     QSO_ControlXPCompress(ActiveChannel,0);
     GUIMISC_EncryptionStatus();
     break;
   case 10:
     QSO_ControlXPCompress(ActiveChannel,128);
     GUIMISC_EncryptionStatus();
     break;
   case 11:
     if (tqso->CompressedMode&3)
      {
       QSO_SendData(10,ActiveChannel,"\r//COMP 0\r");
       QSO_ForceTransmit(ActiveChannel);
       QSO_CompressionOff(ActiveChannel);
      }
     if (tqso->CompressedMode&48)
      {
       if (tqso->CompressedMode&128)
        {
         QSO_ControlXPCompress(ActiveChannel,129);
        }
        else
        {
         QSO_ControlXPCompress(ActiveChannel,1);
        }
      }
     GUIMISC_EncryptionStatus();
     break;
   case 12:
     if (tqso->CompressedMode&128)
      {
       QSO_ControlXPCompress(ActiveChannel,134);
      }
      else
      {
       QSO_ControlXPCompress(ActiveChannel,6);
      }

     GUIMISC_EncryptionStatus();
     break;
   case 13:
     if (tqso->CompressedMode&128)
      {
       QSO_ControlXPCompress(ActiveChannel,135);
      }
      else
      {
       QSO_ControlXPCompress(ActiveChannel,7);
      }
     GUIMISC_EncryptionStatus();
     break;
   case 14:
     QSO_ControlEncryption(ActiveChannel,0);
     GUIMISC_EncryptionStatus();
     break;
   case 15:
     QSO_ControlEncryption(ActiveChannel,1);
     GUIMISC_EncryptionStatus();
     break;
   case 128:
     set(EncryptionWindow,MUIA_Window_Open,FALSE);
     break;
  }

}


void GUI_AbortTransmit(void)
 {
  switch (SERV_AbortFileTransfer(ActiveChannel))
   {
    case ERR_SERVER_NOTCONNECTED:
     GUI_DisplayEventWindow(GUI_String(117));
     break;
    case ERR_SERVER_NOTRANSFER:
     GUI_DisplayEventWindow(GUI_String(124));
     break;
   }

  return;
 }

void GUI_SendPassword(void)
 {
  struct QSO *qso;

  if (ActiveChannel<=0)
   {
    GUI_DisplayEventWindow(GUI_String(117));
    return;
   }

  qso=QSOs+(ActiveChannel-1);
  if (qso->Server==NULL)
   {
    GUI_DisplayEventWindow(GUI_String(117));
    return;
   }

  if ( (qso->User==NULL) || (qso->User->RPType==0) ||
       (qso->User->RPassword[0]=='\0') )
   {
    GUI_DisplayEventWindow(GUI_String(189));
   }
  QSO_SendPassword(ActiveChannel,NULL);
  return;
 }


unsigned long GUI_HandleRequest(unsigned long Title,unsigned long Body,
                                unsigned long Gadgets,unsigned long *Arg)
 {
  return(MUI_RequestA(Application,NULL,0
            ,GUI_String(Title),GUI_String(Gadgets),GUI_String(Body),Arg));
 
 }

void GUI_ChangeHardStatus(int unit,int status,int data)
 {
  int changed=0;
  
  if (HardwareInfoData[unit]!=data) 
   {
    HardwareInfoData[unit]=data;
    changed=1;
   } 
  if (HardwareInfo[unit]!=status)
   {
    HardwareInfo[unit]=status;
    changed=1;
   }
  if (!changed) return;
  if (
      ( (ActiveChannel>0) && ( (QSOs+(ActiveChannel-1))->HardwareUnit==unit) ) ||
      (ActiveChannel==0))
   {
    GUI_RefreshWindowTitle();   
   }
   else
   {
    if ( (status==5) || (status==7) )
     {
      GUI_RefreshWindowTitle();
     }
   }
 }


unsigned long GUI_CheckLeaveProg(void)
 {
  int chan;
  struct QSO *tqso;
  tqso=QSOs;
  
  for (chan=1;chan<=MaxChannel;++chan,++tqso)
   {
    int st,i,sts=3;
    char *gstring;
    if (tqso->Server==NULL) continue;
    st=SERV_GetServerType(tqso);
    if ( (st==0) && (SERV_IsTopServer(tqso)) ) continue;
    if (st!=0)
     {
      for (i=0;i<32;++i)
       {
        if ( st&(1<<i)) 
         {
          sts=i;
          break;
         }
       }
     }
    gstring=GUI_String(sts+264);
     {
      unsigned long par[2];
      par[0]=chan;
      par[1]=(unsigned long ) gstring;
      i=GUI_HandleRequest(0,296,297,par);  
     } 
    if (i==0) return(-1);
    if (i==1)
     {
      /* kill server */
      SERV_CleanupServer(tqso);
      --chan;
      --tqso;
     }
     else
     {
      void *olds;
      /* abort server */
      olds=tqso->Server;
      SERV_AbortServer(tqso);
      for (i=0;i<60;++i)
       {
        if (tqso->Server!=olds) break;
        MAIN_WaitMoment();
       }
      if (i==60)
       {
        SERV_CleanupServer(tqso);
       }
      --chan;
      --tqso;
     }
   }
  return(0);
 }