#include "MyEntityManager.h"
#include "main.h"
#include "Entity.h"


MyEntityManager::MyEntityManager()
{
}

MyEntityManager::~MyEntityManager()
{
    Kill();
}

void MyEntityManager::Add(Entity *pEnt)
{

     m_Entities.push_back(pEnt);
}

bool MyEntityManager::Init()
{
    Kill();
    
    return true;
}

bool MyEntityManager::TagEntityForDeletionByName(std::string name)
{
    
    assert("Fix this");

   // if (!pEnt) return false;

   // pEnt->SetDeleteFlag(true);
    return true;
}

Entity * MyEntityManager::TouchedEntity(int entType, CL_Vector2 vPos, int radius)
{
    
    CL_Vector2 entPos;

    std::list<Entity*>::const_iterator ent = m_Entities.begin();
    for (ent; ent != m_Entities.end(); ++ent)
    {
        if (entType == C_TYPE_ANY || (entType == (*ent)->GetType()))
        {
            entPos =  (*ent)->m_vPosition;
        
            if ( (entPos-vPos).length() < radius+(*ent)->GetRadius())
            {
                return (*ent); //found a hit
            }
        }


    }

 return NULL; //no collision
}

void MyEntityManager::Kill()
{
    std::list<Entity*>::iterator it = m_Entities.begin();
    for (it; it != m_Entities.end(); ++it)
    {
               delete *it;
    }
    m_Entities.clear();
}

void MyEntityManager::Render()
{
    std::list<Entity*>::const_iterator ent = m_Entities.begin();
    for (ent; ent != m_Entities.end(); ++ent)
    {
        {
            (*ent)->Render();
        }
    }
    
}

void MyEntityManager::OnMessage(Message &msg)
{
    std::list<Entity*>::const_iterator ent = m_Entities.begin();
    for (ent; ent != m_Entities.end(); ++ent)
    {
        {
            (*ent)->OnMessage(msg);
        }
    }
    
}


void MyEntityManager::RemoveEntitiesTaggedForDeletion()
{
    //remove anything that was tagged for deletion
    
    std::list<Entity*>::iterator ent = m_Entities.begin();
    for (ent; ent != m_Entities.end(); ++ent)
    {
        {
            if ((*ent)->GetDeleteFlag()) 
            {
                   //actually delete it
                delete *ent;
                ent = m_Entities.erase(ent);
            }
        }
    }

}


template<> bool 
std::greater<Entity*>::operator()(Entity* const &x, Entity* const &y) const
{
    return x->GetSort() < y->GetSort();  //don't worry, these will get inlined
} 



void MyEntityManager::ProcessSortRequests()
{
    m_Entities.sort(std::greater<Entity*>());
}




void MyEntityManager::Update(float step)
{
    std::list<Entity*>::const_iterator ent = m_Entities.begin();
    for (ent; ent != m_Entities.end(); ++ent)
    {
        {
            (*ent)->Update(step);
        }
    }
    
    
    RemoveEntitiesTaggedForDeletion();
    ProcessSortRequests();
}
