#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <fcntl.h>
#include <dos.h>

#include <devices/tpt.h>
#include <dialog/user.h>
#include <dialog/file.h>
#include <dialog/misc.h>
#include <dialog/input.h>
#include <dialog/portconfig.h>

#include <proto/dos.h>
#include <proto/dlg.h>

BOOL  MatchNames(char *, char *, ULONG);
SHORT Display_Computer_Types(void);

#define STK RStruct.Command_Stack
#define HOT StUser.Hot_Keys

extern struct Global_Settings Globals;
extern struct USER_DATA       StUser;
extern struct Ram_File        RStruct;
struct USER_DATA              NUTemp;

struct UserInfo ui = {
   &StUser, &RStruct}
;
struct Query    q1 = {
   NULL, NULL, NULL, NULL, NULL, 0, 0, 0}
;

extern struct Library *DLGBase;
extern char          **SA;


BYTE New_User(char *UserName, struct USER_DATA *User, char mode)
{
   char           *badnames = 0;
   char           *badalias = 0;
   char           *s;
   ULONG           nsize;
   ULONG           asize;
   long            a;
   long            try;

   char            zflag;
   char            string[2];
   char            template = 0;
   char            valid[80];
   char            temppassword[12];
   struct Question q;

   if (FileSize("DLGConfig:Misc/BadNames.BBS", &nsize) != -1)
   {
      if (nsize)
      {
         nsize++;
         badnames = malloc(nsize);
         if (badnames)
         {
            GetFirstStruct("DLGConfig:Misc/BadNames.BBS", badnames, nsize);
            *(badnames+nsize-1) = 0;

            for(s=badnames+nsize; s > badnames; s--)
            if (*s == '\n')  *s = 0;
         }
      }
   }

   if (FileSize("DLGConfig:Misc/BadAlias.BBS", &asize) != -1)
   {
      if (asize)
      {
         asize++;
         badalias = malloc(asize);
         if (badalias)
         {
            GetFirstStruct("DLGConfig:Misc/BadAlias.BBS", badalias, asize);
            *(badalias+asize-1) = 0;

            for(s=badalias+asize; s > badalias; s--)
            if (*s == '\n')  *s = 0;
         }
      }
   }


   if (GetFirstStruct("DLGCONFIG:Template/New_User.template",(char *)&NUTemp,sizeof(NUTemp))!=-1)
   template++;

   
   if (mode != 2  &&  mode != 3)
   {
      if (template)
      User->User_Level = NUTemp.User_Level;
      else
      User->User_Level = 1;

      if (OpenQuest("DLGCONFIG:text/application.txt")==-1)
      {
         AFPrintf(&StUser,Output(),SA[3544]);
         if (badnames)  free(badnames);
         if (badalias)  free(badalias);
         return(-1);
      }


      if (!UserName[0])  strcpy(UserName, SA[3545]);

      if (NextQuest(&q))
      {
         try = 0;
         while(TRUE)
         {
            try++;

            Chk_Abort();
            q1.prompt     = q.quest;
            q1.string     = UserName;
            q1.defstring  = UserName;
            q1.length     = 35;
            q1.typelength = 35;
            q1.flags      = QUERY_CAPITAL|QUERY_NOSTACK;
            DLGQuery(&q1, &ui);
            ScreenPath(UserName);
            DeScore(UserName);
            StripSpaces(UserName);

            if (!Stricmp(UserName, SA[3545]) || try > 3)
            {
               AFPrintf(&StUser,Output(),SA[3546]);
               CloseQuest();
               if (badnames)  free(badnames);
               if (badalias)  free(badalias);
               return(-1);
            }

            AFPrintf(NULL, Output(), "\n\n");
            AFPrintf(&StUser,Output(),SA[3548],UserName);
            zflag = finput(SA[3549],0);
            AFPrintf(NULL, Output(), "\n");
            if (!zflag)  continue;

            if (MatchNames(UserName, badnames, nsize))
            {
               AFPrintf(&StUser,Output(),SA[3567]);
               continue;
            }

            if (CheckUser(UserName))
            {
               AFPrintf(&StUser,Output(),SA[3547]);
               continue;
            }

            break;
         }
      }

      strcpy(User->Alias, UserName);
      if (NextQuest(&q))
      {
         try = 0;
         while(TRUE)
         {
            try++;

            Chk_Abort();
            q1.prompt     = q.quest;
            q1.template   = q.template;
            q1.string     = User->Alias;
            q1.defstring  = UserName;
            q1.length     = 32;
            q1.typelength = 32;
            q1.flags      = QUERY_CAPITAL|QUERY_NOSTACK|QUERY_NODEFEDT;
            DLGQuery(&q1, &ui);
            ScreenPath(User->Alias);
            DeScore(User->Alias);
            StripSpaces(User->Alias);

            if (try > 3)
            {
               AFPrintf(&StUser,Output(),SA[3546]);
               CloseQuest();
               if (badnames)  free(badnames);
               if (badalias)  free(badalias);
               return(-1);
            }

            if (MatchNames(User->Alias, badalias, asize))
            {
               AFPrintf(&StUser,Output(),SA[3568]);
               continue;
            }

            break;
         }
      }

      *User->Phone   = '\0';
      if (NextQuest(&q))
      {
         q1.prompt     = q.quest;
         q1.template   = q.template;
         q1.string     = User->Phone;
         q1.defstring  = NULL;
         q1.length     = 14;
         q1.typelength = 14;
         q1.flags      = QUERY_UPCASE|QUERY_NOSTACK|QUERY_NODEFEDT;
         while(!DLGQuery(&q1, &ui))
         Chk_Abort();
      }

      *User->Address = '\0';
      if (NextQuest(&q))
      {
         q1.prompt     = q.quest;
         q1.template   = q.template;
         q1.string     = User->Address;
         q1.defstring  = NULL;
         q1.length     = 25;
         q1.typelength = 25;
         q1.flags      = QUERY_UPCASE|QUERY_NOSTACK|QUERY_NODEFEDT;
         while(!DLGQuery(&q1, &ui))
         Chk_Abort();
      }

      *User->City    = '\0';
      if (NextQuest(&q))
      {
         q1.prompt     = q.quest;
         q1.template   = q.template;
         q1.string     = User->City;
         q1.defstring  = NULL;
         q1.length     = 23;
         q1.typelength = 23;
         q1.flags      = QUERY_UPCASE|QUERY_NOSTACK|QUERY_NODEFEDT;
         while(!DLGQuery(&q1, &ui))
         Chk_Abort();
      }

      *User->Prov    = '\0';
      if (NextQuest(&q))
      {
         q1.prompt     = q.quest;
         q1.template   = q.template;
         q1.string     = User->Prov;
         q1.defstring  = NULL;
         q1.length     = 5;
         q1.typelength = 5;
         q1.flags      = QUERY_UPCASE|QUERY_NOSTACK|QUERY_NODEFEDT;
         while(!DLGQuery(&q1, &ui))
         Chk_Abort();
      }

      *User->Country = '\0';
      if (NextQuest(&q))
      {
         q1.prompt     = q.quest;
         q1.template   = q.template;
         q1.string     = User->Country;
         q1.defstring  = NULL;
         q1.length     = 24;
         q1.typelength = 24;
         q1.flags      = QUERY_UPCASE|QUERY_NOSTACK|QUERY_NODEFEDT;
         while(!DLGQuery(&q1, &ui))
         Chk_Abort();
      }

      *User->postal  = '\0';

      if (NextQuest(&q))
      {
         q1.prompt     = q.quest;
         q1.template   = q.template;
         q1.string     = User->postal;
         q1.defstring  = NULL;
         q1.length     = 7;
         q1.typelength = 7;
         q1.flags      = QUERY_UPCASE|QUERY_NOSTACK|QUERY_NODEFEDT;
         while(!DLGQuery(&q1, &ui))
         Chk_Abort();
      }

      User->Birth_Year  = 0;
      if (NextQuest(&q))
      while(!(User->Birth_Year=IntQuery(q.quest,1,99,0,&ui)))
      Chk_Abort();

      User->Birth_Month = 1;
      if (NextQuest(&q))
      while(!(User->Birth_Month=IntQuery(q.quest,1,12,0,&ui)))
      Chk_Abort();

      User->Birth_Day   = 1;
      if (NextQuest(&q))
      while(!(User->Birth_Day=IntQuery(q.quest,1,31,0,&ui)))
      Chk_Abort();

      if (NextQuest(&q))
      while(TRUE)
      {
         q1.prompt     = q.quest;
         q1.template   = q.template;
         q1.string     = User->Password;
         q1.defstring  = NULL;
         q1.length     = 11;
         q1.typelength = 11;
         q1.flags      = QUERY_UPCASE|QUERY_HIDDEN|QUERY_NOSTACK|QUERY_NODEFEDT;
         while(!DLGQuery(&q1, &ui))
         Chk_Abort();
         AFPrintf(NULL, Output(), "\n\n");

         q1.prompt     = SA[3550];
         q1.template   = q.template;
         q1.string     = temppassword;
         q1.defstring  = NULL;
         q1.length     = 11;
         q1.typelength = 11;
         q1.flags      = QUERY_UPCASE|QUERY_HIDDEN|QUERY_NOSTACK|QUERY_NODEFEDT;
         while(!DLGQuery(&q1, &ui))
            Chk_Abort();

         if (strcmp(temppassword,User->Password))
         {
            AFPrintf(&StUser,Output(),SA[3551]);
            continue;
         }

         break;
      }

      User->Screen_Width = 80;
      if (NextQuest(&q))
      User->Screen_Width = IntQuery(q.quest,20,132,80,&ui);

      User->Screen_Len   = 23;
      if (NextQuest(&q))
      User->Screen_Len = IntQuery(q.quest,10,80,23,&ui);

      User->Ansi_Flag  = 0;
      if (NextQuest(&q))
      if (BoolQuery(q.quest, (StUser.Ansi_Flag & ANSI_COLOR), &ui))  User->Ansi_Flag |= ANSI_COLOR;

      if (NextQuest(&q))
      if (BoolQuery(q.quest, (StUser.Ansi_Flag & ANSI_POS), &ui))    User->Ansi_Flag |= ANSI_POS;

      if (NextQuest(&q))
      if (BoolQuery(q.quest, (StUser.Ansi_Flag & ANSI_CLR), &ui))    User->Ansi_Flag |= ANSI_CLR;

      if (NextQuest(&q))
      if (BoolQuery(q.quest, 0, &ui))  User->Ansi_Flag |= ANSI_SCROLL;

      User->More_Flag  = 1;
      if (NextQuest(&q))
      User->More_Flag = BoolQuery(q.quest, 1, &ui);

      User->Hot_Keys   = 1;
      if (NextQuest(&q))
      User->Hot_Keys  = BoolQuery(q.quest, 1, &ui);

      User->Help_Level = 0;

      User->send       = 0;
      if (NextQuest(&q))
      {
         AFPrintf(NULL, Output(), "\n\n");
         ListProtocols(User->User_Level, valid, PROTO_SEND, 1); 
         
         Chk_Abort();
         q1.prompt     = q.quest;
         q1.template   = q.template;
         q1.string     = string;
         q1.defstring  = NULL;
         q1.length     = 1;
         q1.typelength = 1;
         q1.flags      = QUERY_UPCASE|QUERY_NOSTACK|QUERY_NODEFEDT;
         DLGQuery(&q1, &ui);

         a = 0;
         while(valid[a]!='\0')
         if (valid[a++]==string[0])  User->send = string[0];
      }

      User->receive    = 0;
      if (NextQuest(&q))
      {
         AFPrintf(NULL, Output(), "\n\n");
         ListProtocols(User->User_Level, valid, PROTO_REC, 1);

         Chk_Abort();
         q1.prompt     = q.quest;
         q1.template   = q.template;
         q1.string     = string;
         q1.defstring  = NULL;
         q1.length     = 1;
         q1.typelength = 1;
         q1.flags      = QUERY_UPCASE|QUERY_NOSTACK|QUERY_NODEFEDT;
         DLGQuery(&q1, &ui);

         a = 0;
         while(valid[a]!='\0')
         if (valid[a++]==string[0])  User->receive=string[0];
      }

      User->archiver   = 0;
      if (NextQuest(&q) && Exists("DLGConfig:Misc/Archivers.bbs"))
      {
         AFPrintf(NULL, Output(), "\n\n");
         User->archiver = IntQuery(q.quest, 1, ListArchivers(User->User_Level,COMPRESS), 0, &ui);
         if (!CheckArchiver(User->archiver,User->User_Level,COMPRESS))  User->archiver = 0;
      }

      User->Editor     = 0;
      if (NextQuest(&q) && Exists("DLGConfig:Misc/Editors.bbs"))
      {
         AFPrintf(NULL, Output(), "\n\n");
         User->Editor = IntQuery(q.quest, 1, ListEditors(User->User_Level), 0, &ui);
         if (!CheckEditor(User->Editor,User->User_Level))  User->Editor = 0;
      }

      if (!User->Editor)
      {
         int           fp;
         struct Editor editor;

         if ((fp=open("DLGCONFIG:Misc/Editors.bbs", O_RDONLY))!=EOF)
         {
            while(read(fp,&editor,sizeof(editor))==sizeof(editor))
            {
               Upper(editor.callstring);
               if (strstr(editor.callstring, "LINEEDIT"))
               {
                  User->Editor = editor.number;
                  break;
               }
            }
            close(fp);
         }
      }

      User->menuset    = 0;
      if (NextQuest(&q) && Exists("DLGConfig:Misc/MenuSets.bbs"))
      {
         AFPrintf(NULL, Output(), "\n\n");
         User->menuset=IntQuery(q.quest, 1, ListMenuSets(User->User_Level), 0, &ui);
         if (!CheckMenuSet(User->menuset,User->User_Level))  User->menuset=0;
      }

      User->charset    = 0;
      if (NextQuest(&q) && Exists("DLGConfig:CharSets/CharSets.bbs"))
      {
         AFPrintf(NULL, Output(), "\n\n");
         ListSets(User->User_Level);
         User->charset=IntQuery(q.quest, 1, 255, 0, &ui);
         if (!CheckSet(User->charset,User->User_Level))  User->charset=0;
      }

      User->Computer_Type = 1;
      if (NextQuest(&q))
      {
         do{
            a = Display_Computer_Types();
         }
         while(!(User->Computer_Type=IntQuery(q.quest, 1, a, 0, &ui)));
      }

      CloseQuest();
   }

   if (mode  &&  mode != 3)
   {
      User->User_Level      = IntQuery (SA[3552], 1, 255, Globals.NewUserLevel, &ui);
      User->Ratio           = IntQuery (SA[3553], 0, 127, NUTemp.Ratio, &ui);
      User->Pop_Screen      = BoolQuery(SA[3554], 0, &ui);
      User->Bulletin_Access = BoolQuery(SA[3555], 0, &ui);
      User->Daily_Limit     = IntQuery (SA[3556], 1, 1440, Globals.Daily_Limit,   &ui);
      User->Session_Limit   = IntQuery (SA[3557], 1, 1440, Globals.Session_Limit, &ui);

      Chk_Abort();
      q1.prompt     = SA[3558];
      q1.template   = NULL;
      q1.string     = string;
      q1.defstring  = SA[3559];
      q1.length     = 8;
      q1.typelength = 8;
      q1.flags      = 0;
      DLGQuery(&q1, &ui);
      User->Bytes_Uploaded = atol(string)*1024L;

      Chk_Abort();
      q1.prompt     = SA[3560];
      q1.template   = NULL;
      q1.string     = string;
      q1.defstring  = SA[3559];
      q1.length     = 8;
      q1.typelength = 8;
      q1.flags      = 0;
      DLGQuery(&q1, &ui);
      User->Bytes_Downloaded = atol(string)*1024L;

      Chk_Abort();
      q1.prompt     = SA[3561];
      q1.template   = NULL;
      q1.string     = string;
      q1.defstring  = NULL;
      q1.length     = 1;
      q1.typelength = 1;
      q1.flags      = 0;
      DLGQuery(&q1, &ui);
      if (string[0]=='C')
      User->UUCP = 1;
      else
      if (string[0]=='W')
      User->UUCP = 2;
      else
      User->UUCP = 0;
      
      User->DirLimit = IntQuery(SA[3562], 0, 29000, Globals.DirLimit, &ui);
      User->credit   = IntQuery(SA[3563], 0, 32000, 0,                &ui);
      User->NetMail  = 0;

      if (BoolQuery(SA[3564], 1, &ui))  User->NetMail += 1;
      if (BoolQuery(SA[3565], 0, &ui))  User->NetMail += 2;

      AFPrintf(NULL, Output(), "\n\n");
   }
   else
   if (template && mode!=3)
   {
      User->User_Level       = NUTemp.User_Level;
      User->Ratio            = NUTemp.Ratio;
      User->Pop_Screen       = NUTemp.Pop_Screen;
      User->Bulletin_Access  = NUTemp.Bulletin_Access;
      User->Daily_Limit      = NUTemp.Daily_Limit;
      User->Session_Limit    = NUTemp.Session_Limit;
      User->UUCP             = NUTemp.UUCP;
      User->DirLimit         = NUTemp.DirLimit;
      User->credit           = NUTemp.credit;
      User->NetMail          = NUTemp.NetMail;
      User->Bytes_Uploaded   = NUTemp.Bytes_Uploaded;
      User->Bytes_Downloaded = NUTemp.Bytes_Downloaded;
   }
   else
   if (mode==3)
   {
      User->User_Level       = 255;
      User->Ratio            =  0;
      User->Pop_Screen       =  0;
      User->Bulletin_Access  =  1;
      User->Daily_Limit      = 1440;
      User->Session_Limit    = 1440;
      User->UUCP             =  0;
      User->DirLimit         = 10000;
      User->credit           = 10000;
      User->NetMail          =  3;
      User->Computer_Type    =  1;
      User->Screen_Len       = 23;
      User->Bytes_Uploaded   =  0;
      User->Bytes_Downloaded =  0;
   }
   else
   {
      User->User_Level       =  1;
      User->Ratio            =  0;
      User->Pop_Screen       =  0;
      User->Bulletin_Access  =  0;
      User->Daily_Limit      = 20;
      User->Session_Limit    = 40;
      User->UUCP             =  0;
      User->DirLimit         = 100;
      User->credit           =  0;
      User->NetMail          =  0;
      User->Bytes_Uploaded   =  0;
      User->Bytes_Downloaded =  0;
   }


   User->Daily_Used       =  0;
   User->msgsig           =  0;
   User->filesig          =  0;
   User->fileorder        = 'F';
   User->filesince        = 'A';
   strcpy(User->Temp_Filler, "\000\000\000\000\000\000");
   User->Last_Area        = -1;
   User->Lex_Flag         =  1;
   User->Private_Flag     =  0;
   User->ThreadMode       =  0;
   User->Total_Calls      =  0;
   User->Online_Time      =  0;
   User->Messages_Entered =  0;
   User->Messages_Read    =  0;
   User->Files_Uploaded   =  0;
   User->Files_Downloaded =  0;
   User->Sysop_Pages      =  0;
   User->Last_File_Area   = -1;
   strcpy(User->stack, Globals.CmdStack);
   User->protocol         =  0;
   User->captureflags     =  0;

   MDate(User->Last_Login);
   User->Long_Date  = AmigaTime();
   User->DateJoined = User->Long_Date;

   AFPrintf(NULL, Output(), "\n\n");

   if (badnames)  free(badnames);
   if (badalias)  free(badalias);
   return(0);
}


BOOL MatchNames(char *name, char *table, ULONG size)

{
   char *end;

   if (table)
   {
      for(end = table+size; end > table; end--)
      if (*end)  break;

      while(table < end)
      {
         if (DLGPatternMatch(table, name))  return(TRUE);

         while(*table)
         table++;
         table++;
      }
   }

   return(FALSE);
}


SHORT Display_Computer_Types()

{
   struct Computer_Type Ct;
   int                  fp;
   SHORT                count = 0;

   AFPrintf(NULL,Output(), "\n\n");

   if ((fp = open("DlgConfig:Port/ComputerTypes.bbs",O_RDONLY)) != EOF)
   {
      while(read(fp,&Ct,sizeof(Ct)) == sizeof(Ct))
      {
         count++;
         AFPrintf(&StUser,Output(),SA[3566],Ct.Number,Ct.Name);
      }

      close(fp);
   }

   return(count);
}
