/* **** HBBS Door Code****************************************************** */

/*
  DoorName
  ========

    what the door does

  Version
  =======

    x.xx, release xx, dd/mm/yyyy

  Options
  =======

    N_ND->ActiveDoor->SystemOptions
    -------------------------------



    Command Line Arguments
    ----------------------

    2  <option>

    3  ...

    4  .

  ToDo
  ====

    what you still have to do



*/

/* **** Includes *********************************************************** */

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

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

#include <HBBS/ANSI_Codes.h>
#include <HBBS/Defines.h>
#include <HBBS/types.h>
#include <HBBS/access.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>

/* **** Variables ********************************************************** */


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

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

long __stack=8*1024; // increse this in 4k incrments if you suffer from
                     // random/suprious crashings after or during the running
                     // of your door.

int    gargc;        // these are just copies of main()'s argc and argv..
char   **gargv;

struct CfgFileData *CfgFile;
struct List *OtherDoorText=NULL;
struct List *OtherDoorCmds=NULL;
struct List *OtherDoorOpts=NULL;
ULONG OtherDoors=0,startfrom;
BOOL DisplayAgain=TRUE;

/* **** Functions ********************************************************** */


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

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);
}

void DisplayIt( ULONG optnum, UBYTE *optstr,UBYTE *optdatastr,BOOL Enabled)
{
  sprintf(outstr,ANSI_RESET "%s[ "ANSI_FG_WHITE"%2d %s]" ANSI_FG_WHITE " %-20s " ANSI_FG_BLUE ": " ANSI_FG_CYAN "%s[K\r\n"ANSI_RESET,Enabled ? ANSI_FG_YELLOW : ANSI_FG_RED,optnum,Enabled ? ANSI_FG_YELLOW : ANSI_FG_RED,optstr,optdatastr);
  DOOR_WriteText(outstr);
}

