/* ppguide.c -- views PowerPacked .guide files */
/* Copyright ©1993 William E. Sorensen.  All rights reserved. */

#define ONESECOND 50UL
#define WINDEF "CON:0/0/640/100/ppguide"

#include <functions.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <libraries/dos.h>
#include <libraries/amigaguide.h>
#include <clib/amigaguide_protos.h>
#include <pragmas/amigaguide_pragmas.h>
#include <libraries/powerpacker.h>
#include <libraries/ppbase.h>
#include <workbench/startup.h>

VOID getprogarg(int,char **);
VOID cleanexit(LONG);

struct PPBase *PPBase=NULL;
struct Library *AmigaGuideBase=NULL;
struct NewAmigaGuide nag={NULL};

char *progarg=NULL;  /* will point to a copy of the program's argument */
ULONG pperror,len;
UBYTE *buffer=NULL;
BPTR tempfile=NULL;
BOOL runfromCLI,tempfileexists=FALSE;
AMIGAGUIDECONTEXT aghandle=NULL;

char tempfilename[]="T:ppguide.tmp";  /* hopefully, this is in RAM: */
char topenerr[]="Unable to open temporary file";
char twriteerr[]="Unable to write to temporary file";
char tshowerr[]="Unable to show temporary file";

char VersionString[]="$VER: ppguide 1.0 (14.5.93)";

char usagestr[]="Usage:  ppguide <file>\n";

extern struct Library *DOSBase;
extern struct WBStartup *WBenchMsg;  /* SAS users may have to use argv */
extern long Enable_Abort;  /* Manx (for Ctrl-C control) */

VOID main(int argc, char *argv[])
{
    Enable_Abort=0L;  /* turn off Manx's Ctrl-C handling */

    getprogarg(argc,argv);  /* get the program's argument */

    /* if it was a question mark, print an informational message */
    if(!strcmp(progarg,"?")){
        printf("%s\nCopyright ©1993 William E. Sorensen.  All rights "
               "reserved.\n%s",VersionString+6,usagestr);
        cleanexit(RETURN_OK);
    }

	if (!(AmigaGuideBase=OpenLibrary((UBYTE *)"amigaguide.library",33L))){
	    printf("You need amigaguide.library V33+!\n");
	    cleanexit(RETURN_FAIL);
	}

    if(!(PPBase=(struct PPBase *)OpenLibrary((UBYTE *)"powerpacker.library",33L))){
        printf("You need powerpacker.library V33+!\n");
        cleanexit(RETURN_FAIL);
    }

    if(pperror=ppLoadData(progarg,DECR_POINTER,MEMF_ANY,&buffer,&len,NULL)){
        printf("Load error: %s\n",ppErrorMessage(pperror));
        cleanexit(RETURN_ERROR);
    }

    if(!(tempfile=Open((UBYTE *)tempfilename,MODE_NEWFILE))){
        /* PrintFault() requires V36+ and writes to stderr, not stdout */
        if(((DOSBase->lib_Version)>=36) && runfromCLI)
            PrintFault(IoErr(),(UBYTE *)topenerr);
        else
            printf("%s\n",topenerr);
        cleanexit(RETURN_ERROR);
    }
    tempfileexists=TRUE;
    if(len!=Write(tempfile,buffer,len)){
        if(((DOSBase->lib_Version)>=36) && runfromCLI)
            PrintFault(IoErr(),(UBYTE *)twriteerr);
        else
            printf("%s\n",twriteerr);
        Close(tempfile);
        cleanexit(RETURN_ERROR);
    }
    Close(tempfile);  /* we have to do this now, not in cleanexit() */

    if(buffer){
        /* get some memory back (we might need it!) */
        FreeMem(buffer,len);
        buffer=NULL;  /* so we don't free it twice */
    }

    nag.nag_Name=(STRPTR)tempfilename;

    /* BaseName is barely documented, but is REQUIRED to avoid an
       Enforcer hit!  (Looks like YOUR bug, CBM!) */
    nag.nag_BaseName=(STRPTR)"ppguide";

    /* OpenAmigaGuide() will not return until user closes all windows. */
    if (!(aghandle=OpenAmigaGuide(&nag,NULL))){
        if(((DOSBase->lib_Version)>=36) && runfromCLI)
            PrintFault(IoErr(),(UBYTE *)tshowerr);
        else
            printf("%s\n",tshowerr);
        cleanexit(RETURN_ERROR);
    }
    CloseAmigaGuide(aghandle);

    cleanexit(RETURN_OK);
}

VOID getprogarg(int mainargc,char **mainargv)
/* parameters should be argc and argv from main() */
/* sets up output for Workbench or CLI; sets global variable
   progarg to point to program's single argument (and exits with
   an appropriate error message if the number of arguments is !=1) */
{
    struct WBArg *wbarg;
    char *tempargptr;

    if(mainargc==0){
        /* program was started from Workbench */
        /* open a CON window for output (and change stdout to this) */
        if(!freopen(WINDEF,"w+",stdout)){
            runfromCLI=TRUE;  /* so cleanexit doesn't wait */
            cleanexit(RETURN_ERROR);
        }
        runfromCLI=FALSE;
        if(WBenchMsg->sm_NumArgs!=2L){
            printf("You must select exactly one project icon!\n");
            cleanexit(RETURN_WARN);
        }
        wbarg=WBenchMsg->sm_ArgList+1;  /* 2nd argument is name of project */
        /* CD to wbarg's directory, if there is one */
        if((wbarg->wa_Lock)&&(*wbarg->wa_Name))
            CurrentDir(wbarg->wa_Lock);
        tempargptr=wbarg->wa_Name;
    }
    else{
        /* program was started from CLI */
        runfromCLI=TRUE;
        if(mainargc!=2){
            printf("%s",usagestr);
            cleanexit(RETURN_WARN);
        }
        tempargptr=mainargv[1];
    }

    /* allocate space for the argument, then copy it to there */
    if(!(progarg=(char *)malloc(strlen(tempargptr)+1))){
        printf("Unable to allocate memory!\n");
        cleanexit(RETURN_ERROR);
    }
    strcpy(progarg,tempargptr);
}

VOID cleanexit(LONG rc)
{
    if(tempfileexists)
        DeleteFile((UBYTE *)tempfilename);  /* don't care if it fails */

    /* ppLoadData alloc'd mem; we don't FreeMem unless ppLoadData worked */
    if((!pperror) && buffer)
        FreeMem(buffer,len);

    if(PPBase)
        CloseLibrary((struct Library *)PPBase);

    if(AmigaGuideBase)
        CloseLibrary(AmigaGuideBase);

    if(progarg)
        free((void *)progarg);  /* deallocate memory for string */

    if(!runfromCLI)
        Delay(ONESECOND);  /* when exit() closes stdout, window closes */

    exit(rc);
}
