/*

   NewUser
   =======

*/


#include <exec/types.h>
#include <exec/memory.h>
#include <clib/exec_protos.h>
#include <clib/alib_protos.h>

#include <dos/dos.h>
#include <clib/dos_protos.h>

#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <ctype.h>
#include <time.h>


#ifdef __SASC
int CXBRK(void) { return(0); }
int _CXBRK(void) { return(0); }
void chkabort(void) {}
#endif

#include <HBBS/Defines.h>
#include <HBBS/types.h>
#include <HBBS/structures.h>
#include <HBBS/hbbscommon_protos.h>
#include <HBBS/hbbscommon_pragmas.h>
#include <HBBS/Hbbsnode_protos.h>
#include <HBBS/Hbbsnode_pragmas.h>
#include <HBBS/ANSI_Codes.h>
#include <HBBS/release.h>
char *versionstr="$VER: NewUser "RELEASE_STR;

ULONG __stack=20000;

struct Library *HBBSCommonBase=NULL;
struct Library *HBBSNodeBase=NULL;

struct BBSGlobalData *BBSGlobal=NULL;
struct NodeData *N_ND=NULL;
int N_NodeNum=-1;
char outstr[BIG_STR];

static VOID cleanup(ULONG num)
{
  if (HBBSNodeBase)
  {
    HBBS_CleanUpDoor();
    CloseLibrary (HBBSNodeBase);
  }

  if (HBBSCommonBase)
  {
    HBBS_CleanUpCommon();
    CloseLibrary (HBBSCommonBase);
  }

  if (num) printf("Door Error = %d\n",num);

  exit(0);
}

static VOID init(char *name)
{
  if(!(HBBSCommonBase = OpenLibrary("HBBSCommon.library",0)))
  {
    cleanup(1);
  }

  if (!(HBBS_InitCommon()))
  {
    cleanup(2);
  }

  if(!(HBBSNodeBase = OpenLibrary("HBBSNode.library",0)))
  {
    cleanup(3);
  }

  if (!(HBBS_InitDoor(N_NodeNum,name)))
  {
    cleanup(4);
  }
  SetProgramName(name);
}


/********************************* ACTUAL DOOR CODE **************************/

BOOL GetOption(char *prompt,char *destination,short minlen, short maxlen, BOOL required)
{
  // returns FALSE for carrier loss, or true when done
  BOOL Done=FALSE;
  while (N_ND->OnlineStatus==OS_ONLINE && !Done)
  {
    DOOR_WriteText(ANSI_RESET ANSI_FG_YELLOW);
    DOOR_WriteText(prompt);
    DOOR_WriteText(ANSI_FG_BLUE " : " ANSI_FG_WHITE);
    if (DOOR_GetLine(GL_EDIT|GL_DISPLAY|GL_HISTORY,'\0',maxlen,0,NULL)==IN_GOTLINE)
    {
      if (strlen(N_ND->CurrentLine)>=minlen && strlen(N_ND->CurrentLine)<=maxlen)
      {
        strcpy(destination,N_ND->CurrentLine);
        Done=TRUE;
      }
      if (!required && N_ND->CurrentLine[0]==0) Done=TRUE;
    }
  }
  return(Done);
}

