package net.phatcode.rel.utils;

import java.awt.Graphics2D;
import net.phatcode.rel.Screen;
import net.phatcode.rel.assets.ImageTextureDataExplosion;
import net.phatcode.rel.math.Utils;
import net.phatcode.rel.math.Vector2D;

public class Explosion
{
	class Explode
	{
		public float x = 0;
		public float y = 0;
		public float dx = 0;
		public float dy = 0;
		public int baseFrame = 0;
		public int numFrames = 1;
		public int frame = 0;
		
		public int counter = 0;
		public boolean active = false;
		
		Explode()
		{
			
		}
		
		void update()
		{
			
			counter++;
			x += dx;
			y += dy; 
			if( (counter & 3) == 0 )
			{
				frame++;
			}
			
		}
		
	}
	private static Explosion instance = new Explosion();

	private ImageAtlas sprites = new ImageAtlas( new ImageTextureDataExplosion() );
	private LinkedArray<Explode> explosions = new LinkedArray<Explode>( 128, new Explode() );
	
	
	private Explosion()
	{
		int size = explosions.getSize();
		for( int i = 0; i < size; i++ )
		{
			explosions.set( i, new Explode() );
		}
		
	}
	
	public static Explosion getInstance()
	{
		return instance;
	}
	
	public void init()
	{
		
	}
	
	public void spawn( float x, float y, 
					   float angle, float speed,
					   int baseFrame, int numFrames )
	{
			Explode ex = explosions.getFreeElement();
			if( ex != null )
			{
				ex.x = x;
				ex.y = y;
				ex.dx = (float)Math.cos(angle) * speed;
				ex.dy = (float)Math.sin(angle) * speed;
				ex.baseFrame = baseFrame;
				ex.numFrames = numFrames;
				ex.frame = 0;
				ex.counter = 0;
				ex.active = true;
			}
	}
	
	public void spawn( Vector2D position, 
					   Vector2D direction,
					   float speed,
					   int baseFrame, int numFrames )
	{
		Explode ex = explosions.getFreeElement();
		if( ex != null )
		{
			ex.x = position.x;
			ex.y = position.y;
			ex.dx = direction.x * speed;
			ex.dy = direction.y * speed;
			ex.baseFrame = baseFrame;
			ex.numFrames = numFrames;
			ex.frame = 0;
			ex.counter = 0;
			ex.active = true;
		}
	}

	public void spawn( float x, float y, 
					   float angle, float speed,
					   int baseFrame, int numFrames,
					   int numSideExplosions )
	{
		for( int i = 0; i < numSideExplosions; i++ )
		{
			Explosion.getInstance().spawn( x, 
					   					   y, 
										   angle + (2 * Utils.PI * i) / (float)numSideExplosions,
										   speed, 
										   baseFrame, numFrames );	
			
		}
		
	}

	public void updateAll()
	{
		int size = explosions.getSize();
		for( int i = 0; i < size; i++ )
		{
			Explode ex = explosions.get(i);
			if( ex.active )
			{
				ex.update();
				if( ex.frame >= ex.numFrames )
				{
					ex.active = false;
					explosions.remove(i);
				}
			}
		}
		
	}
	
	public void renderAll( Screen screen, Graphics2D g )
	{
		
		int size = explosions.getSize();
		for( int i = 0; i < size; i++ )
		{
			Explode ex = explosions.get(i);
			
			if( ex.active )
			{
				int frame = ex.frame + ex.baseFrame;
				g.drawImage( sprites.getSprite(frame), 
							 (int)ex.x - sprites.getSprite(frame).getWidth()/2,
							 (int)ex.y - sprites.getSprite(frame).getHeight()/2,
							 screen );
		
			}
			
		}

	}
	
	public int getActiveExplosions()
	{
		return explosions.getActiveElements();
	}

}
