/*

 function of the confjoin door

 - check parameters for FORWARD, BACKWARD or a valid conference number.
   - if no parameters or invalid conference number then display all confereneces
     that the user is allowed to see and let the user select one
 - set N_ND->CurrentConf to the conference selected
 - load the access data for that conference

*/


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

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

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

struct BBSGlobalData *BBSGlobal=NULL;
struct NodeData *N_ND=NULL;
int N_NodeNum=-1;

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(VOID)
{
  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,"JoinConference")))
  {
    cleanup(4);
  }
}

BOOL AllowAccess(V_BIGNUM confnum)
{
  struct ConfData *tmpconf;

  if (confnum>0 && confnum<=BBSGlobal->Conferences)
  {
    tmpconf=(struct ConfData *)GetNode(BBSGlobal->ConfList,confnum-1);

    // confaccess level higher than user's access level ?

    if (tmpconf->ConfAccess>N_ND->User.CallData.Access)
    {
      return(FALSE);
    }
    else
    {
      return(TRUE);
    }
  }
  return(FALSE);
}

void AccessDenied( void )
{
  DOOR_WriteText(ANSI_RESET ANSI_FG_RED "Access to that conference is restricted\r\n" ANSI_RESET);
}

#define CONF_FORWARD  1
#define CONF_BACKWARD 2
#define CONF_REJOIN   3

void DoorMain(int argc,char *argv[])
{
  char outstr[100];
  short loop;
  struct Node *node;
  BOOL FirstTime=TRUE;
  V_BIGNUM confnum=0;
  V_BIGNUM lastconf=0;

  BOOL CmdLine=TRUE;

  LONG Mode=0;

  if (N_ND->CurrentConf) lastconf=N_ND->CurrentConf->ConfNum;

  // we'll have a loop here for the moment even tho we only use one parameter

  for(loop=2;loop<argc;loop++)
  {
    if (loop==2)
    {
      confnum=atoi(argv[loop]);
    }
  }

  if (N_ND->ActiveDoor->SystemOptions && (stricmp("BACKWARD",N_ND->ActiveDoor->SystemOptions))==0)
  {
    Mode=CONF_BACKWARD;
    confnum=lastconf-1;
    CmdLine=FALSE;
  }
  if (N_ND->ActiveDoor->SystemOptions && (stricmp("FORWARD",N_ND->ActiveDoor->SystemOptions))==0)
  {
    Mode=CONF_FORWARD;
    confnum=lastconf+1;
    CmdLine=FALSE;
  }
  if (N_ND->ActiveDoor->SystemOptions && (stricmp("REJOIN",N_ND->ActiveDoor->SystemOptions))==0)
  {
    Mode=CONF_REJOIN;
    confnum=lastconf;
    CmdLine=FALSE;
  }

  if (Mode==CONF_FORWARD) // keep skipping forwards until we find a conference that we have access to
  {
    while ((confnum<=BBSGlobal->Conferences) && (!AllowAccess(confnum)))
    {
      confnum++;
    }
  }

  if (Mode==CONF_BACKWARD) // keep skipping backwards until <blah>
  {
    while ((confnum>0) && (!AllowAccess(confnum)))
    {
      confnum--;
    }
  }


  if (Mode!=CONF_REJOIN)
  {
    // ok, check to see if the conf number is valid, if not then
    // ask the user to pick a conf,  and keep doing it until they join a conf

    while ((confnum<1 || confnum>BBSGlobal->Conferences) && N_ND->OnlineStatus==OS_ONLINE)
    {
      CmdLine=FALSE;
      if (FirstTime) DOOR_DisplaySpecialScreen("ConfHead");
      for (loop=1,node = BBSGlobal->ConfList->lh_Head ; node->ln_Succ ; node =node->ln_Succ,loop++)
      {
        if ( ((N_ND->User.CallData.Status=='N') && (AllowAccess(loop)))
            || N_ND->User.CallData.Status!='N')
        {
          sprintf(outstr,ANSI_RESET "%d, %s%s\r\n",loop,AllowAccess(loop) ? ANSI_FG_WHITE : ANSI_FG_RED, node->ln_Name);
          DOOR_WriteText(outstr);
        }
      }
      strcpy(N_ND->CharsAllowed,"0123456789");
      DOOR_WriteText("Pick A Conference > ");
      DOOR_GetLine(GL_EDIT|GL_DISPLAY|GL_USECHARS,'\0',0,0,NULL);
      if (N_ND->CurrentLine[0])
      {
        confnum=atoi(N_ND->CurrentLine);
        if (!AllowAccess(confnum))
        {
          AccessDenied();
          confnum=0;
        }
      }
      else
      {
        if (N_ND->CurrentConf)
        {
          confnum=N_ND->CurrentConf->ConfNum;
        }
      }
      FirstTime=FALSE;

    }
  }
  if ((N_ND->OnlineStatus==OS_ONLINE) && ((confnum != lastconf) || (Mode==CONF_REJOIN)) )
  {
    if (!AllowAccess(confnum))
    {
      AccessDenied();
    }
    else
    {
      if (lastconf!=0) DOOR_DisplaySpecialScreen("ConfLeft");
      sprintf(outstr,ANSI_RESET ANSI_FG_CYAN"Joining Conference %d\r\n",confnum);
      DOOR_WriteText(outstr);
      N_ND->CurrentConf=(struct ConfData *)GetNode(BBSGlobal->ConfList,confnum-1);
      N_ND->User.NormalData.LastConf=confnum;
      N_ND->User.CallData.LastConf=confnum;
      N_ND->MaxDIZLines=N_ND->CurrentConf->MaxDIZLines; //copy this accross
      HBBS_SetAccess();
      HBBS_SetBBSCols();
      DOOR_DisplaySpecialScreen("ConfLogo");
      DOOR_DisplaySpecialScreen("ConfBulletin");
      DOOR_DisplaySpecialScreen("ConfJoined");
    }
  }
  else
  {
    if (confnum==lastconf && CmdLine)
    {
      DOOR_WriteText("You're already in that conference!\r\n");
    }
  }
}

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

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