#include "InitFile.h"

#include "File.h"
#include "Text.h"

using namespace Framework;

// Contents of the InitFile class from InitFile.h
// Constructor
InitFile::InitFile()
    : ReferenceCounter(),
      pfad(new Text()),
      name(new RCArray<Text>()),
      wert(new RCArray<Text>())
{}

InitFile::InitFile(Text* pfad)
    : ReferenceCounter(),
      pfad(new Text()),
      name(new RCArray<Text>()),
      wert(new RCArray<Text>())
{
    setPfad(pfad);
}

InitFile::InitFile(const char* pfad)
    : ReferenceCounter(),
      pfad(new Text()),
      name(new RCArray<Text>()),
      wert(new RCArray<Text>())
{
    setPfad(pfad);
}

// Destructor
InitFile::~InitFile()
{
    pfad->release();
    name->release();
    wert->release();
}

// non-constant
void InitFile::setPfad(Text* pfad)
{
    this->pfad->setText(*pfad);
    pfad->release();
}

void InitFile::setPfad(const char* pfad)
{
    this->pfad->setText(pfad);
}

bool InitFile::load()
{
    File* dat = new File();
    dat->setFile(pfad->getText());
    if (!dat->open(File::Style::read))
    {
        dat->release();
        return 0;
    }
    removeAlle();
    Text* zeile = dat->readLine();
    while (zeile)
    {
        zeile->remove("\r\n");
        zeile->remove("\n");
        Text* n = zeile->getTeilText(0, zeile->positionOf('='));
        Text* w = zeile->getTeilText(zeile->positionOf('=') + 1);
        name->add(n);
        wert->add(w);
        zeile->release();
        zeile = dat->readLine();
    }
    dat->close();
    dat->release();
    return 1;
}

bool InitFile::addValue(Text* name, Text* wert)
{
    if (!valueExists(name->getText()))
    {
        this->name->add(new Text(name->getText()));
        this->wert->add(new Text(wert->getText()));
        name->release();
        wert->release();
        return 1;
    }
    name->release();
    wert->release();
    return 0;
}

bool InitFile::addValue(const char* name, const char* wert)
{
    return addValue(new Text(name), new Text(wert));
}

bool InitFile::setValue(Text* name, Text* wert)
{
    if (!valueExists(name->getText()))
    {
        name->release();
        wert->release();
        return 0;
    }
    auto n = this->name->begin();
    for (auto v = this->wert->begin(); v; v++, n++)
    {
        if (n->isEqual(name->getText()))
        {
            v->setText(wert->getText());
            name->release();
            wert->release();
            return 1;
        }
    }
    name->release();
    wert->release();
    return 0;
}

bool InitFile::setValue(const char* name, const char* wert)
{
    return setValue(new Text(name), new Text(wert));
}

bool InitFile::setValue(int num, Text* wert)
{
    bool result = setValue(num, wert->getText());
    wert->release();
    return result;
}

bool InitFile::setValue(int num, const char* wert)
{
    if (num >= name->getEntryCount()) return 0;
    this->wert->z(num)->setText(wert);
    return 1;
}

bool InitFile::removeValue(Text* name)
{
    bool result = removeValue(name->getText());
    name->release();
    return result;
}

bool InitFile::removeValue(const char* name)
{
    if (!valueExists(name)) return 0;
    for (int i = 0; i < wert->getEntryCount(); ++i)
    {
        if (this->name->z(i)->isEqual(name))
        {
            this->name->remove(i);
            this->wert->remove(i);
            return 1;
        }
    }
    return 0;
}

bool InitFile::removeValue(int num)
{
    if (num >= wert->getEntryCount()) return 0;
    this->name->remove(num);
    this->wert->remove(num);
    return 1;
}

void InitFile::removeAlle()
{
    while (wert->getEntryCount() > 0)
    {
        this->name->remove(0);
        this->wert->remove(0);
    }
}

bool InitFile::save()
{
    File* dat = new File();
    dat->setFile(pfad->getText());
    if (!dat->exists()) dat->create();
    if (!dat->open(File::Style::write))
    {
        dat->release();
        return 0;
    }
    auto n = name->begin();
    for (auto v = wert->begin(); v; v++, n++)
    {
        Text* zeile = new Text("");
        zeile->append(n->getText());
        zeile->append("=");
        zeile->append(v->getText());
        zeile->append("\n");
        dat->write(zeile->getText(), zeile->getLength());
        zeile->release();
    }
    dat->close();
    dat->release();
    return 1;
}

// constant
int InitFile::getValueCount() const
{
    return name->getEntryCount();
}

bool InitFile::valueExists(Text* name)
{
    bool result = valueExists(name->getText());
    name->release();
    return result;
}

bool InitFile::valueExists(const char* name)
{
    for (Text* n : *this->name)
    {
        if (n->isEqual(name)) return 1;
    }
    return 0;
}

int InitFile::getValueNumber(Text* name)
{
    int result = getValueNumber(name->getText());
    name->release();
    return result;
}

int InitFile::getValueNumber(const char* name)
{
    int i = 0;
    for (Text* n : *this->name)
    {
        if (n->isEqual(name)) return i;
    }
    return -1;
}

Text* InitFile::getValue(Text* name)
{
    Text* result = getValue(name->getText());
    name->release();
    return result;
}

Text* InitFile::getValue(const char* name)
{
    auto v = wert->begin();
    for (auto n = this->name->begin(); n; n++, v++)
    {
        if (n->isEqual(name)) return dynamic_cast<Text*>(v->getThis());
    }
    return 0;
}

Text* InitFile::getValue(int num)
{
    if (num >= name->getEntryCount()) return 0;
    return wert->get(num);
}

Text* InitFile::zValue(Text* name)
{
    Text* result = zValue(name->getText());
    name->release();
    return result;
}

Text* InitFile::zValue(const char* name)
{
    auto v = wert->begin();
    for (auto n = this->name->begin(); n; n++, v++)
    {
        if (n->isEqual(name)) return v;
    }
    return 0;
}

Text* InitFile::zValue(int num)
{
    if (num >= wert->getEntryCount()) return 0;
    return wert->z(num);
}

Text* InitFile::getName(int num)
{
    if (num >= name->getEntryCount()) return 0;
    return name->get(num);
}

Text* InitFile::zName(int num)
{
    if (num >= name->getEntryCount()) return 0;
    return name->z(num);
}

Text* InitFile::getPfad() const
{
    return dynamic_cast<Text*>(pfad->getThis());
}

Text* InitFile::zPfad() const
{
    return pfad;
}