// This file is a part of the xMule Project.
//
// Copyright (c) 2004 Theodore R. Smith (hopeseekr@xmule.ws / http://www.xmule.ws/)
// DSA-1024 Fingerprint: 10A0 6372 9092 85A2 BB7F 907B CB8B 654B E33B F1ED
//
// 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., 675 Mass Ave, Cambridge, MA 02139, USA.

// Ini.cpp: Implementierung der Klasse CIni.
//
//////////////////////////////////////////////////////////////////////

#ifdef PRECOMP
#	include "xmule-headers.h"
#else
#include "wintypes.h"
#include "ini2.h"
#endif

#include <wx/string.h>
#include <wx/window.h>
#include <wx/config.h>

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;

#define new DEBUG_NEW
#endif

#ifndef _xGetValues_
#	define _xGetValues_
#	define GetRValue(rgb) (((rgb)>>16)&0xff)
#	define GetGValue(rgb) (((rgb)>>8)&0xff)
#	define GetBValue(rgb) ((rgb)&0xff)
#endif

// If the IniFilename contains no path,
// the module-directory will be add to the FileName,
// to avoid storing in the windows-directory
    /*static*/

    void CIni::AddModulPath(wxString &strFileName, bool bModulPath /*= TRUE*/

)
{
#if 0
    char drive[_MAX_DRIVE];
    char dir[_MAX_DIR];
    char fname[_MAX_FNAME];
    char ext[_MAX_EXT];
    _splitpath(strFileName, drive, dir, fname, ext);
    if (! drive[0])
    {
        //PathCanonicalize(..) doesn't work with for all Plattforms !
        wxString strModule;
        if (bModulPath)
        {
            GetModuleFileName(NULL, strModule.GetBuffer(MAX_INI_BUFFER), MAX_INI_BUFFER);
            strModule.ReleaseBuffer();
        }
        else
        {
            GetCurrentDirectory(MAX_INI_BUFFER, strModule.GetBuffer(MAX_INI_BUFFER));
            strModule.ReleaseBuffer();
            // fix by "cpp@world-online.no"
            strModule.TrimRight('\\');
            strModule.TrimRight('/');
            strModule += "\\";
        }
        strModule.ReleaseBuffer();
        _splitpath(strModule, drive, dir, fname, ext);
        strModule = drive;
        strModule += dir;
        strModule += strFileName;
        strFileName = strModule;
    }
#endif
}

    /*static*/

wxString CIni::GetDefaultSection()
{
    return wxString("eMule");
    //   return AfxGetAppName();
}

    /*static*/

    wxString CIni::GetDefaultIniFile(bool bModulPath /*= TRUE*/

)
{
#if 0
    char drive[_MAX_DRIVE];
    char dir[_MAX_DIR];
    char fname[_MAX_FNAME];
    char ext[_MAX_EXT];
    wxString strTemp;
    wxString strApplName;
    GetModuleFileName(NULL, strTemp.GetBuffer(MAX_INI_BUFFER), MAX_INI_BUFFER);
    strTemp.ReleaseBuffer();
    _splitpath(strTemp, drive, dir, fname, ext);
    //"ApplName":
    strTemp = fname;
    //"ApplName.ini":
    strTemp += ".ini";
    if (bModulPath)
    {
        strApplName = drive;
        strApplName += dir;
        strApplName += strTemp;
    }
    else
    {
        GetCurrentDirectory(MAX_INI_BUFFER, strApplName.GetBuffer(MAX_INI_BUFFER));
        strApplName.ReleaseBuffer();
        strApplName.TrimRight('\\');
        strApplName.TrimRight('/');
        strApplName += "\\";
        strApplName += strTemp;
    }
    return strApplName;
#endif
    return "perse";
}

