/****************************************************************************
 *                                                                          *
 *  Program     :   ADFormat                                                *
 *  Revision    :   1.0                                                     *
 *  Version     :   $VER: ADFormat.c                                        *
 *  Copyright   :   © 1993 DIgital DImensions                               *
 *  Author      :   Hans-Jörg Frieden, of DIgital DImensions                *
 *                                                                          *
 *  Revision History                                                        *
 *  Date        Revision    Comment                                         *
 *  ----------------------------------------------------------------------  *
 *  15-Aug-93   1.0         Created file. First working version             *
 *                                                                          *
 ****************************************************************************/

#include "global.h"

static char *version = "$VER: ADFormat 1.0";

static char *BackLinkChars = " @{\" Back to Autodoc-it \" Link \"Autodoc-it/main\"}\n"
                             "---------------------------------------------------------------------\n";

char in[256],out[256];
int col;
BOOL verbose;
BOOL backlink;
BOOL NormConv;

#define TEMPLATE (APTR)"FROM/A,TO/K,COL/K/N,VERBOSE/S,BACKLINK/S"
#define T_FROM      0
#define T_TO        1
#define T_COL       2
#define T_VERBOSE   3
#define T_BACKLINK  4
#define T_COUNT     5
LONG opts[T_COUNT];

#define GETNEXT c=FGetC(fhi); x=c; Write(fho,&x,1);

struct ADEntry { 
    struct ADEntry *next;
    char Title[80];
    UWORD TLeng;
    char Link[80];
    UWORD LLeng;
};

struct ADEntry root,*list;

struct ADEntry *MakeEntry(char *title, char *link) {
    struct ADEntry *ret;
    ret=(struct ADEntry *)AllocVec(sizeof(struct ADEntry),MEMF_ANY);
    if (ret) {
        ret->next=NULL;
        strncpy(ret->Title,title,80);
        ret->TLeng=strlen(title);
        strncpy(ret->Link,link,80);
        ret->LLeng=strlen(link);
        return ret;
    } else return ret;
}

BOOL BuildList(BPTR fh) {
    ULONG c;
    char title[80]; char link[80];
    int t,l;
    struct ADEntry *ad;
    list=&root; root.next=NULL;
    do {
        c=0;
        do {
            while (c!='@') c=FGetC(fh);
            c=FGetC(fh);
            if (c=='e' || c=='E') {
                c=FGetC(fh);
                if (c=='n' || c=='N') {
                    c=FGetC(fh);
                    if (c=='d' || c=='D') {
                        c=FGetC(fh);
                        if (c=='n' || c=='N') {
                            c=FGetC(fh);
                            if (c=='o' || c=='O') {
                                c=FGetC(fh);
                                if (c=='d' || c=='D') {
                                    c=FGetC(fh);
                                    if (c=='e' || c=='E') {
                                        return TRUE;
                                    }
                                }
                            }
                        }
                    }
                }
            } else {
                while (c!='"') c=FGetC(fh);
                t=0;
                c=FGetC(fh);
                while (c!='"') {
                    title[t++]=(char)c;
                    c=FGetC(fh);
                }
                title[t]=0;
                c=FGetC(fh); c=FGetC(fh);
                while (c!='"') c=FGetC(fh);
                l=0;
                c=FGetC(fh);
                while (c!='"') {
                    link[l++]=(char)c;
                    c=FGetC(fh);
                }
                link[l]=0;
                ad=MakeEntry(title,link);
                if (!ad) return FALSE;
                list->next=ad;
                list=list->next;
            }
        } while (c!=-1);
    } while (c!=-1);
    if (c==-1) return FALSE;
    else return TRUE;
}

