#include "context/EntityList.h"
#include "IllegalStateException.h"

TableFormatPtr EntityList::FORMAT_;

EntityList::EntityList()
{
}

EntityList::EntityList(DataTablePtr data)
{
    for (std::vector<DataRecordPtr>::iterator it=data->iteratorBegin(); it!=data->iteratorEnd(); ++it)
    {
        entities.push_back(EntityReferencePtr(new EntityReference((*it)->getString(FIELD_CONTEXT()), (*it)->getString(FIELD_ENTITY()))));
    }
}

EntityList::EntityList(const AgString & context, const AgString & entity)
{
    add(context, entity);
}

EntityList::EntityList(EntityReferencePtr ref)
{
    entities.push_back(ref);
}


TableFormatPtr EntityList::FORMAT()
{

    return FORMAT_;
}


bool EntityList::includes(EntityReferencePtr ref)
{
    return includes(ref->getContext(), ref->getEntity());
}

bool EntityList::includes(const AgString & context, const AgString & entity)
{
    for (std::list<EntityReferencePtr>::iterator ref=entities.begin(); ref!=entities.end(); ++ref) {
        if (((*ref)->getContext() == context) && ((*ref)->getEntity() == entity)) {
            return true;
        }
    }

    return false;
}

DataTablePtr EntityList::toDataTable()
{
    DataTablePtr tab = DataTablePtr(new DataTable(FORMAT()));

    for (std::list<EntityReferencePtr>::iterator ref=entities.begin(); ref!=entities.end(); ++ref) {
        tab->addRecord()->addString((*ref)->getContext()).addString((*ref)->getEntity());
    }

    return tab;
}

bool EntityList::isEmpty()
{
    return entities.empty();
}

void EntityList::add(const AgString & context, const AgString & entity)
{
    if (!includes(context, entity)) {
        add( EntityReferencePtr(new EntityReference(context, entity)) );
    }
}

void EntityList::add(EntityReferencePtr ref)
{
    if(!includes(ref)) {
        entities.push_back(ref);
    }
}

std::list<EntityReferencePtr>  EntityList::getEntities()
{
    return entities;
}

std::list<EntityReferencePtr>::iterator EntityList::iteratorBegin()
{
    return entities.begin();
}

std::list<EntityReferencePtr>::iterator EntityList::iteratorEnd()
{
    return entities.end();
}

AgString EntityList::toString()
{
    assert(0);
    return "";//entities->toString();
}

Cloneable* EntityList::clone()
{
    assert(0);
    //TODO: clone
//    try {
//        EntityList clone = (EntityList) super.clone();
//        clone.entities = new LinkedList();
//        for (EntityReference er : entities)
//        {
//        clone.entities.add(er.clone());
//        }
//        return clone;
//    } catch (CloneNotSupportedException ex) {
//        throw  IllegalStateException(ex->getMessage(), ex);
//    }
    return 0;
}

int EntityList::hashCode()
{
    assert(0);
    //int const prime = int(31);
    int result = int(1);
    //result = prime * result + ((entities == 0) ? int(0) : entities)->hashCode());
    return result;
}

bool EntityList::equals(EntityList *obj)
{
    assert(0);
    if (this == obj)
        return true;

    if (obj == 0)
        return false;

    //TODO: compare list
//    if(!entities)->equals(other)->entities)))
//        return false;

    return true;
}