//////////////////////////////////////////////////////////////////////
// Konstruktion/Destruktion
//////////////////////////////////////////////////////////////////////
// Creates/Use file : "Drive:\ApplPath\ApplName.ini"
    CIni::CIni(bool bModulPath /*= TRUE*/

):
m_bModulPath(bModulPath)
{
    m_strFileName = GetDefaultIniFile(m_bModulPath);
    m_strSection = GetDefaultSection();
}

    CIni::CIni(CIni const &Ini, bool bModulPath /*= TRUE*/

):
m_strFileName(Ini.m_strFileName),
m_strSection(Ini.m_strSection),
m_bModulPath(Ini.m_bModulPath)
{
    if (m_strFileName.IsEmpty())
    m_strFileName = GetDefaultIniFile(m_bModulPath);
    AddModulPath(m_strFileName, m_bModulPath);
    if (m_strSection.IsEmpty())
    m_strSection = GetDefaultSection();
}

    CIni::CIni(wxString const &strFileName, bool bModulPath /*= TRUE*/

):
m_strFileName(strFileName),
m_bModulPath(bModulPath)
{
    if (m_strFileName.IsEmpty())
    m_strFileName = GetDefaultIniFile(m_bModulPath);
    AddModulPath(m_strFileName, bModulPath);
    m_strSection = GetDefaultSection();
}

    CIni::CIni(wxString const &strFileName, wxString const &strSection, bool bModulPath /*= TRUE*/

):
m_strFileName(strFileName),
m_strSection(strSection),
m_bModulPath(bModulPath)
{
    if (m_strFileName.IsEmpty())
    m_strFileName = GetDefaultIniFile(m_bModulPath);
    AddModulPath(m_strFileName, bModulPath);
    if (m_strSection.IsEmpty())
    m_strSection = GetDefaultSection();
}

CIni::~CIni()
{
}

//////////////////////////////////////////////////////////////////////
// Zugriff auf Quelle/Ziel von IO-Operationen
//////////////////////////////////////////////////////////////////////
void CIni::SetFileName(wxString const &strFileName)
{
    m_strFileName = strFileName;
    AddModulPath(m_strFileName);
}

void CIni::SetSection(wxString const &strSection)
{
    m_strSection = strSection;
}

wxString const &CIni::GetFileName() const
{
    return m_strFileName;
}

wxString const &CIni::GetSection() const
{
    return m_strSection;
}

//////////////////////////////////////////////////////////////////////
//
//////////////////////////////////////////////////////////////////////

    void CIni::Init(LPCSTR strFileName, LPCSTR strSection/* = NULL*/

)
{
    if (strSection != NULL)
    m_strSection = strSection;
    if (strFileName != NULL)
    m_strFileName = strFileName;
}

    wxString CIni::GetString(wxString strEntry, LPCSTR strDefault/*=NULL*/

    , LPCSTR strSection/* = NULL*/

)
{
    if (strDefault == NULL)
    return wxString(GetLPCSTR(strEntry, strSection, ""));
    else
    return wxString(GetLPCSTR(strEntry, strSection, strDefault));
}

    double CIni::GetDouble(wxString strEntry, double fDefault/* = 0.0*/

    , LPCSTR strSection/* = NULL*/

)
{
    wxString strDefault;
    //strDefault.Printf("%g",fDefault);
    strDefault = wxString::Format("%g", fDefault);
    GetLPCSTR(strEntry, strSection, strDefault);
    return atof(m_chBuffer);
}

    float CIni::GetFloat(wxString strEntry, float fDefault/* = 0.0*/

    , LPCSTR strSection/* = NULL*/

)
{
    wxString strDefault;
    //strDefault.Printf("%g",fDefault);
    strDefault = wxString::Format("%g", fDefault);
    GetLPCSTR(strEntry, strSection, strDefault);
    return(float) atof(m_chBuffer);
}

    int CIni::GetInt(wxString strEntry, int nDefault/* = 0*/

    , LPCSTR strSection/* = NULL*/

)
{
    wxString strDefault;
    //strDefault.Printf("%d",nDefault);
    strDefault = wxString::Format("%d", nDefault);
    GetLPCSTR(strEntry, strSection, strDefault.GetData());
    return atoi(m_chBuffer);
}

    WORD CIni::GetWORD(wxString strEntry, WORD nDefault/* = 0*/

    , LPCSTR strSection/* = NULL*/

)
{
    wxString strDefault;
    //strDefault.Printf("%u",nDefault);
    strDefault = wxString::Format("%u", nDefault);
    GetLPCSTR(strEntry, strSection, strDefault);
    return(WORD) atoi(m_chBuffer);
}

    bool CIni::GetBool(wxString strEntry, bool bDefault/* = FALSE*/

    , LPCSTR strSection/* = NULL*/

)
{
    wxString strDefault;
    //strDefault.Printf("%d",bDefault);
    strDefault = wxString::Format("%d", bDefault);
    GetLPCSTR(strEntry, strSection, strDefault);
    return(atoi(m_chBuffer) != 0);
}