BOOL ChangeOption(ULONG optionnum)
{
  UBYTE tmpstr[80];
  ULONG MaxLen=48;
  BOOL HasAccess=FALSE;

  if (optionnum<startfrom)
  {
    tmpstr[0]=0;

    switch(optionnum)
    {
      case 1:
        strcpy(tmpstr,N_ND->User.CallData.Handle);
        MaxLen=LEN_HANDLE;
        HasAccess=HBBS_CheckAccess(ACS_EDITHANDLE);
        break;
      case 2:
        strcpy(tmpstr,N_ND->User.CallData.RealName);
        MaxLen=LEN_REALNAME;
        HasAccess=HBBS_CheckAccess(ACS_EDITREALNAME);
        break;
      case 3:
        strcpy(tmpstr,N_ND->User.CallData.Password);
        MaxLen=LEN_PASSWORD;
        HasAccess=HBBS_CheckAccess(ACS_EDITPASSWORD);
        break;
      case 4:
        strcpy(tmpstr,N_ND->User.CallData.Group);
        MaxLen=LEN_GROUP;
        HasAccess=HBBS_CheckAccess(ACS_EDITGROUP);
        break;
      case 5:
        strcpy(tmpstr,N_ND->User.CallData.GeoLocation);
        MaxLen=LEN_GEOLOCATION;
        HasAccess=HBBS_CheckAccess(ACS_EDITLOCATION);
        break;
      case 6:
        strcpy(tmpstr,N_ND->User.CallData.Country);
        MaxLen=LEN_COUNTRY;
        HasAccess=HBBS_CheckAccess(ACS_EDITCOUNTRY);
        break;
      case 7:
        strcpy(tmpstr,N_ND->User.CallData.PhoneNumber);
        MaxLen=LEN_PHONENUMBER;
        HasAccess=HBBS_CheckAccess(ACS_EDITPHONENUMBER);
        break;
      case 8:
        strcpy(tmpstr,N_ND->User.CallData.ComputerType);
        MaxLen=LEN_COMPUTERTYPE;
        HasAccess=HBBS_CheckAccess(ACS_EDITCOMPUTER);
        break;
    }

    if (HasAccess)
    {
      // go to where the option is already printed on the screen, and ask for it again!

      sprintf(outstr,"[%ld;31H[K"ANSI_RESET ANSI_FG_WHITE,3+optionnum);
      DOOR_WriteText(outstr);


      DOOR_GetLine(GL_DISPLAY|GL_EDIT|GL_HISTORY|GL_NORETURN,'\0',MaxLen,0,tmpstr);
      if (N_ND->OnlineStatus==OS_ONLINE && N_ND->CurrentLine[0])
      {

        switch(optionnum)
        {
          case 1: // HANDLE

            // check the handle is ok..

            RemoveSpaces(N_ND->CurrentLine);
            if (strlen(N_ND->CurrentLine) >= 3) // big enough ?
            {
              // it's OK..

              // change the handle to something that's not going to be used..
              strcpy(N_ND->User.NormalData.Handle,"ALL"); // like this..


              // and then save the data.
              HBBS_SaveUserData(&N_ND->User.NormalData);

              // then check to see if someone else is using the handle that the user
              // wants to change thier one to..

              if (!HBBS_ValidUserHandle(N_ND->CurrentLine,NULL))
              {
                // no-one else is using the name, so set it to what the user wants..

                strNcpy(N_ND->User.CallData.Handle,N_ND->CurrentLine,MaxLen);
                strNcpy(N_ND->User.NormalData.Handle,N_ND->CurrentLine,MaxLen);

                // and save IMMEDIATELY! before anyone else tries to use it! :-)

                HBBS_SaveUserData(&N_ND->User.NormalData);
              }
            }
            break;
          case 2:
            strNcpy(N_ND->User.CallData.RealName,N_ND->CurrentLine,MaxLen);
            strNcpy(N_ND->User.NormalData.RealName,N_ND->CurrentLine,MaxLen);
            break;
          case 3:
            if (strlen(N_ND->CurrentLine)>=BBSGlobal->MinPasswordLength)
            {
              strNcpy(N_ND->User.CallData.Password,N_ND->CurrentLine,MaxLen);
              strNcpy(N_ND->User.NormalData.Password,N_ND->CurrentLine,MaxLen);
            }
            break;
          case 4:
            strNcpy(N_ND->User.CallData.Group,N_ND->CurrentLine,MaxLen);
            strNcpy(N_ND->User.NormalData.Group,N_ND->CurrentLine,MaxLen);
            break;
          case 5:
            strNcpy(N_ND->User.CallData.GeoLocation,N_ND->CurrentLine,MaxLen);
            strNcpy(N_ND->User.NormalData.GeoLocation,N_ND->CurrentLine,MaxLen);
            break;
          case 6:
            strNcpy(N_ND->User.CallData.Country,N_ND->CurrentLine,MaxLen);
            strNcpy(N_ND->User.NormalData.Country,N_ND->CurrentLine,MaxLen);
            break;
          case 7:
            strNcpy(N_ND->User.CallData.PhoneNumber,N_ND->CurrentLine,MaxLen);
            strNcpy(N_ND->User.NormalData.PhoneNumber,N_ND->CurrentLine,MaxLen);
            break;
          case 8:
            strNcpy(N_ND->User.CallData.ComputerType,N_ND->CurrentLine,MaxLen);
            strNcpy(N_ND->User.NormalData.ComputerType,N_ND->CurrentLine,MaxLen);
            break;
        }
      }
    }
  }
  else
  {
    DOOR_WriteText("[K");
    DOOR_UserDoor(HBBS_ListName(OtherDoorCmds,optionnum-startfrom),HBBS_ListName(OtherDoorOpts,optionnum-startfrom));
  }

  if (N_ND->OnlineStatus==OS_ONLINE)
  {
    DOOR_WriteText(ANSI_CLS);
    DisplayAgain=TRUE;
    return(FALSE);
  } else return(TRUE);
}


void DisplaySettings( void )
{
  ULONG loop;

  DOOR_WriteText("[1;1H[0;36m-=[ [0;3;37;44m Hydra User Config [0;36;40m ]=- [35m=========== [36m-=[[35m [0;3;33;44m (C) 1995 Deluxe Software Ltd. [0;35;40m [36m]=-\r\n");

  DOOR_WriteText("If an option has RED brackets you cannot change it.\r\n\r\n");

  DisplayIt(1,"Handle",N_ND->User.CallData.Handle,HBBS_CheckAccess(ACS_EDITHANDLE));
  DisplayIt(2,"Real Name",N_ND->User.CallData.RealName,HBBS_CheckAccess(ACS_EDITREALNAME));
  DisplayIt(3,"Password","<not displayed!>",HBBS_CheckAccess(ACS_EDITPASSWORD));
  DisplayIt(4,"Group",N_ND->User.CallData.Group ,HBBS_CheckAccess(ACS_EDITGROUP ));
  DisplayIt(5,"City",N_ND->User.CallData.GeoLocation ,HBBS_CheckAccess(ACS_EDITLOCATION ));
  DisplayIt(6,"Country",N_ND->User.CallData.Country ,HBBS_CheckAccess(ACS_EDITCOUNTRY ));
  DisplayIt(7,"PhoneNumber",N_ND->User.CallData.PhoneNumber ,HBBS_CheckAccess(ACS_EDITPHONENUMBER ));
  DisplayIt(8,"Computer",N_ND->User.CallData.ComputerType ,HBBS_CheckAccess(ACS_EDITCOMPUTER ));

  startfrom=9; // *MUST* be highest number passed to DisplayIt + 1 (or system failure!)

  if (OtherDoors)
  {
    for (loop=0;loop<OtherDoors;loop++)
    {
      DisplayIt(loop+startfrom,HBBS_ListName(OtherDoorText,loop),"",TRUE);
    }
  }
  DOOR_WriteText("\r\n");
}


