package com.gamepatriot.framework2d.implementation;

import com.gamepatriot.androidframework.framework.AndroidAnimationData;

/**
 * The AnimationData class organizes animation-frame reference points. It provides information about the frame's pixel-dimensions, the amount of frames it contains, 
 * and the style of playback used ({@link AnimationStyle}).
 * 
 * @see AndroidAnimationData
 * @author Pete Schmitz, May 8, 2013
 *
 */
public class AnimationData implements AndroidAnimationData {
	
	/** Flags to indicate which pattern the animation data should be sorted as. **/
	public static enum AnimationStyle{
		
		/** Build animation frames from top to bottom then moves right. **/
		VERTICAL, 
		
		/** Build animation frames from left to right then moves down. **/
		HORIZONTAL;
	}
	
	/** Default AnimationStyle to use when one isn't provided during a {@link #set(int, int, int, int)} call. **/
	public static AnimationStyle DEFAULT_ANIMATION_STYLE = AnimationStyle.HORIZONTAL;
	
	/** (Read-only) Pixel width-dimension of each frame to the animation. **/
	public int frameWidth;
	
	/** (Read-only) Pixel height-dimension of each frame to the animation. **/
	public int frameHeight;
	
	/** (Read-only) Amount of columns that are contained within the animation's spritesheet/bitmap. **/
	public int columns;
	
	/** (Read-only) Amount of rows that are contained within the animation's spritesheet/bitmap. **/
	public int rows;
	
	/** (Read-only) Total amount of frames (columns * rows) that are contained within the animation's spritesheet/bitmap. **/
	public int totalFrames;
	
	/** (Read-only) The playback behavior of this animation that determines what pattern the frames on the spritesheet will be sorted as. **/
	public AnimationStyle animationStyle;
	
	/** (Read-only) Array holding X-related positioning for each frame. **/
	public int[] frameX;
	
	/** (Read-only) Array holding Y-related positioning for each frame. **/
	public int[] frameY;
	
	/**
	 * Constructor - Assumes {@link #set(int, int, int, int) set() will be called after construction to build the animation data.
	 */
	public AnimationData(){
		
	}
	
	/**
	 * Constructor - Build initial AnimationData.
	 * @param $width				The total width of the bitmap/spritesheet.
	 * @param $height				The total height of the bitmap/spritesheet.
	 * @param $columns				The number of column cells contained within the bitmap/spritesheet.
	 * @param $rows					The number of row cells contained within the bitmap/spritesheet.
	 * @param $animationStyle		The build order for the animation in reference to cells contained in the bitmap/spritesheet (See {@link AnimationStyle}).
	 */
	public AnimationData(int $width, int $height, int $columns, int $rows, AnimationStyle $animationStyle){
		set($width, $height, $columns, $rows, $animationStyle);
	}
	
	@Override
	public void set(int $width, int $height, int $columns, int $rows) {
		set($width, $height, $columns, $rows, DEFAULT_ANIMATION_STYLE);
	}
	
	/** 
	 * Set animation information and build frame positions.
	 * 
	 * @param $width				The total width of the bitmap/spritesheet.
	 * @param $height				The total height of the bitmap/spritesheet.
	 * @param $columns				The number of column cells contained within the bitmap/spritesheet.
	 * @param $rows					The number of row cells contained within the bitmap/spritesheet.
	 * @param $animationStyle		The build order for the animation in reference to cells contained in the bitmap/spritesheet (See {@link AnimationData.AnimationStyle}).
	**/
	public void set(int $width, int $height, int $columns, int $rows, AnimationStyle $animationStyle) {
		frameWidth = $width/$columns;
		frameHeight = $height/$rows;
		columns = $columns;
		rows = $rows;
		animationStyle = $animationStyle;
		totalFrames = columns * rows;
		
		buildFrames();
	}
	
	/** Build animation frames based on defined properties within the AnimationData class. **/
	private void buildFrames(){
		frameX = new int[totalFrames];
		frameY = new int[totalFrames];
		
		//Build animation cell positions
		int $i;
		int $m;
		
		if (animationStyle == AnimationStyle.HORIZONTAL){
			//Left to right, then down
			for ($i = 0; $i < rows; $i++){
				for ($m = 0; $m < columns; $m++){
					frameX[$i * columns + $m] = $m * frameWidth;
					frameY[$i * columns + $m] = $i * frameHeight;
				}
			}
			
		} else if (animationStyle == AnimationStyle.VERTICAL){
			//Top to bottom, then right
			for ($i = 0; $i < columns; $i++){
				for ($m = 0; $m < rows; $m++){
					frameX[$i * rows + $m] = $i * frameWidth;
					frameY[$i * rows + $m] = $m * frameHeight;
				}
			}
		}
	}
	
	
}
