package projectzombie.entity.particle;

import gl_engine.MathHelpers;
import gl_engine.texture.TextureRef3D;
import gl_engine.vec.Vec2d;
import gl_engine.vec.Vec3d;
import projectzombie.entity.Entity;
import projectzombie.entity.EntityParticle;
import projectzombie.entity.EntityParticlePart;
import projectzombie.init.Models;
import projectzombie.world.chunk.Chunk;
import projectzombie.world.layer.Layer;

public class ParticleSmokeTrail extends EntityParticle
{
	protected class SmokeTrail extends EntityParticlePart
	{
		Vec3d velocity;
		int time;
		
		SmokeTrail(TextureRef3D tex, Vec3d pos, Vec3d velocity) {
			super(tex, pos.add(new Vec3d(0, 0.5, 0)), 0, 0b1000);
			
			time = 500;
			
			this.velocity = velocity;
		}
		
		boolean isDead() {
			return time <= 0;
		}
		
		void update()
		{
			if(time <= 0) {
				return;
			}
			
			time -= 1;
			pos = pos.add(velocity);
			size = time / 10000.0;
		}
		
		@Override
		public double getFade() {
			return 0.5;
		}
	}
	
	private Entity parent;
	private int dead;
	
	private boolean generating_particles = true;
	private SmokeTrail[] particles;
	
	public ParticleSmokeTrail(Entity parent) {
		this(parent, 1000);
	}
	
	private ParticleSmokeTrail(Entity parent, int size) {
		super(parent.getPos(), new Vec3d(0, 0, 0));
		
		dead = size;
		particles = new SmokeTrail[size];
		
		this.parent = parent;
	}
	
	@Override
	public void tick(Chunk chunk, Layer layer) {
		super.tick(chunk, layer);
		
		setPos(parent.getPos());
		
		Vec3d wind = layer.layergen.getWind(layer, getPos().xz());
		
		for(int i=0;i<particles.length;i++)
		{
			if(particles[i] == null) {
				continue;
			}
			
			if(particles[i].isDead()) {
				particles[i] = null;
				dead += 1;
				continue;
			}
			
			particles[i].update();
		}
		
		if(!generating_particles) {
			return;
		}
		
		for(int i=0;i<particles.length;i++) {
			if(particles[i] == null)
			{
				int[] tex_id = {0};
				TextureRef3D tex = Models.PARTICLE_SMOKE_TRAIL.getRandomChunk(tex_id);
				
				particles[i] = new SmokeTrail(tex, parent.getPos().copy(),
						parent.getVelocity().add(MathHelpers.moveTowards3(0.01, new Vec2d(
								rand.nextDouble() * MathHelpers.TWO_PI,
								rand.nextDouble() * MathHelpers.PI - MathHelpers.HALF_PI)))
						.add(wind).multiply(0.5));
				
				dead -= 1;
				
				break;
			}
		}
	}
	
	public void stopParticles() {
		generating_particles = false;
	}

	public boolean noMoreParticles() {
		return dead == particles.length;
	}

	@Override
	public int getParticleCount() {
		return particles.length;
	}

	@Override
	public EntityParticlePart getParticleAt(int id) {
		return particles[id];
	}

}