void FreeCfgStuff( void )
{
  if (CfgFile)
  {
    HBBS_FlushConfig(CfgFile);
    CfgFile=NULL;
  }
  if (OtherDoorText)
  {
    FreeStrList(OtherDoorText);
    OtherDoorText=NULL;
  }
  if (OtherDoorCmds)
  {
    FreeStrList(OtherDoorCmds);
    OtherDoorCmds=NULL;
  }
  if (OtherDoorOpts)
  {
    FreeStrList(OtherDoorOpts);
    OtherDoorOpts=NULL;
  }
  OtherDoors=0;
}

/* **** DoorMain *********************************************************** */

void DoorMain( void )
{
  // reminder:
  // gargv[2] is the first option you should access
  // gargc should always be one higher than the gargv[] that you want to check!

  BOOL Quit=FALSE;
  UBYTE CfgFileName[BIG_STR],*Where;
  LONG tmpnum;

  int loop;
  for(loop=2;loop<gargc;loop++) // if there are any parameters then display them
  {
    sprintf(outstr,"Parameter %d = %s\n\r",loop-1,gargv[loop]);
    DOOR_WriteText(outstr);
  }

  strcpy(CfgFileName,gargv[0]);

  Where=FilePart(CfgFileName);
  *Where=0; // null terminate at char after the last '/'

  strcat(CfgFileName,"UserSettings.CFG");

  if (CfgFile=HBBS_LoadConfig(CfgFileName))
  {
    OtherDoors=HBBS_GetSetting(CfgFile,(void *)&OtherDoorText,VTYPE_STRINGLIST,"DoorDescription",OPT_MULTI);
    tmpnum=HBBS_GetSetting(CfgFile,(void *)&OtherDoorCmds,VTYPE_STRINGLIST,"DoorCommand",OPT_MULTI);
    if ((tmpnum!=OtherDoors) || (OtherDoors!=HBBS_GetSetting(CfgFile,(void *)&OtherDoorOpts,VTYPE_STRINGLIST,"DoorOptions",OPT_MULTI)))
    {
      sprintf(outstr,"Error in config file \"%s\"",CfgFileName);
      HBBS_LogError(BBSGlobal->ErrorLogFile,ERR_GENERAL,outstr,TYPE_WARNING);
      FreeCfgStuff();
    }
  }
  else
  {
    sprintf(outstr,"Cannot find the configuration file \"%s\"",CfgFileName);
    HBBS_LogError(BBSGlobal->ErrorLogFile,ERR_GENERAL,outstr,TYPE_WARNING);

  }

  DOOR_WriteText(ANSI_RESET ANSI_CLS);

  do
  {
    if (DisplayAgain) DisplaySettings();
    DisplayAgain=FALSE;

    DOOR_WriteText(ANSI_RESET "[K");
    DOOR_MenuPrompt("[OptionNumber], [D]isplay Again, [Q]uit "ANSI_FG_BLUE": "ANSI_FG_WHITE,' ');

    strcpy(N_ND->CharsAllowed,"0123456789QqDd");
    DOOR_GetLine(GL_EDIT|GL_DISPLAY|GL_USECHARS|GL_NORETURN,'\0',2,0,NULL);
    if (N_ND->OnlineStatus==OS_OFFLINE)
    {
      Quit=TRUE;
    }
    else
    {
      if (N_ND->OnlineStatus==OS_ONLINE) DOOR_WriteText("\r[k");

      RemoveSpaces(N_ND->CurrentLine);
      switch (toupper(N_ND->CurrentLine[0]))
      {
        case 'Q':
          Quit=TRUE;
          break;

        case 'D':
          DisplayAgain=TRUE;
          break;

        case 0:
        case ' ':
          break;

        default:
          if (sscanf(N_ND->CurrentLine,"%ld",&tmpnum))
          {
            if (tmpnum>=1 && tmpnum<=startfrom+OtherDoors)
            {
              Quit=ChangeOption(tmpnum);
            }
          }
          break;
      }
    }

  } while (!Quit);

  // free memory!

  FreeCfgStuff();

  if (N_ND->OnlineStatus==OS_ONLINE)
  {
    DOOR_WriteText("\r\n");
    HBBS_SaveUserData(&N_ND->User.NormalData);
    DOOR_WriteText("Your user data has been updated!\r\n");
    N_ND->Actions[ACTN_CHANGEDSETTINGS]=ACTC_CHANGEDSETTINGS;

  }
}

int main(int argc,char **argv)
{
  gargc=argc;
  gargv=argv;

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

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

/* **** End Of File ******************************************************** */
