/* **** 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 <libraries/reqtools.h>
#include <clib/reqtools_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 <HBBS/release.h>
char *versionstr="$VER: Download "RELEASE_STR;


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


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

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

long __stack=16*1024; // increase 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;

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

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

BOOL IsProtocolBiDirectional( struct ProtocolNode *pnode )
{
//  return ((BOOL)( ( (pnode->allow_ul) && (pnode->allow_dl) ) ? TRUE : FALSE ) );
  return ((BOOL)(pnode->protocoltype==PTYPE_BIDIRECTIONAL ? TRUE : FALSE));
}


void DoorMain( void )
{
  struct ProtocolNode *protocolnode;
  int protocolnum;
  int loop;
  struct rtFileRequester *filereq;
  char filename[BIG_STR],dirname[BIG_STR],outstr[BIG_STR];
  BOOL ok,ClearTags,FileCopied;
  struct TaggedFile *Tag,*TTag;

  DOOR_DisplaySpecialScreen("ConfDownLoad");
  DOOR_WriteText(ANSI_RESET);

  for(loop=2;loop<gargc;loop++) // if there are any parameters then display them
  {
    DOOR_UserDoor("A",gargv[loop]);
  }

  DOOR_SystemDoor("AskDLFiles","DOWNLOADDOOR");

  if (stricmp(N_ND->DoorReturn,"CANCEL")==0)
  {
    DOOR_Continue(FALSE);
  }
  else
  {
    if (N_ND->OnlineStatus==OS_ONLINE)
    {
      if (N_ND->TaggedFiles>0)
      {
        if (N_ND->LoginType==LOGIN_REMOTE)
        {
          DOOR_SystemDoor("SELECT_PROTOCOL","DOWNLOAD");
          if (N_ND->OnlineStatus==OS_ONLINE)
          {
            if (stricmp(N_ND->DoorReturn,"CANCEL")==0)
            {
              DOOR_Continue(FALSE);
            }
            else
            {
              if (sscanf(N_ND->DoorReturn,"%d",&protocolnum)>=0)
              {
                protocolnode=(struct ProtocolNode *)GetNode(BBSGlobal->ProtocolList,protocolnum);

                sprintf(outstr,"%s %d WAREZ CHECKFILES ",IsProtocolBiDirectional(protocolnode) ? "BOTH" : "DOWNLOAD",protocolnum);

                if (IsProtocolBiDirectional(protocolnode))
                {
                  DOOR_SystemDoor("SHOWPARTUPLOADS","DOWNLOADDOOR");
                }

                DOOR_SystemDoor("TRANSFER",outstr);

                // if the protocol is bi directional then the user might have uploaded
                // some files, if the TRANSFER door returns NOBATCH then we have to kick off the
                // checkfile door outselves.

                if ((IsProtocolBiDirectional(protocolnode)) && (!stricmp(N_ND->DoorReturn,"NOBATCH")))
                {
                  DOOR_SystemDoor("CHECKFILES","ALL");
                }
              }
            }
          }
        }
        else
        {
          if (ReqToolsBase = (struct ReqToolsBase *) OpenLibrary (REQTOOLSNAME, REQTOOLSVERSION))
          {
            if (filereq = (struct rtFileRequester *)rtAllocRequestA(RT_FILEREQ,NULL))
            {
              rtChangeReqAttr(filereq,RTFI_Dir,"HBBS:",TAG_DONE);
              filename[0]=0;
              ok=FALSE;
              ClearTags=FALSE;

              if (rtFileRequest(filereq,filename,"Destination Directory",RT_PubScrName,N_ND->ConScreenName,
                                RTFI_Flags,FREQF_NOFILES,TAG_END))
              {
                strcpy(dirname,filereq->Dir);

                if (dirname[0]) // have we got a dirname ?
                {
                  ok=TRUE;

                  AddPart(dirname,filename,BIG_STR);  // though filename is normally blank.. but this adds a / anyway..

                  sprintf(outstr,ANSI_RESET ANSI_FG_YELLOW "Copying tagged files to " ANSI_FG_BLUE ": "ANSI_FG_WHITE" %s \r\n",dirname);
                  DOOR_WriteText(outstr);

                  if (DOOR_ContinuePrompt("Clear tags after copy ",DEFAULT_YES|DCP_ADDYN))
                  {
                    ClearTags=TRUE;
                  }

                  for ( Tag=(struct TaggedFile *)N_ND->TaggedFileList->lh_Head;
                        Tag->node.ln_Succ;
                        Tag=(struct TaggedFile *)Tag->node.ln_Succ)
                  {
                    // set a flag

                    FileCopied=FALSE;

                    // build the destination name.

                    strcpy(filename,dirname);
                    strcat(filename,FilePart(Tag->node.ln_Name));

                    // tell the user what we're gonna do

                    sprintf(outstr,ANSI_FG_YELLOW "Copying "ANSI_FG_PURPLE"%s"ANSI_FG_YELLOW" to "ANSI_FG_PURPLE"%s"ANSI_FG_YELLOW"...",Tag->node.ln_Name,filename);
                    DOOR_WriteText(outstr);

                    if (PathOK(Tag->node.ln_Name))
                    {
                      // copy the file and report status
                      if (HBBS_CopyFile(Tag->node.ln_Name,filename,0))
                      {
                        FileCopied=TRUE;
                        DOOR_WriteText(ANSI_FG_WHITE "OK\r\n");

                        if (ClearTags)
                        {
                          TTag=(struct TaggedFile*)Tag->node.ln_Pred; // store pointer to previous tag

                          // free the tag and remove it from the list.

                          FreeStr(Tag->node.ln_Name);
                          Remove((struct Node*)Tag);
                          FreeVec(Tag);
                          N_ND->TaggedFiles--;

                          // set the for/next loop's counter tag to point to the previous tag, so
                          // that when it skips forwards it'll miss the one we just free()'d.
                          Tag = TTag;
                        }
                      }
                    }
                    if (!FileCopied)
                    {
                      DOOR_WriteText(ANSI_FG_RED "Failed\r\n");
                    }
                  }
                  DOOR_WriteText(ANSI_RESET);
                }

              }
              if (!ok)
              {
                DOOR_WriteText(ANSI_FG_YELLOW "Cancelled!\r\n");
              }

              rtFreeRequest(filereq);
            }
            CloseLibrary ((struct Library *)ReqToolsBase);
          }
        }
      }
      else
      {

        DOOR_WriteText("No tagged files!\r\n");
        DOOR_Continue(FALSE);
      }
    }
  }
}

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("Download");

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

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