package simogl.effect.particle;

import javax.media.opengl.GL;

import com.sun.opengl.util.texture.Texture;

import simogl.geometry.Point3D;
import simogl.util.Calc;

/**
 * This class represents a particle that uses the direct drawing technique.
 * @author Frank Bruns
 *
 */
public class DDParticle extends AbstractParticle
{

	/**
	 * Creates a new particle
	 * @param size size of the particle
	 * @param position particle's position
	 * @param velocity particle's velocity 
	 * @param maxAge maximum age the particle can reach (in miliseconds)
	 */
	public DDParticle(float size, Point3D position, Point3D velocity, long maxAge)
	{
		super(size,position,velocity,maxAge);
	}
	
	/**
	 * Creates a new particle
	 * @param posX x-coordinate
	 * @param posY y-coordinate
	 * @param posZ z-coordinate
	 * @param velX x-velocity
	 * @param velY y-velocity
	 * @param velZ z-velocity
	 * @param maxAge maximum age the particle can reach (in miliseconds)
	 */
	public DDParticle(float posX, float posY, float posZ, float velX, float velY, float velZ, long maxAge)
	{
		super(posX,posY,posZ,velX,velY,velZ,maxAge);
	}
	
	/**
	 * Draws the particle to the scene
	 * @param gl
	 * @param x x-coordinate
	 * @param y y-coordinate
	 * @param z z-coordinate
	 * @param texture texture to assign to the particle
	 */
	@Override
	public synchronized void draw(GL gl, float x, float y, float z, Texture texture)
	{
		// enable blending
		gl.glEnable(GL.GL_BLEND);
		gl.glDepthMask(false);
		
		// use this blending function to achieve a fading effect
		//gl.glBlendFunc(GL.GL_SRC_ALPHA, GL.GL_ONE);
		
		
		// use this blending to function to make the black parts
		// of the texture transparent
		gl.glBlendFunc(GL.GL_DST_ALPHA, GL.GL_ONE_MINUS_SRC_COLOR);
		
		// apply texture		
		if(texture != null)
		{				
			texture.enable();			
			texture.bind();
		}		
		else gl.glDisable(GL.GL_TEXTURE_2D);	
		
		gl.glPushMatrix();
			// get the effect to the specified position
			gl.glTranslatef(x+this.position.getX(),
					y+this.position.getY(),
					z+this.position.getZ());
			Calc.billboardCylindricalBegin(gl);
			
			gl.glBegin(GL.GL_TRIANGLES);
				gl.glMaterialfv(GL.GL_FRONT_AND_BACK, GL.GL_AMBIENT_AND_DIFFUSE, this.color,0);
				gl.glNormal3fv(face.getTriangle1().getNormal().getPoint(),0);
				gl.glTexCoord2f(this.face.getTriangle1().getTexCoordVertex1().getS(),
						this.face.getTriangle1().getTexCoordVertex1().getT());
				gl.glVertex3fv(this.face.getTriangle1().getVertex1().getPoint(),0);
				
				gl.glTexCoord2f(this.face.getTriangle1().getTexCoordVertex2().getS(),
						this.face.getTriangle1().getTexCoordVertex2().getT());
				gl.glVertex3fv(this.face.getTriangle1().getVertex2().getPoint(),0);
				
				gl.glTexCoord2f(this.face.getTriangle1().getTexCoordVertex3().getS(),
						this.face.getTriangle1().getTexCoordVertex3().getT());
				gl.glVertex3fv(this.face.getTriangle1().getVertex3().getPoint(),0);
					
				
				gl.glNormal3fv(face.getTriangle2().getNormal().getPoint(),0);
				gl.glTexCoord2f(this.face.getTriangle2().getTexCoordVertex1().getS(),
						this.face.getTriangle2().getTexCoordVertex1().getT());
				gl.glVertex3fv(this.face.getTriangle2().getVertex1().getPoint(),0);;
				
				gl.glTexCoord2f(this.face.getTriangle2().getTexCoordVertex2().getS(),
						this.face.getTriangle2().getTexCoordVertex2().getT());
				gl.glVertex3fv(this.face.getTriangle2().getVertex2().getPoint(),0);;
				
				gl.glTexCoord2f(this.face.getTriangle2().getTexCoordVertex3().getS(),
						this.face.getTriangle2().getTexCoordVertex3().getT());
				gl.glVertex3fv(this.face.getTriangle2().getVertex3().getPoint(),0);;
			gl.glEnd();
			
			Calc.billboardEnd(gl);
		gl.glPopMatrix();		
		
		// disable blendig again
		gl.glDisable(GL.GL_BLEND);
		gl.glDepthMask(true);
	}

}
