module br.blast;

private import std.math;
private import opengl;
private import util.log;

public class Blast{
	public real x,y;
	public real width ,height;
	public real scale;
	public int count;
	public int span;
	public real R ,G ,B;
	public double alpha;
	private bool _exists;
	
	public this(real x,real y,real width ,real height ,int span ,real R ,real G ,real B ,real alpha){
		this.x = x;
		this.y = y;
		this.width = width;
		this.height = height;
		this.span = span;
		this.scale = 1.0;
		this.count = 0;
		this.R = R; this.G = G; this.B = B;
		this.alpha = alpha;
		this._exists = true;
		blastManager.add(this);
	}
	
	
	public void run(){
//		Log_write("dddd");
		
		if(span - 30 <= count){
			alpha *= 0.9;
			if(span <= count)vanish();
		}else scale *= 1.1;
		count ++;
	}
	
	public void draw(){
//		Log_write("vvvv");
		glPushMatrix();
		glEnable(GL_BLEND);
		
		glTranslatef(x ,y ,-800);
		
		glBegin(GL_POLYGON);
		
		glColor4f(R ,G ,B ,alpha);
		for(int i=0;i<32;i++){
			glVertex3f(scale * width * cos(cast(real)i / 32.0 * PI * 2.0) ,scale * height * sin(cast(real)i / 32.0 * PI * 2.0) ,0.0);
		}
		//glVertex3f(width ,height ,0.0);
		glEnd();
		
		glDisable(GL_BLEND);
		glPopMatrix();
	}
	
	public bool exists(){
		return _exists;
	}
	public void vanish(){
		_exists = false;
	}
}
public class Blast2:Blast{
	double baseAlpha;
	public this(real x,real y,real width ,real height ,int span ,real R ,real G ,real B ,real alpha){
		super(x ,y ,width ,height ,span ,R ,G ,B ,alpha);
		this.baseAlpha = alpha;
	}
	public void run(){
		if(span - 120 <= count){
			alpha *= 0.98;
			if(span <= count)vanish();
		}else{
			scale *= 1.1;
			alpha = baseAlpha * (1.0 - cast(double)(span - 120 - count) / cast(double)(span - 120));
		}
		count ++;
		
	}
}
public class SmallBlast:Blast{
	private real targetScale;
	private real dScale;
	public this(real x,real y,real width ,real height ,real targetScale ,int span ,real R ,real G ,real B ,real alpha){
		super(x ,y ,width ,height ,span ,R ,G ,B ,alpha);
		this.targetScale = targetScale;
		this.dScale = (this.targetScale - this.scale) / (span * 2/ 3);
	}
	public void run(){
		if(span * 2 / 3<= count){
			scale = targetScale;
			alpha *= 0.9;
			if(span <= count)vanish();
		}else scale += dScale;
		count ++;
	}
}
public BlastManager blastManager;
public class BlastManager{
		public:
	Blast[] blasts;
	//List!(Parts) parts;
	protected:
	//List!(int) van = new List!(int)();
  int blastIdx = 0;
	const int maxBlast;
	public this() {
		maxBlast = 16;
		blasts.length = maxBlast;
		//parts = new List!(Parts)();
		blastIdx = 0;
	}

  public this(int n) {
		maxBlast = n;
		blasts.length = maxBlast;
		//parts = new List!(Parts)();
		blastIdx = 0;
  }

	public bool add(Blast a){
		for(int i = 0;i < blasts.length;i ++){
			if(blasts[blastIdx] is null || !blasts[blastIdx].exists()){
				blasts[blastIdx] = a;
				return true;
			}
			blastIdx ++;
			if(blasts.length <= blastIdx)blastIdx = 0;
		}
		return false;
		//if(maxParts <= parts.size)return false;
		//parts.push_back(p);
		
	}
	public void run() {
		
		for (int i = 0;i < blasts.length;i ++){
			Blast an = blasts[i];
      if (an !is null && an.exists){
				
        an.run();
				if(an.exists == false)an = null;
      }else{
				//van.push_back(i);
      }
    }
		
		
  }
  public void draw() {
		
		for (int i = 0;i < blasts.length;i ++){
			Blast an = blasts[i];
			if (an !is null && an.exists){
				an.draw();
			}
		}
  }


  public void clear() {
		foreach(inout Blast a;blasts){
			if(a !is null && a.exists){
				a.vanish();
			}
		}
   	//parts.length = 0;
    blastIdx = 0;
  }
}
	