BOOL SeekMainNode(BPTR fhi, BPTR fho) {
    ULONG c;
    char x;
    BOOL ret=FALSE;
    do {
        GETNEXT
        if (c=='@') {
            GETNEXT 
            if (c=='N' || c=='n') {
                GETNEXT
                if (c=='O' || c=='o') {
                    GETNEXT
                    if (c=='D' || c=='d') {
                        GETNEXT
                        if (c=='E' || c=='e') {
                            GETNEXT
                            while (c==' ') GETNEXT
                            if (c=='M' || c=='m') {
                                GETNEXT
                                if (c=='A' || c=='a') {
                                    GETNEXT
                                    if (c=='I' || c=='i') {
                                        GETNEXT
                                        if (c=='N' || c=='n') {
                                            ret=TRUE;
                                            while (c!='\n') {GETNEXT}
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
        if (c==-1) {
            ret=FALSE;
            break;
        }
    } while (ret!=TRUE);
    return ret;
}

void CopyRest(BPTR fhi, BPTR fho) {
    ULONG c=0;
    while (c!=-1) {
        c=FGetC(fhi);
        FPutC(fho,(char)c);
    }
}

void DoConvert(char *in, char *out) {
    BPTR fhi,fho;
    BOOL bl;
    struct ADEntry *max;
    struct ADEntry *ad;
    char buffer[256];
    ULONG ColWidth;
    ULONG colnr;
    fhi=Open((APTR)in,MODE_OLDFILE);
    if (fhi) {
        fho=Open((APTR)out,MODE_NEWFILE);
        if (fho) {
            bl=SeekMainNode(fhi,fho);
            if (bl) {
                if (backlink) Write(fho,BackLinkChars,strlen(BackLinkChars));
                bl=BuildList(fhi);
                if (bl) {
                    ad=root.next;
                    root.TLeng=0;
                    max=&root;
                    while (ad->next) {
                        if ( (ad->TLeng) > (max->TLeng) ) max=ad;
                        ad=ad->next;
                    }
                    ColWidth=max->TLeng+1;
                    if (verbose==TRUE) printf("Longest: %s\n",max->Title);
                    ad=root.next;
                    colnr=0;
                    while (ad->next) {
                        sprintf(buffer," @{\"%-*s\" Link \"%s\"}",ColWidth,ad->Title,ad->Link);
                        FWrite(fho,buffer,strlen(buffer),1);
                        colnr++;
                        if (colnr==col) {
                            FPutC(fho,'\n');
                            colnr=0;
                        }
                        ad=ad->next;
                    }
                    FPutC(fho,'\n');
                    FWrite(fho,(APTR)"@ENDNODE\n",8,1);
                    CopyRest(fhi,fho);
                } else printf("Error reading %s\n",in);
            } else printf("Cannot locate MAIN node\n");
            Close(fho);
        } else printf("Cannot open Output file\n");
        Close(fhi);
    } else printf("File %s not found\n",in);
}

void CopyFile(char *to, char *from) {
    BPTR fhi,fho;
    ULONG c=0;
    fhi=Open((APTR)to,MODE_OLDFILE);
    if (verbose) printf("Copying: %s -> %s\n",to,from);
    if (fhi) {
        fho=Open((APTR)from,MODE_NEWFILE);
        if (fho) {
            while (c!=-1) {
                c=FGetC(fhi);
                FPutC(fho,(char)c);
            }
            Close(fho);
        } else printf("Cannot overwrite/create %s\n",to);
        Close(fhi);
    } else printf("File %s not found\n",from);
}

void main(void) {
    struct RDArgs *rda;
    rda=ReadArgs(TEMPLATE,opts,NULL);
    NormConv=TRUE;
    if (rda) {
        if (opts[T_COL]) col=*(LONG *)(opts[T_COL]); else col=1;
        strncpy(in,(char *)opts[T_FROM],256);
        if (opts[T_VERBOSE]) verbose=TRUE; else verbose=FALSE;
        if (opts[T_BACKLINK]) backlink=TRUE; else backlink=FALSE;
        if (opts[T_TO]) strncpy(out,(char *)opts[T_TO],256);
        else {
            strcpy(out,"adfXXX.XXX");
            mktemp(out);
            NormConv=FALSE;
        }
        FreeArgs(rda);
        if (strcmp(in,out)==0) {
            strcpy(out,"adfXXX.XXX");
            mktemp(out);
            NormConv=FALSE;
        }
        DoConvert(in,out);
        if (NormConv==FALSE) {
            CopyFile(out,in);
            DeleteFile((APTR)out);
        }
    } else {
        PrintFault(IoErr(),NULL);
        exit(IoErr());
    }
    exit(0);
}
