package j3deditor.bin.editor;

import j3deditor.bin.util.BackgroundTask;

import j3deditor.bin.util.BackgroundThread;

import java.awt.Dimension;
import java.awt.Image;
import java.awt.image.BufferedImage;


/**
 * Utility that updates the image of a <code>Scene2D</code>
 * in another low priority thread.
 * 
 * @author Risto Seene
 */
public class SceneBuffer implements BackgroundTask{

	/** currently usable image */
	private BufferedImage current;

	/** back buffer */
	private BufferedImage buffer;

	/** size of the image */
	private Dimension size;

	/** Scene2D which image this SceneBuffer updates */
	private Scene2D scene;


	/**
	 * Creates an instance of <code>SceneBuffer</code>
	 * which updates the image shown on the specified
	 * <code>Scene2D</code>.
	 * 
	 * @param scene
	 * 	<code>Scene2D</code> which image this <code>SceneBuffer</code> updates.
	 */
	public SceneBuffer(Scene2D scene){
		this.scene = scene;

		this.current = new BufferedImage(1, 1, BufferedImage.TYPE_INT_RGB);
		this.buffer = new BufferedImage(1, 1, BufferedImage.TYPE_INT_RGB);
	          this.updateSize(scene.getSize());
	}


	/**
	 * Schedules this image to updation.
	 */
	protected void updateImage(){
		BackgroundThread.executeOnce(this);
	}


	/**
	 * Returns the image of the valid buffer.
	 * 
	 * @return the image of the valid buffer
	 */
	public Image getImage(){
		this.updateSize(this.scene.getSize());

		return current;
	}


	/**
	 * Redraws the scene if the size of the
	 * image has been changed.
	 * 
	 * @param size
	 * 	new size of the image
	 */
	private void updateSize(Dimension size){
		if(this.size == null || this.size.getWidth() != size.getWidth() || this.size.getHeight() != size.getHeight()){
			if(size.getWidth() < 1 || size.getHeight() < 1){
				size.setSize(1, 1);
			}
			this.size = size;
			this.updateImage();
		}
	}


	/**
	 * Draws the scene into the backbuffer.
	 * After that flips the buffers and updates the <code>Scene2D</code>.
	 */
	public void process(){
		if(buffer.getWidth() != size.getWidth() || buffer.getHeight() != size.getHeight()){
	                    this.buffer = new BufferedImage((int)(this.size.getWidth()), (int)(this.size.getHeight()), BufferedImage.TYPE_INT_RGB);
	          }
	          scene.paintContent(this.buffer.getGraphics());
	          BufferedImage tmp = this.current;
	          this.current = this.buffer;
	          this.buffer = tmp;
	          this.scene.repaint();
	}

}