wxPoint CIni::GetPoint(wxString strEntry, wxPoint ptDefault, LPCSTR strSection)
{
    wxPoint ptReturn = ptDefault;
    wxString strDefault;
    strDefault = wxString::Format("(%d,%d)", ptDefault.x, ptDefault.y);
    //strDefault.Printf("(%d,%d)",ptDefault.x, ptDefault.y);
    wxString strPoint = GetString(strEntry, (char *) strDefault.GetData());
    sscanf(strPoint, "(%d,%d)", &ptReturn.x, &ptReturn.y);
    return ptReturn;
}

wxRect CIni::GetRect(wxString strEntry, wxRect rectDefault, LPCSTR strSection)
{
#if 0
    wxRect rectReturn = rectDefault;
    wxString strDefault;
    //old version :strDefault.Printf("(%d,%d,%d,%d)",rectDefault.top,rectDefault.left,rectDefault.bottom,rectDefault.right);
    strDefault.Printf("%d,%d,%d,%d", rectDefault.left, rectDefault.top, rectDefault.right, rectDefault.bottom);
    wxString strRect = GetString(strEntry, strDefault);
    int nRead = 0;
    //new Version found
    if (4 == sscanf(strRect, "%d,%d,%d,%d", &rectDefault.left, &rectDefault.top, &rectDefault.right, &rectDefault.bottom))
    return rectReturn;
    //old Version found
    sscanf(strRect, "(%d,%d,%d,%d)", &rectReturn.top, &rectReturn.left, &rectReturn.bottom, &rectReturn.right);
    return rectReturn;
#endif
    return wxRect(0, 0, 0, 0);
}

COLORREF CIni::GetColRef(wxString strEntry, COLORREF crDefault, LPCSTR strSection)
{
    int temp[3] =
    {
        GetRValue(crDefault),
        GetGValue(crDefault),
        GetBValue(crDefault)
        };
    wxString strDefault;
    strDefault = wxString::Format("RGB(%hd,%hd,%hd)", temp[0], temp[1], temp[2]);
    wxString strColRef = GetString(strEntry, (char *) strDefault.GetData());
    sscanf(strColRef, "RGB(%d,%d,%d)", temp, temp + 1, temp + 2);
    return RGB(temp[0], temp[1], temp[2]);
}

void WritePrivateProfileString(const char *sec, const char *entry, const char *jottae, const char *d)
{
    char buffer[512];
    sprintf(buffer, "%s/%s", sec, entry);
    wxConfigBase *cb = wxConfigBase::Get(TRUE);
    cb->Write(buffer, jottae);
    cb->Flush();
}

    void CIni::WriteString(wxString strEntry, wxString str, LPCSTR strSection/* = NULL*/

)
{
    if (strSection != NULL)
    m_strSection = strSection;
    WritePrivateProfileString(m_strSection, strEntry, str, m_strFileName);
}

    void CIni::WriteDouble(wxString strEntry, double f, LPCSTR strSection/*= NULL*/

)
{
    if (strSection != NULL)
    m_strSection = strSection;
    wxString strBuffer;
    strBuffer = wxString::Format("%g", f);
    WritePrivateProfileString(m_strSection, strEntry, strBuffer, m_strFileName);
}

    void CIni::WriteFloat(wxString strEntry, float f, LPCSTR strSection/* = NULL*/

)
{
    if (strSection != NULL)
    m_strSection = strSection;
    wxString strBuffer;
    strBuffer = wxString::Format("%g", f);
    WritePrivateProfileString(m_strSection, strEntry, strBuffer, m_strFileName);
}

    void CIni::WriteInt(wxString strEntry, int n, LPCSTR strSection/* = NULL*/

)
{
    if (strSection != NULL)
    m_strSection = strSection;
    wxString strBuffer;
    strBuffer = wxString::Format("%d", n);
    WritePrivateProfileString(m_strSection, strEntry, strBuffer, m_strFileName);
}

    void CIni::WriteWORD(wxString strEntry, WORD n, LPCSTR strSection/* = NULL*/

)
{
    if (strSection != NULL)
    m_strSection = strSection;
    wxString strBuffer;
    strBuffer = wxString::Format("%u", n);
    WritePrivateProfileString(m_strSection, strEntry, strBuffer, m_strFileName);
}

    void CIni::WriteBool(wxString strEntry, bool b, LPCSTR strSection/* = NULL*/

)
{
    if (strSection != NULL)
    m_strSection = strSection;
    wxString strBuffer;
    strBuffer = wxString::Format("%d", b);
    WritePrivateProfileString(m_strSection, strEntry, strBuffer, m_strFileName);
}

