#include <stdlib.h>
#include <string.h>
#include <dos.h>
#include <exec/types.h>
#include <exec/io.h>
#include <exec/memory.h>
#include <devices/serial.h>
#include <devices/timer.h>

#include <dlg/dlg.h>
#include <dlg/file.h>
#include <dlg/user.h>

#include "xproto.h"

#include <link/io.h>
#include <link/lang.h>

#include <proto/exec.h>
#include <proto/dos.h>
#include <proto/dlg.h>

#include <pragmas/dlg.h>

#include <private/Version.h>
#define  ObjRev "1"
const UBYTE version[]="\0$VER: XPRTransfer " BUILDVER "." ObjRev " ©" COPYRIGHT " by Digerati Dreams "__AMIGADATE__;

BOOL  xpr_setup(struct XPR_IO *);
BOOL  OpenTimer(void);
void  CloseTimer(void);
void  CleanUp(char *);
void  Usage(char *);
void _CXBRK(void);

extern struct SearchCookie *sc;
extern BOOL                 abortflag;

BPTR                sout;
char              **SA;
struct USER_DATA    UserDat;
struct Ram_File     RStruct;

struct timerequest *Timer      = NULL;
struct MsgPort     *Timer_Port = NULL;
struct MsgPort     *ReadBak    = NULL;
struct MsgPort     *WriteBak   = NULL;

struct Library     *DLGBase       = NULL;
struct Library     *XProtocolBase = NULL;

struct DLGSerInfo  *dsi = NULL;
struct XPR_IO      *io  = NULL;

char  mydevice[4]        = "";
char  tempdownloads[80]  = "";
char  destfile     [256] = "";
char *filename  =  NULL;
char *batchfile =  NULL;
char *libname   = "xprzmodem.library";

BOOL SEROPEN = FALSE, batchmode=FALSE, quiet=FALSE;
long signals;

char *setupstring = "TN,OR,B16,AN,DN,KY,SN,RN";
char  tmode       = 'S';
char  protocol    = 'Z';


main(int argc, char **argv)

{char *s;

 sout = Output();
 DLGBase = OpenLibrary(DLGNAME, DLGVERSION);
 if (!DLGBase)                   CleanUp("Unable to open dlg.library");

 GetDevName(mydevice);
 if (!(SA = getlang(mydevice)))  CleanUp("Can't read Language file");

 while(--argc>0)
      {s = *++argv;

       if (*s++ == '-')
          {while(*s)
                {switch(*s++)
                       {case 's':
                        case 'S':  tmode = 'S';
                                   break;

                        case 'r':
                        case 'R':  tmode = 'R';
                                   break;

                        case 'b':
                        case 'B':  batchmode = TRUE;
                                   break;

                        case 'q':
                        case 'Q':  quiet = TRUE;
                                   break;

                        case 'p':
                        case 'P':  if (!--argc) break;
                                   protocol=*(*++argv);
                                   break;

                        case 'l':
                        case 'L':  if (!--argc) break;
                                   libname=*++argv;
                                   break;

                        case 'c':
                        case 'C':  if (!--argc) break;
                                   setupstring=*++argv;
                                   break;

                        case 'f':
                        case 'F':  if (!--argc) break;
                                   filename=*++argv;
                                   break;
                        default:   Usage(SA[3354]);
                       }
                }
          }
      }
 if (tmode=='S' && !filename)                 Usage(SA[3355]);
 if (!ReadUser(&RStruct, &UserDat, mydevice))  CleanUp(SA[3356]);

 ASPrintf(NULL, tempdownloads, "FILE:TempDownloads/%s", RStruct.Name);
 UnderScore(tempdownloads);

 if (!(io = malloc(sizeof(struct XPR_IO))))
       CleanUp(SA[3357]);

 if (!OpenTimer())
      CleanUp(SA[3358]);

 if ((dsi = DLGGetSer(mydevice, protocol))==NULL)
      CleanUp(SA[3359]);
 SEROPEN = TRUE;

 XProtocolBase = OpenLibrary(libname,0);
 if (XProtocolBase == NULL)
     CleanUp(SA[3360]);

 xpr_setup(io);
 io->xpr_filename = setupstring;

 if (!XProtocolSetup(io))
     CleanUp(SA[3361]);

 if (batchmode)  batchfile = filename;

 if (filename && (!batchmode))
     io->xpr_filename = filename;
   else
     io->xpr_filename = NULL;

 if (tmode=='S')
    {if (!XProtocolSend(io))
        {XProtocolCleanup(io);
         CleanUp(SA[3362]);
        }
    }
  else
    if (!XProtocolReceive(io))
       {XProtocolCleanup(io);
        CleanUp(SA[3363]);
       }

 XProtocolCleanup(io);
 CleanUp(NULL);
}


BOOL OpenTimer(void)

{if (Timer_Port = CreateMsgPort())
    {if ((Timer=(struct timerequest *)CreateExtIO(Timer_Port,sizeof (*Timer))))
        {if (!(OpenDevice(TIMERNAME, UNIT_VBLANK,(struct IORequest *)Timer, 0)))
            {Timer->tr_node.io_Command = TR_ADDREQUEST;
             Timer->tr_node.io_Flags   = NULL;
             Timer->tr_node.io_Error   = NULL;
             return(TRUE);
            }
          else
             Timer->tr_node.io_Device = NULL;
        }
    }

 return(FALSE);
}


void CloseTimer(void)

{if (Timer)
    {if (Timer->tr_node.io_Device) CloseDevice((struct IORequest *)Timer);
         DeleteExtIO((struct IORequest *)Timer);
    }

 if (Timer_Port)
     DeleteMsgPort(Timer_Port);
}


void CleanUp(char *s)

{if (sc)       SearchEnd(sc);
 if (SEROPEN)  DLGReleaseSer(dsi);

 CloseTimer();
 if (tempdownloads[0])  DelDir(tempdownloads, NULL);
 if (XProtocolBase)     CloseLibrary(XProtocolBase);
 if (DLGBase)           CloseLibrary(DLGBase);

 if (s)
    {Write(sout, "\n Error: ", 9);
     Write(sout,  s, strlen(s));
     Write(sout, "\n\n", 2);
    }

 exit(s?5:0);
}


void Usage(char *string)

{AFPrintf(NULL, sout, SA[3364], string);
 AFPrintf(NULL, sout, SA[3365]);
 AFPrintf(NULL, sout, SA[3366]);
 AFPrintf(NULL, sout, SA[3367]);
 AFPrintf(NULL, sout, SA[3368]);
 AFPrintf(NULL, sout, SA[3369]);
 AFPrintf(NULL, sout, SA[3370]);
 AFPrintf(NULL, sout, SA[3371]);
 AFPrintf(NULL, sout, SA[3372]);
 AFPrintf(NULL, sout, SA[3373]);
 AFPrintf(NULL, sout, SA[3374]);
 AFPrintf(NULL, sout, SA[3375]);

 CleanUp(NULL);
}


void _CXBRK(void)

{abortflag = TRUE;
}
