import de.grogra.imp3d.*;
import de.grogra.ray2.tracing.*;
import de.grogra.rgg.*;
import de.grogra.imp.*;
import de.grogra.math.*;
import de.grogra.vecmath.*;
import de.grogra.vecmath.geom.*;
import de.grogra.imp3d.ray2.*;
import de.grogra.pf.registry.expr.*;
import de.grogra.pf.registry.Item;
import de.grogra.util.*;
import de.grogra.pf.ui.util.*;
import java.awt.image.*;
import java.awt.*;
import java.io.*;
import javax.vecmath.*;
import de.grogra.imp3d.objects.*;

public abstract class Billboarder extends Library {
	
	protected RotationCamera camera;
	protected View3D view3d;
	protected double RotationAngle		= 0;
	protected Point3d CamPos			= new Point3d(0,0,8);
	protected TVector3d rotationPoint	= new TVector3d(0,0,0);
	
	protected String pathAndFileName	= "";
	protected String targetFolder		= "C:/Bachlor-Arbeit/Arbeit/Anhaenge/Billboards/";
	protected String targetFileTmpl		= "bill_";
	protected String fileExt			= ".png";	
	
	protected int imgWidth				= 0;
	protected int imgHeight				= 0;
		
	protected String vrmlBB				= "";
	
	protected int sides					= 1;
	protected int currentSide			= 0;
	
	protected LockProtectedCommand lpc;
	
	public void initialize(double distance, double zOfsset, int sides)
	{
		this.sides					= sides;
		RotationAngle				= Math.round(360/sides);
		
		camera.setDim(distance, zOfsset);
		//cake();
	}
		
	public void beginAt(int side)
	{
		if(side < sides && side > 0)
		{
			currentSide = side;
		}
	}
	
	/** 
	  * This method rendered each side of an object given in the view. The number
	  * of sides was set by invoke the initialize - method. After a render-step
	  * the camera will rotate arround the Y-axis and it will be start the next
	  * render-step.
	  */
	public void billboarding()
	{
		ObjectExpr objExpr	= (ObjectExpr) Item.resolveItem(Library.workbench(), "/renderers/3d/ray2");
		
		// Creates a new Renderer
		Raytracer raytracer	= (Raytracer) objExpr.evaluate(Library.workbench(), new StringMap());	

		// Add a new observer to the renderer. Cause we observe the view-panel and the image, wich will
		// be write to disk.s
		raytracer.addImageObserver(new ImageObserver() {
									
				public boolean imageUpdate(Image img, int infoflags, int x, int y, final int width, final int height) 
				{
					if ((infoflags & ALLBITS) == 0)
					{
						return true;
					} 
					
					if(imgWidth == 0)
						imgWidth	= width;
					
					if(imgHeight == 0)
						imgHeight	= height;
					// This writes the rendered image to Disk
					IMP.writeImage(view3d,(RenderedImage) img, new MimeType("image/png", null), new File(pathAndFileName));
					//currentSide++;
					// To receive information about the progress during rendering, we have to
					// invoke from main-thread the next render-task, because maybe we want to
					// render another side of view.
					view3d.getWorkbench().getJobManager().runLater(lpc, null, view3d, 0);
					
					// Return if image is ready (no more image updates => false)
					return false;
				}
			} 
		);
		//String filename	= ;
		// Starts the renderer
		
		view3d.getViewComponent().render((Renderer) raytracer);

	}	
	
	abstract protected void setRunLater();
	
}