void CIni::WritePoint(wxString strEntry, wxPoint pt, LPCSTR strSection)
{
    if (strSection != NULL)
    m_strSection = strSection;
    wxString strBuffer;
    strBuffer = wxString::Format("(%d,%d)", pt.x, pt.y);
    Write(m_strFileName, m_strSection, strEntry, strBuffer);
}

void CIni::WriteRect(wxString strEntry, wxRect rect, LPCSTR strSection)
{
    if (strSection != NULL)
    m_strSection = strSection;
    wxString strBuffer;
    //strBuffer.Printf("(%d,%d,%d,%d)",rect.top,rect.left,rect.bottom,rect.right);
    Write(m_strFileName, m_strSection, strEntry, strBuffer);
}

void CIni::WriteColRef(wxString strEntry, COLORREF cr, LPCSTR strSection)
{
    if (strSection != NULL)
    m_strSection = strSection;
    wxString strBuffer;
    strBuffer = wxString::Format("RGB(%d,%d,%d)", GetRValue(cr), GetGValue(cr), GetBValue(cr));
    Write(m_strFileName, m_strSection, strEntry, strBuffer);
}

wxChar *CIni::GetLPCSTR(wxString strEntry, const wxChar *strSection, const wxChar *strDefault)
{
    wxConfigBase *cb = wxConfigBase::Get(TRUE);
    char buffer[512];
    if (strSection)
    m_strSection = wxString(strSection);
    sprintf(buffer, "%s/%s", m_strSection.GetData(), strEntry.GetData());
    wxString stringu = cb->Read(wxString(buffer), wxString(strDefault));
    cb->Flush();
    memcpy(m_chBuffer, stringu.GetData(), stringu.Length() + 1);
    return m_chBuffer;
#if 0
    // evtl Section neu setzen
    if (strSection != NULL)
    m_strSection = strSection;
    wxString temp;
    if (strDefault == NULL)
    temp = Read(m_strFileName, m_strSection, strEntry, wxString());
    else
    temp = Read(m_strFileName, m_strSection, strEntry, strDefault);
    // '+1' damit die Null am Ende mit kopiert wird:
    return(wxChar *) memcpy(m_chBuffer, (LPCTSTR) temp.GetData(), temp.Length() + 1);
#endif
}