void DoorMain( int argc,char *argv[] )
{
  BOOL Done=FALSE;
  BOOL UserAdded=FALSE;
  short loop;
  char tmpstr[BIG_STR];
  struct CfgFileData *NewUserCFG=NULL;
  BOOL ConfigOK=FALSE;
  struct UserData NU;
  short p;

  strcpy(outstr,argv[0]);
  if ((p=iposition(".HBBS",outstr))==(strlen(outstr)-5))
  {
    outstr[p]=0; //terminate string
  }
  strcat(outstr,".CFG");

  if (NewUserCFG=HBBS_LoadConfig(outstr,LCFG_NONE))
  {
    if (HBBS_GetSetting(NewUserCFG,(void *)&NU.Access,VTYPE_BIGNUM,"AccessLevel",OPT_SINGLE) &&
        HBBS_GetSetting(NewUserCFG,(void *)&NU.LastConf,VTYPE_BIGNUM,"ConfNum",OPT_SINGLE) &&
        HBBS_GetSetting(NewUserCFG,(void *)&NU.TimeAllowed,VTYPE_BIGNUM,"TimeAllowed",OPT_SINGLE))
    {
      ConfigOK=TRUE;
    }
    HBBS_FlushConfig(NewUserCFG);
  }

  if (!ConfigOK)
  {
    DOOR_PausePrompt("The NewUser door's config file could not be found or has errors\r\nA new user could not be created! - Press Return\r\n");
  }
  else
  {
    // initialise UserData structure for our new user.

    HBBS_InitUserData(&N_ND->User.CallData,NU.Access,NU.LastConf);
    N_ND->User.CallData.TimeAllowed=NU.TimeAllowed;

    // Get the users handle from the parameters passed to the door, remembering
    // that the users handle MAY have spaces in it..

    N_ND->User.CallData.Handle[0]=0;
    for (loop=2;loop<argc;loop++)
    {
      if (loop!=2) strcat(N_ND->User.CallData.Handle," ");
      strcat(N_ND->User.CallData.Handle,argv[loop]);
    }

    // Ok, we need to see if new users are allowed
    // a) at this time
    // b) on this node

    // *C* add time check..

    if (N_ND->NodeSettings.AllowNewUsers==FALSE)
    {
      DOOR_DisplaySpecialScreen(SSCREEN_NONEWAT_ALL);
    }
    else
    {
      // *C* display the screen "NoNewAt_ThisTime" if user is not allowed at this time.

      // display the screen "NoNewAt_BAUD" if users modem is too slow..

      sprintf(tmpstr,"NoNewAt_%s",N_ND->ConnectBaud);
      if (DOOR_DisplaySpecialScreen(tmpstr))
      {
        DOOR_HangUp();
        N_ND->OnlineStatus=OS_OFFLINE;
      }
      else
      {

        while (N_ND->OnlineStatus==OS_ONLINE && !Done)
        {
          DOOR_DisplaySpecialScreen("GuestLogin");
          sprintf(tmpstr,ANSI_RESET ANSI_CLS ANSI_FG_CYAN "You now need to enter a password to use on this system, make sure it is at\r\n"
                         "least %d character%s long, preferably with some numbers in it somewhere\r\n",BBSGlobal->MinPasswordLength,BBSGlobal->MinPasswordLength == 1 ? "" : "s");
          DOOR_WriteText(tmpstr);
          if (GetOption("Password To Use",N_ND->User.CallData.Password,BBSGlobal->MinPasswordLength,LEN_PASSWORD,TRUE))
          {
            DOOR_WriteText(ANSI_FG_CYAN"Please Enter Your Real Name\r\n");
            if (GetOption("Real Name",N_ND->User.CallData.RealName,3,LEN_REALNAME,FALSE))
            {
              DOOR_WriteText(ANSI_FG_CYAN "If you are in any scene groups, then enter the name of them now\r\n"
                             "(Note: This is used by WHO doors and bulletins to display a bit of\r\n"
                             "Information about you)\r\n");
              if (GetOption("Scene Group",N_ND->User.CallData.Group,2,LEN_GROUP,FALSE))
              {
                DOOR_WriteText(ANSI_FG_CYAN "Enter the name of the town/city you are calling from\r\n");
                if (GetOption("City",N_ND->User.CallData.GeoLocation,3,LEN_GEOLOCATION,FALSE))
                {
                  DOOR_WriteText(ANSI_FG_CYAN "Enter The Country you are calling from\r\n");
                  if (GetOption("Country",N_ND->User.CallData.Country,2,LEN_COUNTRY,FALSE))
                  {
                    DOOR_WriteText(ANSI_FG_CYAN "Please enter your voice phone number\r\n");
                    if (GetOption("Phone Number",N_ND->User.CallData.PhoneNumber,5,LEN_PHONENUMBER,FALSE))
                    {
                      DOOR_WriteText(ANSI_FG_CYAN "Please enter details of all your computers\r\n");
                      if (GetOption("Computer Type",N_ND->User.CallData.ComputerType,2,LEN_COMPUTERTYPE,FALSE))
                      {
                        DOOR_WriteText(ANSI_FG_YELLOW"\r\nThankyou!\r\n");

                        // We have to add the user to the userdatafile here so that the doors that we call
                        // in a moment can access the user in the user.data file...

                        if (HBBS_AddUser(&N_ND->User.CallData))
                        {
                          CopyMem(&N_ND->User.CallData,&N_ND->User.NormalData,sizeof(struct UserData));
                          N_ND->User.Valid=TRUE;

                          N_ND->User.CallData.Language=1;
                          N_ND->User.NormalData.Language=1;

                          DOOR_SystemDoor("SelectLanguage",NULL);
                          if (N_ND->OnlineStatus==OS_ONLINE)
                          {
                            DOOR_SystemDoor("LinesPerScreen",NULL);
                            if (N_ND->OnlineStatus==OS_ONLINE)
                            {
                              DOOR_UserDoor("SENT",NULL);
                              if (N_ND->OnlineStatus==OS_ONLINE)
                              {
                                HBBS_SaveUserData(&N_ND->User.CallData);
                                DOOR_DisplaySpecialScreen("Joined");
                                N_ND->Actions[ACTN_NEWUSER]=ACTC_NEWUSER;
                                UserAdded=TRUE;
                                sprintf(tmpstr,"Created a new user: %s / %s",N_ND->User.CallData.Handle,N_ND->User.CallData.Group);
                                HBBS_LogError(BBSGlobal->ErrorLogFile,ERR_GENERAL,tmpstr,TYPE_WARNING);
                                Done=TRUE;
                              }
                            }
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  }
  if (!UserAdded)
  {
    DOOR_SysopText("Failed to add user\r\n");
    HBBS_LogError(BBSGlobal->ErrorLogFile,ERR_GENERAL,"Failed To Create A NewUser Account",TYPE_WARNING);
  }

  DOOR_Return(UserAdded ? "USERADDED" : "FAILED");
  DOOR_Continue(FALSE);
}

int main(int argc,char *argv[])
{
  if (sscanf(argv[1],"%d",&N_NodeNum)==0)
  {
    printf("Invalid/No Paramaters for door!\n");
    exit (20);
  }
  init("NewUser");

  if (BBSGlobal=HBBS_GimmeBBS())
  {
    if (N_ND=HBBS_NodeDataPtr(N_NodeNum)) // this should not fail in normal circumstances..
    {
      DoorMain(argc,argv);
    }
  }
  cleanup(0);
}
