#include "aliens.h"
#include <cmath>

Aliens::Aliens(Map * map_, QObject *parent) :
    QObject(parent)
{
    map = map_;
    nextId = 1;
    m_missingAliens = 0;
}


void Aliens::addAlien(int srcId)
{
    if (srcId < 0 || srcId >= srcAliens.size())
    {
        qCritical("ERROR out of aliens range");
        return;
    }
    AlienType al;
    al.id = nextId;
    al.src = &(srcAliens[srcId]);
    al.finish = map->finishs().at(qrand()%map->finishs().size());
    al.pos = QPointF(map->starts().at(qrand()%map->starts().size()));
    al.path = map->createPath(al.pos.toPoint(),al.finish);
    al.pathIndex = 1;
    al.angle = 180.0f*(- std::atan2( al.pos.x() - al.path.at(al.pathIndex).x(),al.pos.y() - al.path.at(al.pathIndex).y()))/M_PI;
    if (al.path.isEmpty())
    {
        qCritical("ERROR create path");
        return; // FIXME: this
    }
    //qDebug() << al.path;
    al.health = al.src->health;
    al.speed = al.src->speed;
    al.item = new ADItem(al.id,ADItem::Alien,al.src->images,QRectF(-cellSize,-cellSize,cellSize*2,cellSize*2));
    al.item->setPos(al.pos*cellSize+QPointF(cellSize/2,cellSize/2));
    al.item->setRotation(al.angle);
    curAliens.insert(al.id,al);
    scene->addItem(al.item);
    nextId++;
}


void Aliens::retrace(bool * OK)
{
    map->removeAliensPath();
    for (QHash<int, AlienType>::iterator i = curAliens.begin(); i != curAliens.end(); ++i)
    {
        i->path = map->createPath(i->pos.toPoint(),i->finish);
        i->pathIndex = 1;
        if (i->path.isEmpty())
        {
            *OK = false;
            qDebug("Aliens retrace = false");
        }
    }
}


void Aliens::delAlien(int id, bool missed)
{
    emit alien_killed(id,missed);
    if (missed)
    {
        m_missingAliens++;
        qDebug() << tr("Missing aliens = %1!").arg(m_missingAliens);
    }
    scene->removeItem(curAliens[id].item);
    delete curAliens[id].item;
    curAliens.remove(id);
}


void Aliens::update()
{
    QList <int> missIndex;
    for (QHash<int, AlienType>::iterator i = curAliens.begin(); i != curAliens.end(); ++i)
    {
        float angl,arctg = 0;
        int curMiss = -1;
        while (distance2(i->pos, i->path.at(i->pathIndex)) < i->speed * i->speed)
        {
            i->pathIndex++;
            if (i->pathIndex >= i->path.size())
            {
                missIndex.push_back(i->id);
                curMiss = i->id;
                break;
            }
        }
        if (curMiss < 0)
        {
            // TODO: smooth rotate (how???)
            arctg = std::atan2(i->pos.x() - i->path.at(i->pathIndex).x(),i->pos.y() - i->path.at(i->pathIndex).y());
            angl = 180.0f*(-arctg)/M_PI;
            i->angle = angl;
            i->pos.rx() -= i->speed*std::sin(arctg);
            i->pos.ry() -= i->speed*std::cos(arctg);
        }
        i->item->setPos(i->pos*cellSize+QPointF(cellSize/2,cellSize/2));
        i->item->setRotation(i->angle);
        i->item->setBarValue(i->health/i->src->health);
        i->item->next(i->speed*cellSize);
    }
    for (int j=0; j<missIndex.size(); j++)
    {
        delAlien(missIndex.at(j),true);
    }
}
