#include "effect.h"
#include "collection.h"
#include "manager.h"
#include "emitter.h"

namespace render{
namespace fx{

effect::effect()
{
    running = 0;
    next = 0;
}

effect::~effect()
{
    for(auto &i: _objs)
        i.obj->stop();
    _objs.clear();
}


void effect::start()
{
    running = 1;
    for(auto &i: _objs)
        i.obj->start();
}

void effect::stop()
{
    running = 0;
    for(auto &i: _objs)
        i.obj->stop();
    if(next)
    {
        effect *n = addManagedEffect(next->create()).get();
        n->pos = pos;
        n->start();
    }
}

void effect::terminate()
{
    running = 0;
    for(auto &i: _objs)
        i.obj->stop();
}

void effect::update()
{
    int runningCount = 0;

    for(objectRef &i: _objs) {
        i.obj->update();
        if(i.obj->_running)
            runningCount++;
        else if(looped && running)
            i.obj->start();
    }

    if(running && !runningCount)
    {
        if(next)
        {
            effect *n = addManagedEffect(next->create()).get();
            n->pos = pos;
            n->start();
        }
        running = 0;
    }
}

bool effect::isRunning()
{
    return running;
}

bool effect::hasAliveParticles()
{
    for(auto &i: _objs)
        if(emitter *em = dynamic_cast<emitter*>(i.obj))
            if(em->drawCount)
            {
                return true;
            }


    return false;
}

void effect::draw()
{
    for(auto &i: _objs) {
        i.obj->draw();
    }
}

effect *effectInfo::create() const
{
    effect *eff = new effect;
    eff->_objs.reserve(objects.size());
    for(auto &i: objects)
    {
        eff->_objs.emplace_back();
        auto &objRef = eff->_objs.back();
        objRef.obj = root->createObject(i.id, i.workTime, eff);
        objRef.workTime = i.workTime;
        i.position.math(&objRef.position);
        i.angle.math(&objRef.angle);
    }
    eff->looped = looped;
    if(!next.empty())
    {
        eff->next = root->getEffectDef(next);
    }


    return eff;
}

}}
