/************************************************************************/
/*    Copyright (C) 2004  Michael C. Shultz               */
/*                                    */
/* This program is free software; you can redistribute it and/or modify */
/* it under the terms of the GNU General Public License as published by */
/* the Free Software Foundation; either version 2 of the License, or (at*/
/* your option) any later version.                    */
/*                                    */
/* This program is distributed in the hope that it will be useful,    */
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  */
/* GNU General Public License for more details.           */
/*                                    */
/* You should have received a copy of the GNU General Public License  */
/* along with this program; if not, write to the Free Software        */
/* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA      */
/*  02111-1307, USA.                          */
/*                                    */
/* Michael C. Shultz                          */
/* ringworm@inbox.lv                          */
/* Box 3238 Landers, CA 92285                     */
/************************************************************************/
#include  "mgmlParse.h"

#define PASS01    1
#define PASS02    2

typedef struct
{
    int             argc;
    unsigned    int     streamBufferSize;
    
    char**          argv;
    char*           streamBuffer;

    FILE*           streamInput;

} tree;

int pass1( tree * );
int pass2( tree * );
int pass3( tree * );
/**********************************************************************************/
int    main( int argc, char **argv )
{
    char*   id      = argv[0];
    char    ver[]       = "0.1.4";
    tree    property;
    FILE*   tidyStream  = NULL;

    property.argc   = argc;
    property.argv   = argv;

    /* open input file */
    if( pass1( &property ) != 0 )
    {
        fprintf( stderr, "%s %s: pass1 returned an error\n", id, ver );
        exit( PASS01 ); 
    }

    /* read input file's contents into a buffer */
    if( pass2( &property ) != 0 )
    {
        fprintf( stderr, "%s %s: pass2 returned an error\n", id, ver );
        exit( PASS02 );
    } 
    
    pass3( &property );

    tidyStream = popen(
        "/usr/local/bin/tidy  -i -c -asxml -preserve -q -f tidy.err",
        "w" );
    fprintf( tidyStream, "%s\n", property.streamBuffer );
    pclose( tidyStream );   

    free( property.streamBuffer );
    exit( 0 );
}
/**********************************************************************************/
int pass3( tree *property )
{
    char    topTag[]    = "<html><head><LINK REL=STYLESHEET HREF=docbook.css></head><body>";
    char    baseTag[]   = "</body></html>";
    char    blankTag[]  = " "; 
    char    tagBookEnd[]    = "</book>";
    char    tagBook[]   = "<book>";
    char    tagChapEnd[]    = "</chap>";
    char    tagChap[]   = "<chap>";
    char    tagDateEnd[]    = "</date>";
    char    tagDate[]   = "<date>";
    char    tagH1End[]  = "</h1>";
    char    tagH1[]     = "<h1>";
    char    tagH2End[]  = "</h2>";
    char    tagH2[]     = "<h2>";
    char    tagH3End[]  = "</h3>";
    char    tagH3[]     = "<h3>";
    char    tagH4End[]  = "</h4>";
    char    tagH4[]     = "<h4>";
    char    tagOSEnd[]  = "</os>";
    char    tagOS[]     = "<os>";
    char    tagSect1End[]   = "</sect1>";
    char    tagSect1[]  = "<sect1>";
    char    tagSect2End[]   = "</sect2>";
    char    tagSect2[]  = "<sect2>";
    char    tagSetEnd[]     = "</set>";
    char    tagSet[]    = "<set>";
    char    tagTitleEnd[]   = "</title>";
    char    tagTitle[]  = "<title>";

    while( MGrInStringSwap( property->streamBuffer, tagDate, tagH4 ) == 0 )
    {
        MGrInStringSwap( property->streamBuffer, tagDateEnd, tagH4End );
    }
    while( MGrInStringSwap( property->streamBuffer, tagOS, tagH2 ) == 0 )
    {
        MGrInStringSwap( property->streamBuffer, tagOSEnd, tagH2End );
    }

    if( !( MGrInStringSwap( property->streamBuffer,
    tagSet, topTag ) ) )
    {
        MGrInStringSwap( property->streamBuffer, tagTitle, tagH1 );
        MGrInStringSwap( property->streamBuffer, tagTitleEnd, tagH1End );
        while( MGrInStringSwap( property->streamBuffer, tagBook, blankTag ) == 0 )
        {
            MGrInStringSwap( property->streamBuffer, tagTitle, tagH2 );
            MGrInStringSwap( property->streamBuffer, tagTitleEnd, tagH2End );
            while( MGrInStringSwap( property->streamBuffer, tagChap, blankTag ) == 0 )
            {
                MGrInStringSwap( property->streamBuffer, tagTitle, tagH3 );
                MGrInStringSwap( property->streamBuffer, tagTitleEnd, tagH3End );
                while( MGrInStringSwap( property->streamBuffer, tagSect1, blankTag ) == 0 )
                {
                    MGrInStringSwap( property->streamBuffer, tagTitle, tagH4 );
                    MGrInStringSwap( property->streamBuffer, tagTitleEnd, tagH4End );
                    while( MGrInStringSwap( property->streamBuffer, tagSect2, blankTag ) == 0 )
                    {
                        MGrInStringSwap( property->streamBuffer, tagTitle, tagH4 );
                        MGrInStringSwap( property->streamBuffer, tagTitleEnd, tagH4End );
                        MGrInStringSwap( property->streamBuffer, tagSect2End, blankTag );
                    }
                    MGrInStringSwap( property->streamBuffer, tagSect1End, blankTag );
                }
                MGrInStringSwap( property->streamBuffer, tagChapEnd, blankTag );
            }
            MGrInStringSwap( property->streamBuffer, tagBookEnd, blankTag );
        }
        MGrInStringSwap( property->streamBuffer, tagSetEnd, baseTag );
        return( 0 );   
    }
    if( !( MGrInStringSwap( property->streamBuffer,
    tagBook, topTag ) ) )
    {
        MGrInStringSwap( property->streamBuffer, tagTitle, tagH2 );
        MGrInStringSwap( property->streamBuffer, tagTitleEnd, tagH2End );
        while( MGrInStringSwap( property->streamBuffer, tagChap, blankTag ) == 0 )
        {
            MGrInStringSwap( property->streamBuffer, tagTitle, tagH3 );
            MGrInStringSwap( property->streamBuffer, tagTitleEnd, tagH3End );
            while( MGrInStringSwap( property->streamBuffer, tagSect1, blankTag ) == 0 )
            {
                MGrInStringSwap( property->streamBuffer, tagTitle, tagH4 );
                MGrInStringSwap( property->streamBuffer, tagTitleEnd, tagH4End );
                    while( MGrInStringSwap( property->streamBuffer, tagSect2, blankTag ) == 0 )
                    {
                        MGrInStringSwap( property->streamBuffer, tagTitle, tagH4 );
                        MGrInStringSwap( property->streamBuffer, tagTitleEnd, tagH4End );
                        MGrInStringSwap( property->streamBuffer, tagSect2End, blankTag );
                    }
                MGrInStringSwap( property->streamBuffer, tagSect1End, blankTag );
            }
            MGrInStringSwap( property->streamBuffer, tagChapEnd, blankTag );
        }
        MGrInStringSwap( property->streamBuffer, tagBookEnd, baseTag );
        return( 0 );   
    }
    if( !( MGrInStringSwap( property->streamBuffer,
    tagChap, topTag ) ) )
    {
        MGrInStringSwap( property->streamBuffer, tagTitle, tagH3 );
        MGrInStringSwap( property->streamBuffer, tagTitleEnd, tagH3End );
        while( MGrInStringSwap( property->streamBuffer, tagSect1, blankTag ) == 0 )
        {
            MGrInStringSwap( property->streamBuffer, tagTitle, tagH4 );
            MGrInStringSwap( property->streamBuffer, tagTitleEnd, tagH4End );
            while( MGrInStringSwap( property->streamBuffer, tagSect2, blankTag ) == 0 )
            {
                MGrInStringSwap( property->streamBuffer, tagTitle, tagH4 );
                MGrInStringSwap( property->streamBuffer, tagTitleEnd, tagH4End );
                MGrInStringSwap( property->streamBuffer, tagSect2End, blankTag );
            }
            MGrInStringSwap( property->streamBuffer, tagSect1End, blankTag );
        }
        MGrInStringSwap( property->streamBuffer, tagChapEnd, baseTag );
        return( 0 );   
    }
    if( !( MGrInStringSwap( property->streamBuffer,
    tagSect1, topTag ) ) )
    {
        MGrInStringSwap( property->streamBuffer, tagTitle, tagH4 );
        MGrInStringSwap( property->streamBuffer, tagTitleEnd, tagH4End );
        while( MGrInStringSwap( property->streamBuffer, tagSect2, blankTag ) == 0 )
        {
            MGrInStringSwap( property->streamBuffer, tagTitle, tagH4 );
            MGrInStringSwap( property->streamBuffer, tagTitleEnd, tagH4End );
            MGrInStringSwap( property->streamBuffer, tagSect2End, blankTag );
        }
        MGrInStringSwap( property->streamBuffer, tagSect1End, baseTag );
        return( 0 );   
    }
    return( 0 );   
}

