/*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 <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

#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 GUIUSER_UserSetHook(struct Hook *MyHook,unsigned long *Param,void *Object,
                         void *Data);



#define usobject(xx) GlobalArraysP->UserSetObjects[xx+1]


void GUIUSER_WriteKeyGad(unsigned long *cipher,unsigned char *buffer);
void GUIUSER_ReadKeyGad(unsigned long *cipher,unsigned char *buffer);


void GUIUSER_UserSettings(void)
{

  if (UserSettingsWindow==NULL)
   {

     signed long i;

     GlobalArraysP->UserSetUser=NULL;
     for (i=0;i<16;++i)
      {
       GlobalArraysP->UserSetTerminal[i]=GUI_String(164+i);
      }
     GlobalArraysP->UserSetTerminal[16]=NULL;

     for (i=0;i<8;++i)
      {
       GlobalArraysP->UserSetPassword[i]=GUI_String(180+i);
      }
     GlobalArraysP->UserSetPassword[8]=NULL;

     GlobalArraysP->UserSetLanguage[0]=GUI_String(312);
     for (i=1;i<999;++i)
      {
       unsigned long j;
       j=GetLanguageString(i);
       if (j==0)
        {
         GlobalArraysP->UserSetLanguage[i]=NULL;
         break;
        }
       GlobalArraysP->UserSetLanguage[i]=GUI_String(j);
      }


     GlobalArraysP->UserSetGroups[0]=GUI_String(148);
     GlobalArraysP->UserSetGroups[1]=GUI_String(149);
     GlobalArraysP->UserSetGroups[2]=NULL;

     GlobalArraysP->UserSetDColl[0]=GUI_String(508);
     GlobalArraysP->UserSetDColl[1]=GUI_String(509);
     GlobalArraysP->UserSetDColl[2]=NULL;

     FillHook(&HooksP->UserSettings,(void *) GUIUSER_UserSetHook,NULL);


     UserSettingsWindow =
                 WindowObject,
                     MUIA_Window_Title, GUI_String(143),
                     MUIA_Window_ID   , MAKE_ID('U','S','E','T'),
                     MUIA_HelpNode,"User_Settings",
                     WindowContents,

                       VGroup,
                         Child,HGroup,

                             Child,Label2(GUI_String(144)),
                             Child,usobject(0)=String(NULL,10),
                             Child,usobject(1)=SimpleButton(GUI_String(145)),
                             Child,usobject(2)=SimpleButton(GUI_String(146)),
                             End,
                         Child,usobject(-1)=RegisterGroup(GlobalArraysP->UserSetGroups),

                                 Child,VGroup,
                                         MUIA_HelpNode,"User_Settings_General",
                                         Child,ColGroup(4),

                                                 Child,Label2(GUI_String(156)),
                                                 Child,usobject(3)=String(NULL,32),
                                                 Child,Label(GUI_String(162)),
                                                 Child,usobject(4)=Cycle(GlobalArraysP->UserSetTerminal),
                                                 Child,Label2(GUI_String(157)),
                                                 Child,usobject(5)=String(NULL,32),
                                                 Child,Label(GUI_String(159)),
                                                 Child,usobject(6)=Cycle(GlobalArraysP->UserSetPassword),
                                                 Child,Label2(GUI_String(158)),
                                                 Child,usobject(7)=String(NULL,7),
                                                 Child,Label(GUI_String(160)),
                                                 Child,usobject(8)=Cycle(GlobalArraysP->UserSetPassword),

                                               End,
                                         Child,ColGroup(2),
                                                 Child,Label2(GUI_String(159)),
                                                 Child,usobject(9)=String(NULL,81),
                                                 Child,Label2(GUI_String(160)),
                                                 Child,usobject(10)=String(NULL,81),
                                                 Child,Label2(GUI_String(161)),
                                                 Child,usobject(11)=String(NULL,80),
                                                 Child,Label(GUI_String(311)),
                                                 Child,usobject(12)=Cycle(GlobalArraysP->UserSetLanguage),
                                                 Child,Label(GUI_String(507)),
                                                 Child,usobject(30)=Cycle(GlobalArraysP->UserSetDColl),
                                                 Child,Label2(GUI_String(315)),
                                                 Child,usobject(13)=String(NULL,33),

                                               End,
                                         Child,HGroup,
                                                 Child,Label2(GUI_String(499)),
                                                 Child,usobject(28)=String(NULL,5),
                                                 Child,Label2(GUI_String(500)),
                                                 Child,usobject(29)=Slider(1,100,100),

                                               End,


                                         Child,HGroup,
                                                 Child,Label2(GUI_String(473)),
                                                 Child,usobject(27)=PopaslObject,
                                                   MUIA_Popstring_String,String(NULL,80),
                                                   MUIA_Popstring_Button,PopButton(MUII_PopDrawer),
                                                   ASLFR_TitleText,GUI_String(473),
                                                   ASLFR_DrawersOnly,TRUE,
                                                   End,

                                               End,


                                       End,

                                 Child,VGroup,
                                         MUIA_HelpNode,"User_Settings_Link",
                                         Child,HGroup,

                                               Child,HSpace(0),
                                               Child,Label(GUI_String(192)),
                                               Child,usobject(14)=CheckMark(FALSE),
                                               Child,HSpace(0),
                                            End,

                                         Child,ColGroup(4),
                                               Child,Label2(NULL),
                                               Child,Label2(GUI_String(193)),
                                               Child,Label2(GUI_String(194)),
                                               Child,Label2(GUI_String(195)),

                                               Child,Label2(GUI_String(228)),
                                               Child,usobject(15)=Slider(200,2000,700),
                                               Child,usobject(16)=Slider(200,2000,700),
                                               Child,usobject(17)=Slider(200,2000,700),

                                               Child,Label2(GUI_String(229)),
                                               Child,usobject(18)=Slider(0,100,20),
                                               Child,usobject(19)=Slider(0,100,20),
                                               Child,usobject(20)=Slider(0,100,20),

                                               Child,Label2(GUI_String(230)),
                                               Child,usobject(21)=Slider(1,7,4),
                                               Child,usobject(22)=Slider(1,7,4),
                                               Child,usobject(23)=Slider(1,7,4),

                                               Child,Label2(GUI_String(231)),
                                               Child,usobject(24)=Slider(32,256,128),
                                               Child,usobject(25)=Slider(32,256,128),
                                               Child,usobject(26)=Slider(32,256,128),


                                            End,

                                       End,


                               End,

                         End,
                     End;

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

    DoMethod(Application,OM_ADDMEMBER,UserSettingsWindow);

    {
     signed long i,kv;  /* add one for register group */
     for (i=0;i<32;++i)
      {
       set(usobject(i-1),MUIA_CycleChain,1);
      }


     for (i=3;i<31;++i)
      {
       kv=MUIA_String_Acknowledge;
       if ( (i>=15) && (i<=26) ) kv=MUIA_Slider_Level;
       if (i==14) kv=MUIA_Selected;
       if ( (i==4) || (i==6) || (i==30) || (i==8) || (i==12) ) kv=MUIA_Cycle_Active;
       if (i==27) kv=MUIA_String_Contents;
       if (i==29) kv=MUIA_Slider_Level;

       DoMethod(usobject(i),MUIM_Notify,kv,MUIV_EveryTime,
                usobject(i),4,MUIM_CallHook,&HooksP->UserSettings,i,
                MUIV_TriggerValue);
       if (kv==MUIA_String_Acknowledge)
        {
         set (usobject(i),MUIA_String_AdvanceOnCR,TRUE);
        }
      }
    }




    DoMethod(UserSettingsWindow,MUIM_Notify,MUIA_Window_CloseRequest,TRUE,
             UserSettingsWindow,4,MUIM_CallHook,&HooksP->UserSettings,999,0);

    DoMethod(usobject(0),MUIM_Notify,MUIA_String_Acknowledge,
             MUIV_EveryTime,usobject(0),4,MUIM_CallHook,&HooksP->UserSettings,
             0,MUIV_TriggerValue);

    DoMethod(usobject(1),MUIM_Notify,MUIA_Pressed,FALSE,
             usobject(1),4,MUIM_CallHook,&HooksP->UserSettings,1,0);
    DoMethod(usobject(2),MUIM_Notify,MUIA_Pressed,FALSE,
             usobject(2),4,MUIM_CallHook,&HooksP->UserSettings,2,0);

   }


  {
   unsigned long status;

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


 set(usobject(0),MUIA_String_Contents,(ULONG) "STANDARD");
 set(usobject(0),MUIA_String_Acknowledge,TRUE);
 set(UserSettingsWindow,MUIA_Window_Open,TRUE);
 return;
}

