// IniFile.cpp: implementation of the IniFile class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "IniFile.h"
#include <stdio.h>


#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

IniFile::IniFile()
{
    isValid=true;
    char tempo[30];
    if (!MainFile.Open(FILENAME,CFile::modeReadWrite | CFile::shareDenyNone))
    {
        InitFile(); 
    }
    // if this isn't true then the file is corrupted, hence make a new one.
    else if (!(SearchforKey(DEFAULTMAP,tempo)))
    {
        InitFile();
    }
    else
    {
        isValid = true;
    }  
}

IniFile::~IniFile()
{
        MainFile.Close();
}


BOOL IniFile::SearchforKey(char *key, char *returnstring)
{
    char AllInfo[INIMAXFILESIZE];
    char temp1[INIMAXKEYSIZE];
    char temp2[INIMAXKEYSIZE];
    char *tptr;

    if (!isValid)
        return false;

    MainFile.SeekToBegin();
    int filelength = MainFile.Read(AllInfo,1000);

    if ((filelength < INIMAXFILESIZE) && (filelength >= 0))
    {
        AllInfo[filelength] = '\0'; // need to do this to get the sscanf to work properly
    }

    tptr = AllInfo;
    int tremain,length;

    tremain = sscanf(tptr,"%s = %s",temp1,temp2);
    length = strlen(temp1)+strlen(temp2) + 4;

    while ( tremain != EOF )
    {
        if (!strcmp(temp1,key)) // it is the key
        {
            strcpy(returnstring,temp2);
            RemoveUnderScore(returnstring);
            return true;
        }
        else
        {
            tptr+=length;
            tremain = sscanf(tptr,"%s = %s",temp1,temp2);
            length = strlen(temp1)+strlen(temp2) + 5;
        }
    }
    return false;



}

BOOL IniFile::SearchforKey(char *key, CString &returnstring)
{
    char AllInfo[INIMAXFILESIZE];
    char temp1[INIMAXKEYSIZE];
    char temp2[INIMAXKEYSIZE];
    char *tptr;

    if (!isValid)
        return false;

    MainFile.SeekToBegin();
    int filelength = MainFile.Read(AllInfo,1000);

    if ((filelength < INIMAXFILESIZE) && (filelength >= 0))
    {
        AllInfo[filelength] = '\0'; // need to do this to get the sscanf to work properly
    }

    tptr = AllInfo;
    int tremain,length;

    tremain = sscanf(tptr,"%s = %s",temp1,temp2);
    length = strlen(temp1)+strlen(temp2) + 4;

    while ( tremain != EOF )
    {
        if (!strcmp(temp1,key)) // it is the key
        {
            returnstring = temp2;
            RemoveUnderScore(returnstring);
            return true;
        }
        else
        {
            tptr+=length;
            tremain = sscanf(tptr,"%s = %s",temp1,temp2);
            length = strlen(temp1)+strlen(temp2) + 5;
        }
    }
    return false;



}

void IniFile::RemoveUnderScore(char *buffer)
{
    int length = strlen(buffer);
    for (int ix = 0; ix < length; ix++)
    {
        if (buffer[ix] == '_')
        {
            buffer[ix] = ' ';
        }
    }
}

void IniFile::RemoveUnderScore(CString &buffer)
{
    buffer.Replace("_"," ");
}


void IniFile::AddUnderScore(char *buffer)
{
    int length = strlen(buffer);
    for (int ix = 0; ix < length; ix++)
    {
        if (buffer[ix] == ' ')
        {
            buffer[ix] = '_';
        }
    }

}

BOOL IniFile::AddKey(char *key, char *value)
{
    char Buffer[INIMAXFILESIZE];
    char tempo[INIMAXKEYSIZE];
    RemoveUnderScore(key);

    if (!isValid)
        return false;

    if (SearchforKey(key,tempo))
    {
        return false; // already exists
    }
    else
    {
        MainFile.SeekToBegin();
        int filelength = MainFile.Read(Buffer,INIMAXFILESIZE);
        if ((filelength < INIMAXFILESIZE) && (filelength >= 0))
        {
            Buffer[filelength] = '\0'; // need to do this to get the sscanf to work properly
        }

        sprintf(tempo,"%s = %s%c%c",key,value,13,10);
        strcat(Buffer,tempo);
        MainFile.SeekToBegin();
        MainFile.Write(Buffer,strlen(Buffer));
        return true;
    }





}

BOOL IniFile::ReplaceKey(char *key, char *newvalue)
{
    char AllInfo[INIMAXFILESIZE];
    char newbuffer[INIMAXFILESIZE];
    char temp1[INIMAXKEYSIZE];
    char temp2[INIMAXKEYSIZE];
    char *tptr;
    bool change = false;

    if (!isValid)
        return false;

    newbuffer[0] = '\0';

    AddUnderScore(newvalue);
    MainFile.SeekToBegin();
    int filelength = MainFile.Read(AllInfo,INIMAXFILESIZE);

    if ((filelength < INIMAXFILESIZE) && (filelength >= 0))
    {
        AllInfo[filelength] = '\0'; // need to do this to get the sscanf to work properly
    }

    tptr = AllInfo;
    int tremain,length,biglength;

    biglength=0;

    tremain = sscanf(tptr,"%s = %s",temp1,temp2);
    length = strlen(temp1)+strlen(temp2) + 4;
    biglength+=length;

    while ( (tremain != EOF) && (biglength <= filelength))
    {
        if (!strcmp(temp1,key)) // it is the key
        {
            char tempo[INIMAXKEYSIZE];
            int count = sprintf(tempo,"%s = %s%c%c",key,newvalue,13,10);
            strncat(newbuffer,tempo,count-1);
            change=true;
        }
        else
        {
            strncat(newbuffer,tptr,length); // +1 because one of the end line characters are not counted
        }
        tptr+=length;
        temp1[0] = '\0';
        temp2[0] = '\0';
        tremain = sscanf(tptr,"%s = %s",temp1,temp2);
        length = strlen(temp1)+strlen(temp2) + 5;
        biglength+=length;
    }

    // I have to recreate the file, in case the newer INI file is short then the old one, some old characters will be stuck at the end.
    MainFile.Close();
    CFile::Remove(FILENAME);
    if (!MainFile.Open(FILENAME,CFile::modeReadWrite | CFile::shareDenyNone | CFile::modeCreate ))
    {
        AfxMessageBox("Warning, INI file Creation Error\nMineSweeper probably located in a read only area\nUser settings will not be saved\n");
        isValid=false;
    }
    MainFile.Write(newbuffer,strlen(newbuffer));

    RemoveUnderScore(newvalue); // so it doesn't change the original value;

    return change;



}

void IniFile::InitFile()
{
    if (!MainFile.Open(FILENAME,CFile::modeReadWrite | CFile::shareDenyNone | CFile::modeCreate ))
    {
        AfxMessageBox("Warning, INI file Creation Error\nMineSweeper probably located in a read only area\nUser settings will not be saved\n");
        isValid=false;
    }
    else
    {
        AddKey(INIMODEL,DEFAULTMODEL);
        AddKey(INIBEAM,DEFAULTBEAM);
        AddKey(INIMAP,DEFAULTMAP);
        isValid = true;
    }

}
