/**
 *  Triangles
 *  Copyright (C) 2016 POSITIVE MENTAL ATTITUDE
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, version 3 of the License.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 
 /**
  * This is based on a wiki entry
  * https://github.com/SFML/SFML/wiki/Source:-Particle-System
  */

#include <sstream>
#include <cmath>
#include "Particle.hpp"

ParticleSystem::ParticleSystem(int width, int height):
	_origin(0, 0),
	_particleSpeed(20.f),
	_dissolutionRate(60.f),
	_enabled(true) 
{
	_colors.push_back(sf::Color::White);
	_image.create( width, height, sf::Color::Transparent);
	_texture.loadFromImage(_image);
	_sprite = sf::Sprite(_texture);
}

ParticleSystem::~ParticleSystem()
{
	for(auto it = _particles.begin(); it != _particles.end(); it++)
		delete *it;
}

void ParticleSystem::fuel(int particles, float angle)
{
	if(!_enabled)
		return;
		
	if(particles < 0)
		particles = -particles;
		
	if(_particles.size() > 40000)
		return;

	Particle* particle;
	for(int i = 0; i < particles; i++)
	{
		particle = new Particle();
		particle->pos.x = _origin.x;
		particle->pos.y = _origin.y;
		
		particle->vel.x = float((rand() % 30000 - 15000) / 1000.f);
		particle->vel.y = float((rand() % 30000 - 15000) / 1000.f);

		particle->color = _colors[rand() % _colors.size()];
		particle->transparency = 255.f;
		particle->color.a = sf::Uint8(particle->transparency);
		_particles.push_back(particle);
	}
}

void ParticleSystem::update(sf::Time delta)
{
	if(!_enabled)
		return;

	float time = delta.asSeconds();

	for(auto it = _particles.begin(); it != _particles.end(); it++ )
	{
        (*it)->pos.x += (*it)->vel.x * time * _particleSpeed;
	    (*it)->pos.y += (*it)->vel.y * time * _particleSpeed;

		(*it)->transparency -= (_dissolutionRate * time);
		(*it)->color.a = sf::Uint8((*it)->transparency);

		if((*it)->pos.x > _image.getSize().x || (*it)->pos.x < 0 || (*it)->pos.y > _image.getSize().y || (*it)->pos.y < 0 || (*it)->color.a < 10)
		{
            delete (*it);
		    it = _particles.erase(it);
		    if(it == _particles.end()) 
				return;
        }
	}
}

void ParticleSystem::render()
{
	if(!_enabled)
		return;

	for(auto it = _particles.begin(); it != _particles.end(); it++)
		_image.setPixel((int)(*it)->pos.x, (int)(*it)->pos.y, (*it)->color);
    _texture.update(_image);
}

void ParticleSystem::clear()
{
	if(!_enabled)
		return;
		
	for(auto it = _particles.begin(); it != _particles.end(); it++ )
		_image.setPixel( (int)(*it)->pos.x, (int)(*it)->pos.y, sf::Color::Transparent);
}

void ParticleSystem::draw(sf::RenderTarget& target, sf::RenderStates states) const
{
	target.draw(_sprite);
}