/**
* @(#)RotateTransition.java
* @version 1.51 04/06/97
* @author Robert Temple (robertt@starwave.com)
*/

import java.awt.image.MemoryImageSource;
import java.awt.*;
import java.lang.Math;

/**
* The RotateTransition class changes one image into another by making it
* appear as if one image is rotating upward from below the other image.
* it might appear as if the images are on a cube with the current image
* facing you, and the next image on the bottom of the cube, but slowly
* moving up to face you.
*/
public class RotateTransition extends BillTransition {
// Static Members
	/** 
	* The total number of cells this transition will show on the screen before
    * the new image is shown in its entirety
	*/
	final static int CELLS = 12;

// Instance Members

	/** the current angle at which the billboards are rotated at */
	double current_angle;

	/**
	* Used to initialize the transition right after it is created.
	* creates cells
	* @param owner the component to be used to create images from cells
	*/
	public void init(Component owner, int[] current, int[] next) {
		init(owner, current, next, CELLS, 180);

		double angle_increase = (Math.PI / 2.0d) * (1.0d / (double)(CELLS + 1));

		current_angle = angle_increase;
	
		for(int c = 0; c < CELLS; ++c) {

			// give other threads a shot at the CPU
			try { Thread.sleep(100); } catch (InterruptedException e) {}

			Rotate();

			// give other threads a shot at the CPU
			try { Thread.sleep(100); } catch (InterruptedException e) {}

			// create the new cell image from the work pixels
			createCellFromWorkPixels(c);

			current_angle += angle_increase;
		}

		// we don't need the work pixels anymore
		work_pixels = null;
	}

	/**
	* Create the next cell in the work pixel array
	*/
	final void Rotate() {
		// calculate the portion of the top billboard that can be seen
		double top_billboard_h = ((double)cell_h / 2d * 
					Math.sin(Math.PI / 2d - current_angle)) + 
					(double)cell_h / 2d;

		// calculate the portion of the bottom billboard that can be seen
		double bottom_billboard_h = ((double)cell_h / 2d * Math.sin(current_angle)) + (double)cell_h / 2d;

		// calculate the vertical location that the top billboard ends and the
		// next billboard starts
		int location = cell_h - (int)(bottom_billboard_h * Math.sin(current_angle));

		// calculate the vertical adder to determine the vertical position
		// to take pixels from the source image
		float adder = (float)top_billboard_h / (float)location;

		// the current vertical location on the source image to grab pixels from
		float position = (float)cell_h - (float)top_billboard_h + adder - 1f;

		// draw in the top billboard
		for(int y = 0; y < location; ++y) {
			
			System.arraycopy((Object)current_pixels, 
						(int)position * cell_w, (Object)work_pixels, 
						y * cell_w, cell_w);

			position += adder;
		}

		adder = (float)bottom_billboard_h / (float)(cell_h - location);
		position = 0f;

		// draw in the bottom billboard
		for(int y = location; y < cell_h; ++y) {

			System.arraycopy((Object)next_pixels, (int)position * cell_w,
						(Object)work_pixels, y * cell_w, cell_w);

			position += adder;
		}
	}
}


