/*
** small database program using the ini.library
*/

#include <stdio.h>
#include <string.h>
#include <dos/dos.h>
#include <dos/dosasl.h>
#include <proto/exec.h>
#include <proto/dos.h>

#include "/libraries/ini.h"
#include "/clib/ini_protos.h"
#include "/pragmas/ini_pragmas.h"

#define ARG_TEMPLATE    "DBASE/A,INDEX/S,FIND/K,ADD/K,REMOVE/K,CONTENTS/K"
#define ARGOPT_DBASE    0
#define ARGOPT_INDEX    1
#define ARGOPT_FIND     2   
#define ARGOPT_ADD      3
#define ARGOPT_REMOVE   4
#define ARGOPT_CONTENTS 5
#define ARGOPT_COUNT    6

#define DBASE_SECTION   "DBASE"

static UBYTE *VersTag = "\0$VER: dbase 1.0 (Oct.1,1993)";
struct RDArgs *args = NULL;
LONG opts[ ARGOPT_COUNT ];
struct IniBase *IniBase;
STRPTR fileName;

int main(int argc, char *argv[])
{
    if( ( args = ReadArgs( ARG_TEMPLATE, opts, NULL ) ) == NULL )
    {
        PrintFault( IoErr(), NULL );
        return( RETURN_ERROR );
    }

    if( ( IniBase = (struct IniBase *)OpenLibrary( "ini.library", 0 ) ) != NULL )
    {
        INIPARSER parser; 
        INILINEINFO *info;
        INIERROR rc;

        fileName = (STRPTR)(opts[ARGOPT_DBASE]);

        /* open the dbase */
        if( ( rc = ini_New( fileName, &parser ) ) == INIERROR_NONE )
        {
            /* now that the ini.library has opened our small database, we have 
               four options available
               
                * "INDEX" = print out a list of all contents
                * "FIND" = find an entry and show it
                * "ADD" = add a new entry
                * "REMOVE" = remove an existing entry

            */
            
            if( opts[ ARGOPT_INDEX ] ) 
            {
                /* find section header */
                if( ( info = ini_GetHeader( &parser, DBASE_SECTION ) ) != NULL )
                {
                    /* the first element in the list is the first after the header */
                    for( info = (INILINEINFO *)info->node.ln_Succ;
                         info && (info->flags!=INIFLAG_HEADER);
                         info = (INILINEINFO *)info->node.ln_Succ )
                    {
                        /* show only variables */
                        if( info->flags == INIFLAG_VARIABLE )
                        {
                            printf("%s=%s\n", info->variable, info->contents );
                        }
                    }
                }
                else printf("ERROR, cannot find DBASE section\n");
            }           
            else if( opts[ ARGOPT_FIND ] )
            {
                char buffer[256];

                /* we use ini_GetString() for this simple task */
                ini_GetString( &parser,
                               DBASE_SECTION,
                               (STRPTR)opts[ ARGOPT_FIND ],
                               "<not found>",
                               buffer,
                               256 );

                printf("%s=%s\n", (STRPTR)opts[ ARGOPT_FIND ], buffer );               
            }
            else if( opts[ ARGOPT_REMOVE ] )
            {
                if( ( rc = ini_RemoveVariable( &parser, DBASE_SECTION,
                                            (STRPTR)opts[ ARGOPT_REMOVE ] ) ) == INIERROR_NONE )
                {
                    if( ( rc = ini_Save( fileName, &parser ) ) != INIERROR_NONE )
                        printf( "INIERROR:\"%s\" returned from ini_Save()\n", ini_ErrorString( rc ) );                   
                }
                else printf( "INIERROR:\"%s\" returned from ini_RemoveVariable()\n", ini_ErrorString( rc ) );
            }
            else if( opts[ ARGOPT_ADD ] )
            {
                /* add string "<ARGOPT_ADD>=<ARGOPT_CONTENTS>". We can use
                   ini_ChangeString() for that matter, because this function
                   automagically appends the name if it doesn't yet exist */

                STRPTR newContents = opts[ARGOPT_CONTENTS] ? (STRPTR)opts[ ARGOPT_CONTENTS ] : (STRPTR)"<unused>";
                
                if( ( rc = ini_ChangeString( &parser, DBASE_SECTION,
                            (STRPTR)opts[ ARGOPT_ADD ], newContents ) ) == INIERROR_NONE )
                {
                    if( ( rc = ini_Save( fileName, (INIPARSER *)&parser ) ) != INIERROR_NONE )
                        printf( "INIERROR:\"%s\" returned from ini_Save()\n", ini_ErrorString( rc ) );
                }
                else printf( "INIERROR:\"%s\" returned from ini_ChangeString()\n", ini_ErrorString( rc ) );
            }

            ini_Delete( &parser );
        }
        else printf( "INIERROR:\"%s\" returned from ini_New()\n", ini_ErrorString( rc ) );

        CloseLibrary( (struct Library *)IniBase );
    }

    FreeArgs( args );

    return( RETURN_OK );
}