void CIni::SerGetString(bool bGet, wxString &str, wxString strEntry, LPCSTR strSection, LPCSTR strDefault)
{
    if (bGet)
    str = GetString(strEntry, strDefault/*=NULL*/
    , strSection/* = NULL*/
    );
    else
    WriteString(strEntry, str, strSection/* = NULL*/
    );
}

    void CIni::SerGetDouble(bool bGet, double &f, wxString strEntry, LPCSTR strSection/* = NULL*/

    , double fDefault/* = 0.0*/

)
{
    if (bGet)
    f = GetDouble(strEntry, fDefault/*=NULL*/
    , strSection/* = NULL*/
    );
    else
    WriteDouble(strEntry, f, strSection/* = NULL*/
    );
}

    void CIni::SerGetFloat(bool bGet, float &f, wxString strEntry, LPCSTR strSection/* = NULL*/

    , float fDefault/* = 0.0*/

)
{
    if (bGet)
    f = GetFloat(strEntry, fDefault/*=NULL*/
    , strSection/* = NULL*/
    );
    else
    WriteFloat(strEntry, f, strSection/* = NULL*/
    );
}

    void CIni::SerGetInt(bool bGet, int &n, wxString strEntry, LPCSTR strSection/* = NULL*/

    , int nDefault/* = 0*/

)
{
    if (bGet)
    n = GetInt(strEntry, nDefault/*=NULL*/
    , strSection/* = NULL*/
    );
    else
    WriteInt(strEntry, n, strSection/* = NULL*/
    );
}

    void CIni::SerGetDWORD(bool bGet, DWORD &n, wxString strEntry, LPCSTR strSection/* = NULL*/

    , DWORD nDefault/* = 0*/

)
{
    if (bGet)
    n = (DWORD) GetInt(strEntry, nDefault/*=NULL*/
    , strSection/* = NULL*/
    );
    else
    WriteInt(strEntry, n, strSection/* = NULL*/
    );
}

    void CIni::SerGetBool(bool bGet, bool &b, wxString strEntry, LPCSTR strSection/* = NULL*/

    , bool bDefault/* = FALSE*/

)
{
    if (bGet)
    b = GetBool(strEntry, bDefault/*=NULL*/
    , strSection/* = NULL*/
    );
    else
    WriteBool(strEntry, b, strSection/* = NULL*/
    );
}

void CIni::SerGetPoint(bool bGet, wxPoint &pt, wxString strEntry, LPCSTR strSection, wxPoint ptDefault)
{
    if (bGet)
    pt = GetPoint(strEntry, ptDefault, strSection);
    else
    WritePoint(strEntry, pt, strSection);
}

void CIni::SerGetRect(bool bGet, wxRect &rect, wxString strEntry, LPCSTR strSection, wxRect rectDefault)
{
    if (bGet)
    rect = GetRect(strEntry, rectDefault, strSection);
    else
    WriteRect(strEntry, rect, strSection);
}

void CIni::SerGetColRef(bool bGet, COLORREF &cr, wxString strEntry, LPCSTR strSection, COLORREF crDefault)
{
    if (bGet)
    cr = GetColRef(strEntry, crDefault, strSection);
    else
    WriteColRef(strEntry, cr, strSection);
}

// Überladene Methoden //////////////////////////////////////////////////////////////////////////////////////////////////77
// Einfache Typen /////////////////////////////////////////////////////////////////////////////////////////////////////////
    void CIni::SerGet(bool bGet, wxString &str, wxString strEntry, LPCSTR strSection/*= NULL*/

    , LPCSTR strDefault/*= NULL*/

)
{
    SerGetString(bGet, str, strEntry, strSection, strDefault);
}

    void CIni::SerGet(bool bGet, double &f, wxString strEntry, LPCSTR strSection/*= NULL*/

    , double fDefault/* = 0.0*/

)
{
    SerGetDouble(bGet, f, strEntry, strSection, fDefault);
}

    void CIni::SerGet(bool bGet, float &f, wxString strEntry, LPCSTR strSection/*= NULL*/

    , float fDefault/* = 0.0*/

)
{
    SerGetFloat(bGet, f, strEntry, strSection, fDefault);
}

    void CIni::SerGet(bool bGet, int &n, wxString strEntry, LPCSTR strSection/*= NULL*/

    , int nDefault/* = 0*/

)
{
    SerGetInt(bGet, n, strEntry, strSection, nDefault);
}

    void CIni::SerGet(bool bGet, short &n, wxString strEntry, LPCSTR strSection/*= NULL*/

    , int nDefault/* = 0*/

)
{
    int nTemp = n;
    SerGetInt(bGet, nTemp, strEntry, strSection, nDefault);
    n = nTemp;
}

    void CIni::SerGet(bool bGet, DWORD &n, wxString strEntry, LPCSTR strSection/*= NULL*/

    , DWORD nDefault/* = 0*/

)
{
    SerGetDWORD(bGet, n, strEntry, strSection, nDefault);
}

    void CIni::SerGet(bool bGet, WORD &n, wxString strEntry, LPCSTR strSection/*= NULL*/

    , DWORD nDefault/* = 0*/

)
{
    DWORD dwTemp = n;
    SerGetDWORD(bGet, dwTemp, strEntry, strSection, nDefault);
    n = dwTemp;
}

