/*
   Await Connect Door for HBBS (C) 1995 Hydra/LSD

*/

#include <exec/types.h>
#include <exec/memory.h>

#include <dos/dos.h>          // JUST so we can call SetProgramName()
#include <clib/dos_protos.h>

#include <clib/exec_protos.h>
#include <clib/alib_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/release.h>
#include <HBBS/ANSI_Codes.h>
#include <HBBS/Defines.h>
#include <HBBS/types.h>
#include <HBBS/structures.h>

#include <HBBS/Hbbscommon_protos.h>
#ifdef __SASC
#include <HBBS/hbbscommon_pragmas_sas.h>
#else
#include <HBBS/hbbscommon_pragmas_stc.h>
#endif

#include <HBBS/Hbbsnode_protos.h>
#ifdef __SASC
#include <HBBS/Hbbsnode_pragmas_sas.h>
#else
#include <HBBS/Hbbsnode_pragmas_stc.h>
#endif
char *versionstr="$VER: AwaitConnect "RELEASE_STR;

extern struct Library *DOSBase;
extern struct Library *SysBase;
struct Library *HBBSCommonBase=NULL;
struct Library *HBBSNodeBase=NULL;

struct BBSGlobalData *BBSGlobal=NULL;
struct NodeData *N_ND=NULL;
int N_NodeNum=-1;
UBYTE *str_CRLF="\n\r\0";

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

V_BOOL CheckModemConnectStr( void )
{
  V_BOOL retval=FALSE;
  struct Node *nd;
  short tmpval1,tmpval2;

  for (nd = N_ND->NodeDevice.RelaxedConnectStr->lh_Head ; nd->ln_Succ ; nd = nd->ln_Succ)
  {
    if (nd->ln_Name)
    {
      if (iposition(nd->ln_Name,N_ND->CurrentLine)>=0)
      {
        retval=TRUE;
        // ok, get the baud rate from the connect string!
        tmpval1=iposition(" ",N_ND->CurrentLine);
        tmpval2=iposition("/",N_ND->CurrentLine)-1; // miss out the "/"
        if (tmpval1 >= 0)
        {
          tmpval1++; // miss out the " "
          if (tmpval2 <0)
          {
            tmpval2=strlen(N_ND->CurrentLine)-1;
          }
          if (tmpval2>tmpval1)
          {
            strftcpy(N_ND->ConnectBaud,N_ND->CurrentLine,tmpval1,tmpval2);
          }
        }
        else // can't determine connect speed, so set to 33600 so doors don't get confused by a blank string!
        {
          strcpy(N_ND->ConnectBaud,"33600");
       }
      }
    }
  }
  return(retval);
}

void CheckModemIncomingStr( void )
{
  if (N_ND->NodeDevice.Incoming!=NULL && iposition(N_ND->NodeDevice.Incoming,N_ND->CurrentLine)>=0)
  {
    DOOR_SysopText("Incoming Call...\r\n");
  }
}

