#include "AbstractElement.h"

using namespace Framework;

ElementPath::ElementPath(RCArray<Text>* path)
    : ReferenceCounter(),
      path(path),
      index(0)
{}

ElementPath::~ElementPath() {}

bool Framework::ElementPath::isValid() const
{
    return index < path->getEintragAnzahl();
}

bool Framework::ElementPath::hasNext() const
{
    return index < path->getEintragAnzahl() - 1;
}

void Framework::ElementPath::next()
{
    index++;
}

bool Framework::ElementPath::isObjectAttribute() const
{
    return path->z(index)->hatAt(0, ".");
}

bool Framework::ElementPath::isArrayElement() const
{
    return path->z(index)->hatAt(0, "[");
}

int Framework::ElementPath::getArrayIndex() const
{
    Text result = path->z(index)->getText() + 1;
    return (int)result;
}

Text Framework::ElementPath::getObjectAttribute() const
{
    return path->z(index)->getText() + 1;
}

Text Framework::ElementPath::toString() const
{
    Text result = "value";
    for (Text* txt : *path)
    {
        result += *txt;
    }
    return result;
}

int Framework::ElementPath::getCurrentPathElementIndex() const
{
    return index;
}

void Framework::ElementPath::setCurrentPathElementIndex(int index)
{
    this->index = index;
}

ElementPathBuilder::ElementPathBuilder()
    : path(new RCArray<Text>())
{}

Framework::ElementPathBuilder::ElementPathBuilder(
    const ElementPathBuilder& other)
    : path(dynamic_cast<RCArray<Text>*>(path->getThis()))
{}

ElementPathBuilder::~ElementPathBuilder()
{
    path->release();
}

ElementPathBuilder& ElementPathBuilder::appendArrayElement(int index)
{
    path->add(new Text(Text("[") + Text(index) + "]"));
    return *this;
}

ElementPathBuilder& ElementPathBuilder::appendObjectElement(Text key)
{
    path->add(new Text(Text(".") + key));
    return *this;
}

ElementPathBuilder& ElementPathBuilder::prependArrayElement(int index)
{
    path->add(new Text(Text("[") + Text(index) + "]"), 0);
    return *this;
}

ElementPathBuilder& ElementPathBuilder::prependObjectElement(Text key)
{
    path->add(new Text(Text(".") + key), 0);
    return *this;
}

ElementPath* ElementPathBuilder::build()
{
    return new ElementPath(dynamic_cast<RCArray<Text>*>(path->getThis()));
}

ElementPathBuilder& Framework::ElementPathBuilder::operator=(
    const ElementPathBuilder& other)
{
    if (path) path->release();
    path = dynamic_cast<RCArray<Text>*>(other.path->getThis());
    return *this;
}
