/***************************************************************************
  FileLab V0.85 by Chris Papademetrious
    Last modified: 02/07/90

    If you find this useful in day-to-day use, a contribution would be
    greatly appreciated. However, if converting text files is all you
    do all day, you have my sympathy...

    Chris Papademetrious
    217 Linda Terrace
    Ephrata, PA  17522

Modifies text files; strips extra spaces, linefeeds, and formfeeds (clear-
screen characters) from pesky PD text files
***************************************************************************/

#include <stdio.h>
#include <intuition/intuition.h>
#include "gadgets.c"

FILE *input, *output, *fopen(); /* pointers to buffered input and output files*/

struct IntuiMessage *message;   /* pointer to IDCMP messages */

ULONG msgclass;             /* IDCMP message class */
USHORT code, gadgetnum;     /* gadget code and number */
struct Message *GetMsg();   /* GetMsg() returns a pointer to a Message */
long total;         /* total file read */

main()
    {
    open_all(); /* open window, libraries */
    for(;;)     /* FOREVER */
        {
        if ((message = (struct IntuiMessage *) GetMsg(window->UserPort)) == NULL)
            {
            Wait(1L << window->UserPort->mp_SigBit);    /* wait if no msg */
            continue;
            }
        msgclass = message->Class;
        code = message->Code;
        gadgetnum = ((struct Gadget *)message->IAddress)->GadgetID;
        ReplyMsg(message);  /* Let Intuition know we got it */
        switch(msgclass)
            {
            case REFRESHWINDOW:
                refreshwindow();    /* homebrew refresh routine */
                continue;

            case CLOSEWINDOW:
                close_all();        /* bye bye */

            case GADGETUP:
                switch(gadgetnum)   /* gadget released, find out which */
                    {
                    case 3:         /* START gadget */
                        convertfiles(inputbuffer, outputbuffer);
                        continue;   /* continue FOREVER loop */
                    }
            }
        }
    close_all();    /* de-allocate all */
    }

convertfiles(inputname, outputname) /* routine to convert files; inputname
                                       outputname are pointers to 80-char
                                       buffers containing file names */
char *inputname, *outputname;

    {
    register int loopcntr, spacecntr=0, lfcntr=2;
    register int curchar, oldchar;          /* REGISTER vars for speed */
    long bar=0;
    BOOL format, indent, clear, abort=FALSE;

    if (
    !(input = (FILE *) fopen(inputname, "r")) ||
    !(output = (FILE *) fopen(outputname, "w")) )
        {               /* oops, couldn't lock files */
        DisplayBeep(NULL);
        if (input) fclose(input);       /* close what I DID have open */
        if (output) fclose(output);
        return;
        }

    format = formatgadget.Flags & SELECTED;
    indent = indentgadget.Flags & SELECTED; /* set conversion flags */
    clear = cleargadget.Flags & SELECTED;
    swapgadgets();  /* enable/disable */

    fseek(input, 0L, 2L);   /* go to end of file... */
    bar = ftell(input);     /* and find length.. */
    rewind(input);          /* and back again! */

    for(;;) /* endless loop */
         {
         if (message = (struct IntuiMessage *) GetMsg(window->UserPort))
                    /* ^^^ get any IntuiMessages  ^^^ */
            {
            msgclass = message->Class;
            code = message->Code;
            gadgetnum = ((struct Gadget *)message->IAddress)->GadgetID;
            ReplyMsg(message);
            switch(msgclass)
                {
                case REFRESHWINDOW: /* simple refresh */
                    refreshwindow();
                    continue;
                case GADGETUP:  /* STOP gadget must have been hit */
                    abort = TRUE;
                    continue;
                }
            }
        for(loopcntr=0;loopcntr<1024;loopcntr++)
            {

        /* ^^^ inside loop, gadgets only checked every 1024 bytes
           to improve inside loop speed */

            oldchar = curchar;
            curchar = fgetc(input); /* update old, read new */
            if (curchar == EOF) break;  /* end of file */
            if ((clear) && (curchar == 12)) curchar = 10;
                /* ^^^ if 0x0C found (CTRL-L) convert to linefeed */
            if ((indent) && (curchar == 9)) curchar = 32;
                /* ^^^ if tab found and indent enabled, convert to space */
            if (format)
                {
                if (curchar == 32)  /* if current char. is space,...  */
                    {               /*                                */
                    spacecntr++;    /* increment space counter...     */
                    continue;       /* and continue w/out writing     */
                    }
                if (curchar == 10)  /* if curent char. is linefeed... */
                    {               /*                                */
                    spacecntr=0;    /* reset space counter to zero... */
                    lfcntr++;       /* and update linefeed counter... */
                    continue;       /* and continue w/out writing     */
                    }
                if (
                ((curchar != 10) && (curchar != 32)) &&
                (( oldchar == 10) || (oldchar == 32)) )
                    {

                /* ^^^ if oldchar isn't space or linefeed, and
                   curchar IS, must be time to write the queued
                   spaces and/or linefeeds! */

                    if (lfcntr < 2) /* not new paragraph */
                        {
                        lfcntr = 0; /* no linefeeds (joins lines) */
                        spacecntr = 1;  /* extra space to seperate */
                        }
                    else
                        {
                        if (indent) spacecntr = 5;  /* indent if set */
                        }
                    if (lfcntr)     for (;lfcntr>0;lfcntr--) putc(10L, output);
                    if (spacecntr)  for (;spacecntr>0;spacecntr--) putc(32L, output);
                    }   /* ^^^ write linefeeds and spaces */
                }
            fputc (curchar, output);    /* put current character to file */
            }
        SetAPen(window->RPort, 3L); /* set current foreground pen */
        RectFill(window->RPort, 25L, 73L, 25 + (512 * ftell(input) / bar), 79L);
                        /* ^^^ draw percentage bar */
        if ((curchar == EOF) || abort) break;   /* abort if EOF */
        }
    fclose(output); /* close */
    fclose(input);  /* files */
    swapgadgets();  /* you're outta here! */
    return;
    }

