
/*

  Select Protocol Door (C) 1995 Deluxe Software! - Written By Dominic Clifton

  Functions of door:

  - Check User.CallData.Protocol, if 0 display list of availiable protocols and let
    user select one, if set to 1 or more then:

    - take 1 from the CallData.Protocol value, and return the value as a string
      in N_ND->DoorReturn

  - You must also only display protocol that are availiable for the type of transfer
    selected ( i.e. only show protocols with Allow_UL when type UPLOAD is set
    (see Argv[0])  Bi-Directional protocols MUST have Allow_UL AND Allow_DL set..
  - Check validity of N_ND->DoorReturn (ie, must be lower than amount in
    BBSGlobal->Protocols)


  Todo
  ====

  * Loop or CANCEL if invalid protocol has been selected

  * Make nice and colourfull.

  * Add Config to change colours and or display special or user screen before
    and after selecting protocols.

    (Make all text output configurable ?)

*/

#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>


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

#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 <HBBS/release.h>
char *versionstr="$VER: SelectProtocol "RELEASE_STR;

char versionstr[]="$VER: SelectProtocol 1.0";
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(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);
}

BOOL ProtocolOK(struct ProtocolNode *pnode,char *param)
{
  if ( ((pnode->allow_ul) && (!stricmp("UPLOAD",param)))
       ||
       ((pnode->allow_dl) && (!stricmp("DOWNLOAD",param))) )
  {
    return(TRUE); // Protocol Is OK
  }

  return(FALSE);
}

void DoorMain(int argc,char *argv[])
{
  int loop;
  struct ProtocolNode *pnode;
  char outstr[BIG_STR];
  int number;
  int displayed=0;
  BOOL Done=FALSE;

  DOOR_Return("CANCEL");

  if (number=N_ND->User.CallData.Protocol)
  {
    number--; // default protocol if offset by one.
    pnode=(struct ProtocolNode *)GetNode(BBSGlobal->ProtocolList,number);
    if (ProtocolOK(pnode,argv[2]))
    {
      sprintf(N_ND->DoorReturn,"%d",number);
      return;
    }
    else DOOR_WriteText("Your default protocol is not valid for this type of transfer\r\n"
                        "Please select a different protocol from the list.\r\n");

  }

  // Display All Protocols
  for (loop=0;loop<BBSGlobal->Protocols;loop++)
  {
    pnode=(struct ProtocolNode *)GetNode(BBSGlobal->ProtocolList,loop);

    if (ProtocolOK(pnode,argv[2]))
    {
      displayed++;
      sprintf(outstr,"%-02d) %s\r\n",displayed,pnode->node.ln_Name);
      DOOR_WriteText(outstr);
    }
  }

  if (displayed)
  {
    // Ask For Protocol, or return to select default protocol or first protcol in list
    // if default protocol is not set for the user.

    do
    {
      DOOR_WriteText("\r\nSelect Protocol For ");
      DOOR_WriteText(argv[2]);
      DOOR_WriteText(" >");

      strcpy(N_ND->CharsAllowed,"0123456789");

      DOOR_GetLine(GL_EDIT|GL_DISPLAY|GL_USECHARS|GL_IMMEDIATE,'\0',BBSGlobal->Protocols>9 ? 2 : 1,0,NULL);

      if (N_ND->OnlineStatus=OS_ONLINE)
      {
        if ((N_ND->CurrentLine[0]==0) || (sscanf(N_ND->CurrentLine,"%d",&number)==0))
        {
          // blank line, or no number.
          number=1;
        }


        if (number>=1 && number <=displayed)
        {

          loop=0;
          displayed=0;
          do
          {
            pnode=(struct ProtocolNode *)GetNode(BBSGlobal->ProtocolList,loop);
            if (ProtocolOK(pnode,argv[2]))
            {
              displayed++;
            }
            loop++;
          } while (number!=displayed);

          sprintf(outstr,ANSI_RESET ANSI_FG_CYAN "Selected Protocol "ANSI_FG_WHITE"%d "ANSI_FG_CYAN"- "ANSI_FG_WHITE"%s\r\n",number,pnode->node.ln_Name);
          DOOR_WriteText(outstr);

          sprintf(outstr,"%d",loop-1);
          DOOR_Return(outstr);
          Done=TRUE;
        }
        else
        {
          // number too high or low.

          DOOR_WriteText("Invalid Option!\r\nSelecting protocol 1\r\n");
        }
      }
      else Done=TRUE;
    } while (!Done);
  }
  else DOOR_WriteText("\r\nNo Protocols Availiable For This Type Of Transfer!\r\n\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("SelectProtocol");

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