void GUIUSER_UserSetHook(struct Hook *MyHook,unsigned long *Param,void *Object,
                         void *Data)
{
 struct User *cuser;
 unsigned long tv;
 cuser=GlobalArraysP->UserSetUser;
 tv=*(Param+1);
 if ( (*Param>2) && (*Param<900) && (cuser==NULL) ) return;
 switch (*Param)
  {
   case 0:
    {
     char *charptr,*dptr;
     char bufchar[32];
     if (GlobalArraysP->UserSetUser!=NULL)
      {
       QSO_CloseUser(GlobalArraysP->UserSetUser);
       GlobalArraysP->UserSetUser=NULL;
      }
     get(usobject(0),MUIA_String_Contents,&charptr);
     dptr=bufchar;
     do {
         *(dptr++)=*(charptr++);
         if ( (*(dptr-1)>='a') && (*(dptr-1)<='z') )
               *(dptr-1)-=32;

        } while ( *(charptr-1)!='\0');

     nnset(usobject(0),MUIA_String_Contents,(ULONG)bufchar);
     if (bufchar[0]=='?') break;
     if ( (bufchar[0]=='S') && (bufchar[1]=='T') && (bufchar[2]=='A') &&
          (bufchar[3]=='N') && (bufchar[4]=='D') && (bufchar[5]=='A') &&
          (bufchar[6]=='R') && (bufchar[7]=='D') )
      {
       GlobalArraysP->UserSetUser=QSO_OpenStandardUser();
      }
      else
      {
       GlobalArraysP->UserSetUser=QSO_OpenUser_SSID(bufchar);
      }
     cuser=GlobalArraysP->UserSetUser;
     if (cuser==NULL)
      {
       nnset(usobject(0),MUIA_String_Contents,(ULONG )"????");
       break;
      }
      {
       unsigned char *sptr,*dptr;
       unsigned char buffer[48];
       sptr=cuser->Name;dptr=buffer;
       do { *(dptr++)=*(sptr++); } while ( *(sptr-1)!='\0' ) ;
       MAIN_ConvertToAmiga(buffer);
       nnset(usobject(3),MUIA_String_Contents,(ULONG) buffer);
       nnset(usobject(4),MUIA_Cycle_Active,cuser->Type);
       sptr=cuser->QTH;dptr=buffer;
       do { *(dptr++)=*(sptr++); } while ( *(sptr-1)!='\0' ) ;
       MAIN_ConvertToAmiga(buffer);
       nnset(usobject(5),MUIA_String_Contents,(ULONG) buffer);
      }
     nnset(usobject(6),MUIA_Cycle_Active,cuser->RPType);
     nnset(usobject(7),MUIA_String_Contents,(ULONG) cuser->Locator);
     nnset(usobject(8),MUIA_Cycle_Active,cuser->LPType);
     nnset(usobject(9),MUIA_String_Contents,(ULONG) cuser->RPassword);
     nnset(usobject(10),MUIA_String_Contents,(ULONG) cuser->LPassword);
     nnset(usobject(11),MUIA_String_Contents,(ULONG) cuser->DigiPath);
     nnset(usobject(12),MUIA_Cycle_Active,cuser->Language);
      {
       unsigned char buffer[80];
       GUIUSER_WriteKeyGad(cuser->CipherKey,buffer);
       nnset(usobject(13),MUIA_String_Contents,(ULONG) buffer);
      }
     nnset(usobject(14),MUIA_Selected,cuser->LinkUse);
     nnset(usobject(15),MUIA_Slider_Level,cuser->MinFrack);
     nnset(usobject(16),MUIA_Slider_Level,cuser->MaxFrack);
     nnset(usobject(17),MUIA_Slider_Level,cuser->CurFrack);
     nnset(usobject(18),MUIA_Slider_Level,cuser->MinTries);
     nnset(usobject(19),MUIA_Slider_Level,cuser->MaxTries);
     nnset(usobject(20),MUIA_Slider_Level,cuser->CurTries);
     nnset(usobject(21),MUIA_Slider_Level,cuser->MinMaxFrame);
     nnset(usobject(22),MUIA_Slider_Level,cuser->MaxMaxFrame);
     nnset(usobject(23),MUIA_Slider_Level,cuser->CurMaxFrame);
     nnset(usobject(24),MUIA_Slider_Level,cuser->MinPaclen);
     nnset(usobject(25),MUIA_Slider_Level,cuser->MaxPaclen);
     nnset(usobject(26),MUIA_Slider_Level,cuser->CurPaclen);
     nnset(usobject(27),MUIA_String_Contents,(ULONG) cuser->PrivateDir);
      {
       unsigned char xx[5];
       xx[0]=cuser->XPKType[0];
       xx[1]=cuser->XPKType[1];
       xx[2]=cuser->XPKType[2];
       xx[3]=cuser->XPKType[3];
       xx[4]='\0';
       nnset(usobject(28),MUIA_String_Contents,(ULONG) xx);
      }
     nnset(usobject(29),MUIA_Slider_Level,cuser->XPKEfficiency);
     nnset(usobject(30),MUIA_Cycle_Active,cuser->Datacollector);
     break;
    }


   case 1:
     if (cuser==NULL) break;
     if (QSO_RemoveUser(cuser)) break;
     GlobalArraysP->UserSetUser=NULL;
     set(usobject(0),MUIA_String_Contents,(ULONG) "STANDARD");
     set(usobject(0),MUIA_String_Acknowledge,TRUE);
     break;
   case 2:
     set(usobject(0),MUIA_String_Contents,(ULONG) "STANDARD");
     set(usobject(0),MUIA_String_Acknowledge,TRUE);
     break;

   case 3:
     DoMethod(Object,MUIM_WriteString,tv,cuser->Name);
     MAIN_ConvertToPC(cuser->Name);
     QSO_ChangeUser(cuser);
     break;
   case 4:
     cuser->Type=tv;
     QSO_ChangeUser(cuser);
     break;
   case 5:
     DoMethod(Object,MUIM_WriteString,tv,cuser->QTH);
     MAIN_ConvertToPC(cuser->QTH);
     QSO_ChangeUser(cuser);
     break;
   case 6:
     cuser->RPType=tv;
     QSO_ChangeUser(cuser);
     break;
   case 7:
      {
       unsigned char buffer[16];
       DoMethod(Object,MUIM_WriteString,tv,buffer);
       if (!QSO_ValidateLocator(buffer))
        {
         DoMethod(Object,MUIM_WriteString,buffer,cuser->Locator);
         QSO_ChangeUser(cuser);
        }
       nnset(Object,MUIA_String_Contents,(ULONG) cuser->Locator);
       break;
      }
   case 8:
     cuser->LPType=tv;
     QSO_ChangeUser(cuser);
     break;
   case 9:
     DoMethod(Object,MUIM_WriteString,tv,cuser->RPassword);
     QSO_ChangeUser(cuser);
     break;
   case 10:
     DoMethod(Object,MUIM_WriteString,tv,cuser->LPassword);
     QSO_ChangeUser(cuser);
     break;
   case 11:
     DoMethod(Object,MUIM_WriteString,tv,cuser->DigiPath);
     QSO_ChangeUser(cuser);
     break;
   case 12:
     cuser->Language=tv;
     QSO_ChangeUser(cuser);
     break;
   case 13:
    {
     unsigned char buffer[80];
     GUIUSER_ReadKeyGad(cuser->CipherKey,(char *) tv);
     QSO_ChangeUser(cuser);
     GUIUSER_WriteKeyGad(cuser->CipherKey,buffer);
     nnset(usobject(13),MUIA_String_Contents,(ULONG) buffer);
     break;
    }
   case 14:
     cuser->LinkUse=tv;
     QSO_ChangeUser(cuser);
     break;
   case 15:
     cuser->MinFrack=tv;
     QSO_ChangeUser(cuser);
     break;
   case 16:
     cuser->MaxFrack=tv;
     QSO_ChangeUser(cuser);
     break;
   case 17:
     cuser->CurFrack=tv;
     QSO_ChangeUser(cuser);
     break;
   case 18:
     cuser->MinTries=tv;
     QSO_ChangeUser(cuser);
     break;
   case 19:
     cuser->MaxTries=tv;
     QSO_ChangeUser(cuser);
     break;
   case 20:
     cuser->CurTries=tv;
     QSO_ChangeUser(cuser);
     break;
   case 21:
     cuser->MinMaxFrame=tv;
     QSO_ChangeUser(cuser);
     break;
   case 22:
     cuser->MaxMaxFrame=tv;
     QSO_ChangeUser(cuser);
     break;
   case 23:
     cuser->CurMaxFrame=tv;
     QSO_ChangeUser(cuser);
     break;
   case 24:
     cuser->MinPaclen=tv;
     QSO_ChangeUser(cuser);
     break;
   case 25:
     cuser->MaxPaclen=tv;
     QSO_ChangeUser(cuser);
     break;
   case 26:
     cuser->CurPaclen=tv;
     QSO_ChangeUser(cuser);
     break;
   case 27:
     DoMethod(Object,MUIM_WriteString,tv,cuser->PrivateDir);
     QSO_ChangeUser(cuser);
     break;
   case 28:
     {
      unsigned char *tvp;
      tvp=(unsigned char *) tv;
      cuser->XPKType[0]=tvp[0];
      cuser->XPKType[1]=tvp[1];
      cuser->XPKType[2]=tvp[2];
      cuser->XPKType[3]=tvp[3];
      QSO_ChangeUser(cuser);
      break;
     }
   case 29:
     cuser->XPKEfficiency=tv;
     QSO_ChangeUser(cuser);
     break;
   case 30:
     cuser->Datacollector=tv;
     QSO_ChangeUser(cuser);
     break;
   case 999:
    set(UserSettingsWindow,MUIA_Window_Open,FALSE);
    if (GlobalArraysP->UserSetUser!=NULL)
     {
      QSO_CloseUser(GlobalArraysP->UserSetUser);
      GlobalArraysP->UserSetUser=NULL;
     }

  }

}