swapgadgets()   /* swaps DISABLED flag of each gadget */
    {
    RemoveGList(window, &cleargadget, NULL);    /* disconnect gadgets, */
    fileinputgadget.Flags ^= GADGDISABLED;
    fileoutputgadget.Flags ^= GADGDISABLED;
    startgadget.Flags ^= GADGDISABLED;
    stopgadget.Flags ^= GADGDISABLED;           /* make changes, */
    formatgadget.Flags ^= GADGDISABLED;
    indentgadget.Flags ^= GADGDISABLED;
    cleargadget.Flags ^= GADGDISABLED;
    AddGList(window, &cleargadget, -1L, 7, NULL);   /* stick 'em back in, */
    refreshwindow();                            /* and clean up */
    }

refreshwindow()
    {
    SetAPen(window->RPort, 0L); /* set foreground pen to background (0L) */
    RectFill(window->RPort, 2L, 11L, 557L, 82L);    /* clear window */
    RefreshGadgets(&cleargadget, window, NULL);     /* refresh gadgets */
    SetAPen(window->RPort, 2L);                /* set foreground again */
    RectFill(window->RPort, 24L, 72L, 540L, 80L);   /* draw black bar */
    }

open_all()
    {
    if (!(IntuitionBase = (struct IntuitionBase *) OpenLibrary("intuition.library", NULL)))
        {   /* ^^^ library ptr not returned, no library */
        DisplayBeep(NULL);
        close_all();
        }
    if (!(GfxBase = (struct GfxBase *) OpenLibrary("graphics.library", NULL)))
        {   /* ^^^ library ptr not returned, no library */
        DisplayBeep(NULL);
        close_all();
        }
    if (!(window = (struct Window *) OpenWindow(&MainWindow)))
        {   /* ^^^ window ptr not returned, no window */
        DisplayBeep(NULL);
        close_all();
        }
    SetAPen(window->RPort, 2L); /* draw black bar */
    RectFill(window->RPort, 24L, 72L, 536L, 80L);
    }

close_all()
    {
    if (window) CloseWindow(window);    /* close window */
    if (GfxBase) CloseLibrary(GfxBase); /* close graphics.library */
    if (IntuitionBase) CloseLibrary(IntuitionBase); /* close intuition */
    exit(NULL); /* exit program */
    }

/* Enjoy! Feel free to hack this code to pieces any way you wish. Please
 don't sell this or include it in any non-public domain product without
 notifying me, or include it in any public domain product being sold for
 a cost exceeding (US)$5. */