//	void		SerGet(	bool bGet,bool		& b,	wxString strEntry,	LPCSTR strSection = NULL,	bool bDefault = FALSE);
    void CIni::SerGet(bool bGet, wxPoint &pt, wxString strEntry, LPCSTR strSection/*= NULL*/

    , wxPoint ptDefault/* = wxPoint(0,0)*/

)
{
    SerGetPoint(bGet, pt, strEntry, strSection, ptDefault);
}

    void CIni::SerGet(bool bGet, wxRect &rect, wxString strEntry, LPCSTR strSection/*= NULL*/

    , wxRect rectDefault/* = wxRect(0,0,0,0)*/

)
{
    SerGetRect(bGet, rect, strEntry, strSection, rectDefault);
}

//	void		SerGet(	bool bGet,COLORREF	& cr,	wxString strEntry,	LPCSTR strSection = NULL,	COLORREF crDefault = RGB(128,128,128));

// Überladene Methoden ////////////////////////////////////////////////////////////////////////////////////////////
// ARRAYS /////////////////////////////////////////////////////////////////////////////////////////////////////////
// Entries werden durch Unterstrich + Index ergenzt////////////////////////////////////////////////////////////////
    void CIni::SerGet(bool bGet, wxString *ar, int nCount, wxString strEntry, LPCSTR strSection/*=NULL*/

    , LPCSTR Default/*=NULL*/

)
{
    if (nCount > 0)
    {
        wxString strBuffer;
        if (bGet)
        {
            strBuffer = GetString(strEntry, "", strSection);
            int nOffset = 0;
            for (int i = 0 ; i < nCount ; i++)
            {
                nOffset = Parse(strBuffer, nOffset, ar[i]);
                if (ar[i].Length() == 0)
                ar[i] = Default;
            }
        }
        else
        {
            strBuffer = ar[0];
            for (int i = 1 ; i < nCount ; i++)
            {
                //.AppendChar(',');:
                strBuffer = strBuffer + ",";
                strBuffer.Append(ar[i]);
            }
            WriteString(strEntry, strBuffer, strSection);
        }
    }
}

    void CIni::SerGet(bool bGet, double *ar, int nCount, wxString strEntry, LPCSTR strSection/*=NULL*/

    , double Default/* = 0.0*/

)
{
    if (nCount > 0)
    {
        wxString strBuffer;
        if (bGet)
        {
            strBuffer = GetString(strEntry, "", strSection);
            wxString strTemp;
            int nOffset = 0;
            for (int i = 0 ; i < nCount ; i++)
            {
                nOffset = Parse(strBuffer, nOffset, strTemp);
                if (strTemp.Length() == 0)
                ar[i] = Default;
                else
                ar[i] = atof(strTemp);
            }
        }
        else
        {
            wxString strTemp;
            strBuffer = wxString::Format("%g", ar[0]);
            for (int i = 1 ; i < nCount ; i++)
            {
                strTemp = wxString::Format("%g", ar[i]);
                //strBuffer.AppendChar(',');
                strBuffer = strBuffer + ",";
                strBuffer.Append(strTemp);
            }
            WriteString(strEntry, strBuffer, strSection);
        }
    }
}

    void CIni::SerGet(bool bGet, float *ar, int nCount, wxString strEntry, LPCSTR strSection/*=NULL*/

    , float Default/* = 0.0*/

)
{
    if (nCount > 0)
    {
        wxString strBuffer;
        if (bGet)
        {
            strBuffer = GetString(strEntry, "", strSection);
            wxString strTemp;
            int nOffset = 0;
            for (int i = 0 ; i < nCount ; i++)
            {
                nOffset = Parse(strBuffer, nOffset, strTemp);
                if (strTemp.Length() == 0)
                ar[i] = Default;
                else
                ar[i] = (float) atof(strTemp);
            }
        }
        else
        {
            wxString strTemp;
            strBuffer = wxString::Format("%g", ar[0]);
            for (int i = 1 ; i < nCount ; i++)
            {
                strTemp = wxString::Format("%g", ar[i]);
                //strBuffer.AppendChar(',');
                strBuffer = strBuffer + ",";
                strBuffer.Append(strTemp);
            }
            WriteString(strEntry, strBuffer, strSection);
        }
    }
}

    void CIni::SerGet(bool bGet, int *ar, int nCount, wxString strEntry, LPCSTR strSection/*=NULL*/

    , int Default/* = 0*/

)
{
    if (nCount > 0)
    {
        wxString strBuffer;
        if (bGet)
        {
            strBuffer = GetString(strEntry, "", strSection);
            wxString strTemp;
            int nOffset = 0;
            for (int i = 0 ; i < nCount ; i++)
            {
                nOffset = Parse(strBuffer, nOffset, strTemp);
                if (strTemp.Length() == 0)
                ar[i] = Default;
                else
                ar[i] = atoi(strTemp);
            }
        }
        else
        {
            wxString strTemp;
            strBuffer = wxString::Format("%d", ar[0]);
            for (int i = 1 ; i < nCount ; i++)
            {
                strTemp = wxString::Format("%d", ar[i]);
                //strBuffer.AppendChar(',');
                strBuffer = strBuffer + ",";
                strBuffer.Append(strTemp);
            }
            WriteString(strEntry, strBuffer, strSection);
        }
    }
}

    void CIni::SerGet(bool bGet, unsigned char *ar, int nCount, wxString strEntry, LPCSTR strSection/*=NULL*/

    , unsigned char Default/* = 0*/

)
{
    if (nCount > 0)
    {
        wxString strBuffer;
        if (bGet)
        {
            strBuffer = GetString(strEntry, "", strSection);
            wxString strTemp;
            int nOffset = 0;
            for (int i = 0 ; i < nCount ; i++)
            {
                nOffset = Parse(strBuffer, nOffset, strTemp);
                if (strTemp.Length() == 0)
                ar[i] = Default;
                else
                ar[i] = (unsigned char) atoi(strTemp);
            }
        }
        else
        {
            wxString strTemp;
            strBuffer = wxString::Format("%d", ar[0]);
            for (int i = 1 ; i < nCount ; i++)
            {
                strTemp = wxString::Format("%d", ar[i]);
                //strBuffer.AppendChar(',');
                strBuffer = strBuffer + ",";
                strBuffer.Append(strTemp);
            }
            WriteString(strEntry, strBuffer, strSection);
        }
    }
}

    void CIni::SerGet(bool bGet, short *ar, int nCount, wxString strEntry, LPCSTR strSection/*=NULL*/

    , int Default/* = 0*/

)
{
    if (nCount > 0)
    {
        wxString strBuffer;
        if (bGet)
        {
            strBuffer = GetString(strEntry, "", strSection);
            wxString strTemp;
            int nOffset = 0;
            for (int i = 0 ; i < nCount ; i++)
            {
                nOffset = Parse(strBuffer, nOffset, strTemp);
                if (strTemp.Length() == 0)
                ar[i] = Default;
                else
                ar[i] = (short) atoi(strTemp);
            }
        }
        else
        {
            wxString strTemp;
            strBuffer = wxString::Format("%d", ar[0]);
            for (int i = 1 ; i < nCount ; i++)
            {
                strTemp = wxString::Format("%d", ar[i]);
                //strBuffer.AppendChar(',');
                strBuffer = strBuffer + ",";
                strBuffer.Append(strTemp);
            }
            WriteString(strEntry, strBuffer, strSection);
        }
    }
}

    void CIni::SerGet(bool bGet, DWORD *ar, int nCount, wxString strEntry, LPCSTR strSection/*=NULL*/

    , DWORD Default/* = 0*/

)
{
    if (nCount > 0)
    {
        wxString strBuffer;
        if (bGet)
        {
            strBuffer = GetString(strEntry, "", strSection);
            wxString strTemp;
            int nOffset = 0;
            for (int i = 0 ; i < nCount ; i++)
            {
                nOffset = Parse(strBuffer, nOffset, strTemp);
                if (strTemp.Length() == 0)
                ar[i] = Default;
                else
                ar[i] = (DWORD) atoi(strTemp);
            }
        }
        else
        {
            wxString strTemp;
            strBuffer = wxString::Format("%d", ar[0]);
            for (int i = 1 ; i < nCount ; i++)
            {
                strTemp = wxString::Format("%d", ar[i]);
                //strBuffer.AppendChar(',');
                strBuffer = strBuffer + ",";
                strBuffer.Append(strTemp);
            }
            WriteString(strEntry, strBuffer, strSection);
        }
    }
}

    void CIni::SerGet(bool bGet, WORD *ar, int nCount, wxString strEntry, LPCSTR strSection/*=NULL*/

    , DWORD Default/* = 0*/

)
{
    if (nCount > 0)
    {
        wxString strBuffer;
        if (bGet)
        {
            strBuffer = GetString(strEntry, "", strSection);
            wxString strTemp;
            int nOffset = 0;
            for (int i = 0 ; i < nCount ; i++)
            {
                nOffset = Parse(strBuffer, nOffset, strTemp);
                if (strTemp.Length() == 0)
                ar[i] = Default;
                else
                ar[i] = (WORD) atoi(strTemp);
            }
        }
        else
        {
            wxString strTemp;
            strBuffer = wxString::Format("%d", ar[0]);
            for (int i = 1 ; i < nCount ; i++)
            {
                strTemp = wxString::Format("%d", ar[i]);
                //				strBuffer.AppendChar(',');
                strBuffer = strBuffer + ",";
                strBuffer.Append(strTemp);
            }
            WriteString(strEntry, strBuffer, strSection);
        }
    }
}

    void CIni::SerGet(bool bGet, wxPoint *ar, int nCount, wxString strEntry, LPCSTR strSection/*=NULL*/

    , wxPoint Default/* = wxPoint(0,0)*/

)
{
    wxString strBuffer;
    for (int i = 0 ; i < nCount ; i++)
    {
        strBuffer = wxString::Format("_%i", i);
        strBuffer = strEntry + strBuffer;
        SerGet(bGet, ar[i], strBuffer, strSection, Default);
    }
}

    void CIni::SerGet(bool bGet, wxRect *ar, int nCount, wxString strEntry, LPCSTR strSection/*=NULL*/

    , wxRect Default/* = wxRect(0,0,0,0)*/

)
{
    wxString strBuffer;
    for (int i = 0 ; i < nCount ; i++)
    {
        strBuffer = wxString::Format("_%i", i);
        strBuffer = strEntry + strBuffer;
        SerGet(bGet, ar[i], strBuffer, strSection, Default);
    }
}

