#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <conio.h>
#include <rtos.h>
#include <stdlib.h>
#include <filename.h>
#include <inifile.h>

#ifdef __DJGPP__
#include <unistd.h>
#endif

#define INIBUFSIZE ( 512 + 1 )
#define FILELENGTH ( 80 + 1 ) /* dos file length limit */

//----------------------------------------------------------------------
void trim( char *s )
{
    char *p, *q;

    /* trim left spaces */
    for ( p = s ; (*p) && isspace(*p) ; p++ );
    for ( q = s ; *p ; ) *q++ = *p++;
    *q = 0;

    /* trim right spaces */
    if ( q != s ) {
        while ( isspace( *(--q) ))
           *q = 0;
    }
}

//----------------------------------------------------------------------

/* GetSectionName destructive */
static char *GetSectionName( char *line )
{
    char *p;
    if ( *line == '[') {
        if ( (p = strchr( line , ']' )) != NULL ) {
            *p = 0;
            *line = ' ';
            trim( line );
            return( line );
        }
    }
    return( NULL );
}

//----------------------------------------------------------------------

static char *GetKeyData( char *line )
{
    char *p;

    if ( *line == '[' ) return( NULL );

    if ((p = strchr(line,'='))!=NULL ) {
        *p++ = 0;
        trim( line );
        trim( p );
        return( p );
    }
    return( NULL );
}

//----------------------------------------------------------------------

char * GetIniString( const char *filename, const char *section,
                     const char *key, const char *def )
{
    FILE *f = NULL;
    char *result = NULL;
    char *buf = NULL;
    char *p;
    int insection = 0;

    dos_enter();
    do {
        if ((buf = kcalloc( INIBUFSIZE , 1 )) == NULL ) break;

        if ((f = fopen( filename, "rt")) != NULL ) {
            while ( fgets( buf, INIBUFSIZE - 1, f ) != NULL ) {
                buf[ INIBUFSIZE - 1 ] = 0;

                trim( buf );

                if ( (*buf != '#') && ( *buf != ';' )) {
                    /* check if section name */
                    if ( ( p = GetSectionName( buf )) != NULL )
                        insection = !stricmp( p, section );
                    else {
                        /* data line */
                        if ( insection != 0 ) {
                            if ( (p = GetKeyData( buf )) != NULL ) {
                                if ( !stricmp( buf, key )) {
                                    result = kstrdup( p );
                                    break;
                                }
                            }
                        }
                    }
                }
            }
        }
    } while ( 0 );
    if ( f != NULL ) fclose( f );
    if ( buf != NULL ) kfree( buf );
    dos_exit();

    /* didn't find it, use default */
    if ( result == NULL )
        if ( def != NULL )
            result = kstrdup( def );
    return( result );
}

//----------------------------------------------------------------------

int SetIniString( const char *filename, const char *section,
                  const char *key, const char *value )
{
    char *name2;
    FILE *in = NULL, *out = NULL;
    int result = 0;
    char *buf = NULL;
    char *p;
    int insection = 0;


    dos_enter();

    /* terminate values with CR or LF */
    if ( ( p = strchr( value , 13 )) != NULL ) *p = 0;
    if ( ( p = strchr( value , 10 )) != NULL ) *p = 0;

    do {
        if ((buf = kcalloc( INIBUFSIZE , 1 )) == NULL ) break;
        if ((name2 = kcalloc( FILELENGTH, 1 )) == NULL ) break;

        FileChangeExt(filename, ".TMP", name2 );
        if ( FileExists( name2 )) unlink( name2 );

        if (( out = fopen( name2, "wt" )) == NULL ) break;

        if (( in = fopen( filename, "rt" )) == NULL ) {
            fprintf( out, "[%s]\n", section );
            fprintf( out, "%s=%s\n", key, value );
            result = 1;
            break;
        }

        while ( fgets( buf, INIBUFSIZE - 1, in ) != NULL ) {
            buf[ INIBUFSIZE - 1 ] = 0;

            trim( buf );

            /* preserve comments */
            if ( (*buf == '#') || ( *buf == ';' )) {
                fprintf( out, "%s\n", buf );
                continue;
            }

            /* look for section names */
            if ( ( p = GetSectionName( buf )) != NULL ) {
                fprintf( out, "\n[%s]\n", p );

                if ( (insection = !stricmp( p, section )) != 0 ) {
                    /* write our new data */
                    fprintf( out , "%s=%s\n", key, value );
                    result = 1;
                }
                continue;
            }

            /* look for x=y */
            if ( ( p = GetKeyData( buf )) != NULL ) {
                if ( !insection || stricmp( buf, key )) {
                    fprintf(out,"%s=%s\n", buf, p );
                }
            }
            continue;
        }
        if ( result == 0 ) {
            fprintf( out, "[%s]\n", section );
            fprintf( out, "%s=%s\n", key, value );
            result = 1 ;
        }

    } while ( 0 );

    if ( in    != NULL ) fclose( in );
    if ( out   != NULL ) fclose( out );

    if ( result ) {
        if ( FileExists( filename ) )
            FileRenameExt( filename, ".BAK" );
        result = FileRenameExt( name2, FileGetExt( filename ));
    }

    if ( buf   != NULL ) kfree( buf );
    if ( name2 != NULL ) kfree( name2 );

    dos_exit();
    return( result );
}
//----------------------------------------------------------------------
DWORD GetIniDWORD( const char *filename, const char *section,
                   const char *key, DWORD def )
{
    char *s;
    DWORD x = def;
    if ( ( s = GetIniString( filename, section, key, NULL )) != NULL ) {
        trim( s );  /* get rid of leading spaces */
        x = atol( s );
        kfree( s );
    }
    return( x );
}
//----------------------------------------------------------------------
DWORD SetIniDWORD( const char *filename, const char *section,
                   const char *key, DWORD value )
{
    char s[32];

    sprintf( s, "%lu" , value );
    return( SetIniString( filename, section, key, s ));
}