void GUIUSER_WriteKeyGad(unsigned long *cipher,unsigned char *buffer)
{
 char *sptr,*dptr;
 unsigned long code;
 unsigned long i;
 unsigned long codex;

#define rol(src,bits) ( ((src)<<bits) | ((src)>>(32-bits) ) )
#define ror(src,bits) ( ((src)>>bits) | ((src)<<(32-bits) ) )

 if ( (cipher[0]==0) && (cipher[1]==0) && (cipher[2]==0)
       && (cipher[3]==0) )
   {
    sptr=GUI_String(316);
    dptr=buffer;
    do { *(dptr++)=*(sptr++); } while (*(sptr-1)!='\0');
    return;
   }
 sptr=GUI_String(317);
 dptr=buffer;
 while (*sptr!='\0') *(dptr++)=*(sptr++);

 *(dptr++)=' ';
 *(dptr++)='(';
 code=ror(cipher[0],4);
 code=rol(code^cipher[1],8);
 code=ror(code^cipher[2],5);
 code=rol(code^cipher[3],7);
 for (i=0;i<8;++i)
  {
   code=rol(code,4);
   codex=code & 0xf;
   if (codex<10)
    {
     *(dptr++)='0'+codex;
    }
    else
    {
     *(dptr++)='A'+codex-10;
    }
  }
 *(dptr++)=')';
 *dptr='\0';

#undef rol
#undef ror

}

void GUIUSER_ReadKeyGad(unsigned long *cipher,unsigned char *buffer)
{
 unsigned long i,k,val;
 unsigned long newcipher[4];
 char *sptr;

 sptr=buffer;
 for (i=0;i<4;++i)
  {
   val=0;
   for (k=0;k<8;++k)
    {
     val=val<<4;
     if ( (*sptr>='0') && (*sptr<='9') )
      {
       val|=( (*sptr)-'0' );
      }
      else
      {
       if ( (*sptr>='a') && (*sptr<='f') )
         {
          val|=( *(sptr)-'a'+10);
         }
         else
         {
          if ( (*sptr>='A') && (*sptr<='F') )
            {
             val|=( *(sptr)-'A'+10);
            }
            else
            {
             return;
            }
         }
      }
     ++sptr;
    }
   newcipher[i]=val;
  }
 cipher[0]=newcipher[0];
 cipher[1]=newcipher[1];
 cipher[2]=newcipher[2];
 cipher[3]=newcipher[3];
}