int CIni::Parse(wxString &strIn, int nOffset, wxString &strOut)
{
    strOut.Clear();
    int nLength = strIn.Length();
    if (nOffset < nLength)
    {
        if (nOffset != 0 &&strIn.GetChar(nOffset) == ',')
        nOffset++;
        while (nOffset < nLength)
        {
            if (!isspace(strIn.GetChar(nOffset)))
            break;
            nOffset++;
        }
        while (nOffset < nLength)
        {
            strOut += strIn.GetChar(nOffset);
            if (strIn.GetChar(++nOffset) == ',')
            break;
        }
        strOut.Trim();
    }
    return nOffset;
}

void GetPrivateProfileString(const wxChar *a0, const wxChar *a, const wxChar *b, wxChar *ret, long len, const wxChar *name)
{
    printf("todo. gpps\n");
}

//////////////////////////////////////////////////////////////////////
// statische Methoden
//////////////////////////////////////////////////////////////////////
wxString CIni::Read(wxString const &strFileName, wxString const &strSection, wxString const &strEntry, wxString const &strDefault)
{
    wxString strReturn;
    GetPrivateProfileString(strSection,
    strEntry,
    strDefault,
    //.GetBufferSetLength(MAX_INI_BUFFER),:
    (wxChar *) strReturn.GetData(),
    MAX_INI_BUFFER,
    strFileName);
    //strReturn.ReleaseBuffer();
    return strReturn;
}

void CIni::Write(wxString const &strFileName, wxString const &strSection, wxString const &strEntry, wxString const &strValue)
{
    WritePrivateProfileString(strSection,
    strEntry,
    strValue,
    strFileName);
}

