#pragma once

#include <mutex>
#include "def.h"
#include "object.h"
#include "parameters.h"
#include "spawner.h"
#include "../render.h"
#include "../sprite/atlas.h"

namespace render{
namespace fx{

class emitter: public object
{
friend class effect;
friend class emitterInfo;
public:
    render::blendMode blend;

    emitter(effect*);
    ~emitter();

    void clear() noexcept;
    void update() noexcept;

    void start();
    void stop();

    void pushTextureNode(const std::string&);
    void setTextureAtlas(const std::string&);

    void getInfo(particlesUpdateInfo*) noexcept;

    emissionParam emission;
    particlesParam particles;
    bool lock();

    const uint32_t &drawCount;
protected:
    void _draw() noexcept;
private:
    effect *_root;
    const render::sprite::textureAtlas *_atlas;
    std::vector<vec4f> _texNodes;
    std::vector<textureAnimationInfo> _animation;
    vec2f _xpos;
    vec2f _pos;
    vec2f _oldPos;
    uint32_t _drawCount, _updatedCount;
    std::vector<particleData> _data;
    std::vector<particle> _rdata[2];
    std::vector<particle> *_front, *_back;
    std::mutex _locker;
    float _spawnCount;
    bool _updated;
};

class emitterInfo: public objectInfo
{
public:
    float workTime;
    render::blendMode blend;
    uint32_t maxParticles;
    std::string texAtlas;
    std::vector<std::string> texNodes;
    std::vector<textureAnimationInfo> animation;
    _emitterParam<vec2f> lifeTime;
    _emitterParam<float> emission;
    _emitterParam<vec2f> direction;
    _emitterParam<float> angle;
    _emitterParam<float> speed;
    _emitterParam<float> alpha;
    _emitterParam<vec2f> scale;
    _emitterParam<vec3f> color;

    particleSpawnerInfo *spawnerInfo;
    virtual object *create(float, effect*);
    emitterInfo();
    ~emitterInfo();
};

}}