void DisplayAwaitScreen( void )
{
  if (!DOOR_DisplaySpecialScreen("Await")) // Display Await Screen..
  {
    DOOR_SysopText(ANSI_RESET ANSI_FG_CYAN
                   ANSI_FG_PURPLE "  [" ANSI_FG_WHITE "F1" ANSI_FG_PURPLE "] " ANSI_FG_WHITE " - " ANSI_FG_GREEN "Local Login\n\r"
                   ANSI_FG_PURPLE "  [" ANSI_FG_WHITE "F2" ANSI_FG_PURPLE "] " ANSI_FG_WHITE " - " ANSI_FG_GREEN "Initialise Modem\n\r"
                   ANSI_FG_PURPLE "  [" ANSI_FG_WHITE "F3" ANSI_FG_PURPLE "] " ANSI_FG_WHITE " - " ANSI_FG_GREEN "Answer Modem Now\n\r"
                   ANSI_FG_PURPLE "  [" ANSI_FG_WHITE "F4" ANSI_FG_PURPLE "] " ANSI_FG_WHITE " - " ANSI_FG_GREEN "Display Await Screen ANSI\n\r"
                   ANSI_FG_PURPLE "  [" ANSI_FG_WHITE "F5" ANSI_FG_PURPLE "] " ANSI_FG_WHITE " - " ANSI_FG_GREEN "Toggle modem Debug\n\r"
                   ANSI_FG_PURPLE "  [" ANSI_FG_WHITE "F6" ANSI_FG_PURPLE "] " ANSI_FG_WHITE " - " ANSI_FG_GREEN "Account Editor\n\r"
                   ANSI_FG_PURPLE "  [" ANSI_FG_WHITE "F7" ANSI_FG_PURPLE "] " ANSI_FG_WHITE " - " ANSI_FG_GREEN "Close Watch Window/Screen\n\r"
                   ANSI_FG_PURPLE "  [" ANSI_FG_WHITE "F8" ANSI_FG_PURPLE "] " ANSI_FG_WHITE " - " ANSI_FG_GREEN "Toggle Watch between Screen or Window\n\r"
                   ANSI_FG_PURPLE "  [" ANSI_FG_WHITE "F9" ANSI_FG_PURPLE "] " ANSI_FG_WHITE " - " ANSI_FG_GREEN "Terminal Door\n\r"
                   ANSI_FG_PURPLE "  [" ANSI_FG_WHITE "F10" ANSI_FG_PURPLE "]" ANSI_FG_WHITE " - " ANSI_FG_GREEN "Shutdown This Node\n\r\r\n"
                   ANSI_FG_PURPLE "  [" ANSI_FG_WHITE "SHIFT + F9" ANSI_FG_PURPLE "] " ANSI_FG_WHITE " - " ANSI_FG_GREEN "Initialise Call\n\r"
                   "Awaiting Connect ....\r\n");
  }
}


void DoorMain( void )
{
  ULONG getlinestatus;
  char outstr[1024];
  
  
  DisplayAwaitScreen();
  do
  {
    N_ND->LoginType=LOGIN_NONE;

    getlinestatus=DOOR_GetLine(GL_NOINACTIVITY,'\0',0,0,NULL);
    
    if (N_ND->CurrentLine[0]) // skip blank lines
    {
      DOOR_SysopText(N_ND->CurrentLine);
      DOOR_SysopText(str_CRLF);
    }
    
    switch (getlinestatus)
    {
      case IN_LOGIN:
        N_ND->LoginType=LOGIN_LOCAL;
        break;
      case IN_IMMEDIATE:
        if (N_ND->NodeSettings.UseDevice)
        {
          DOOR_WriteSerText(N_ND->NodeDevice.ImmediateAnswer);
          DOOR_WriteSerText("\n\r");
        }
        break;
      case IN_TERMINAL:
        DOOR_SysopText("Terminal door is not implemented yet!\r\n");
        break;
      case IN_GOTLINE:
        if (!N_ND->NodeDevice.NullModemCable)
        {
          CheckModemIncomingStr();
          if (CheckModemConnectStr()) N_ND->LoginType=LOGIN_REMOTE;
        }
        else
        {
          DOOR_WriteSerText("CONNECT\r\n");
          strcpy(N_ND->ConnectBaud,"LOCAL");
          N_ND->LoginType=LOGIN_REMOTE;
        }
        break;
      case IN_SHUTDOWN:
        N_ND->RequestShutdown=TRUE;
        break;
      case IN_DISPLAYAWAIT:
        DisplayAwaitScreen();
        break;
      case IN_DIALOUT:
        if (N_ND->NodeSettings.UseDevice)
        { 
          sprintf(outstr,"%sEnter number to dial %s%sEnter=Cancel%s%s",
            N_ND->BBSCols->MenuTextANSI,
            N_ND->BBSCols->MenuOpenBracket, 
            N_ND->BBSCols->MenuDefaultOptANSI, 
            N_ND->BBSCols->MenuCloseBracket,
            N_ND->BBSCols->MenuPromptANSI);
          
          DOOR_SysopText(outstr);
          N_ND->LoginType=LOGIN_LOCAL;
          if (IN_GOTLINE==DOOR_GetLine(GL_NOINACTIVITY|GL_SYSOP|GL_EDIT|GL_DISPLAY,'\0',0,0,NULL))
          {
            if (N_ND->CurrentLine[0])
            {
              DOOR_WriteSerText("ATDT");
              DOOR_WriteSerText(N_ND->CurrentLine);
              DOOR_WriteSerText("\r\n");
            }
          }
          N_ND->LoginType=LOGIN_NONE;
        }
        break;

    }
  } while (N_ND->RequestShutdown==FALSE && N_ND->LoginType==LOGIN_NONE);
}

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

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