/**********************************************************************************/
int pass2( tree *property )
{
    char    id[]        = "pass2";

    property->streamBufferSize = 0;
    while( fgetc( property->streamInput ) != EOF )
    {
        property->streamBufferSize++;
    }   
    property->streamBufferSize = property->streamBufferSize * 2;
    /*
        fprintf( stderr, "property->streamBufferSize = %d\n", property->streamBufferSize );
    */
    if( ferror( property->streamInput ) != 0 )
    {
        fprintf( stderr, "%s error: error reading property->streamInput\n", id );
        perror( "system message" );
        return( 1 ); 
    }   
    rewind( property->streamInput );
    property->streamBuffer   = ( char* )malloc( property->streamBufferSize );
/* Fix strlen seg fault in CURRENT??? ver 0.1.8 20040806 */
property->streamBuffer[property->streamBufferSize - 1] = 0;

    if( property->streamBuffer == NULL )
    {
        fprintf( stderr, "%s error: unable to allocate memory for property->streamBuffer\n", 
                    id );
        return( 1 ); 
    }   
    fread( property->streamBuffer, 1, property->streamBufferSize, property->streamInput );
    if( ferror( property->streamInput ) != 0 )
    {
        fprintf( stderr, "%s error: error reading property->streamInput\n", id );
        perror( "system message" );
        return( 1 ); 
    }   
    fflush( property->streamInput );
    fclose( property->streamInput );
    return( 0 );
}
/**********************************************************************************/
int pass1( tree *property )
{
    char    id[]    = "pass1";
    if( property->argc == 0 )
    {
        fprintf( stderr, "I need a file to parse on the command line\n" );
        return( 1 );
    }
    property->streamInput = fopen( property->argv[1], "r" );
    if( property->streamInput == NULL )
    {
        fprintf( stderr, "%s error:  unable to open %s  ", id, property->argv[1] );
        perror( "system message" );
        return( 1 );
    }
    return( 0 );
}