package com.gamepatriot.androidframework.framework;

import java.util.ArrayList;

/**
 * An AndroidScreen implementation should behave as a collection of images and shapes that are organized in a display list so they can be renderered by an {@link AndroidRenderer}. 
 * Also, the interface implies a compensation for receiving broadcasted input commands ({@link #touchPress(int, int)} and {@link #touchRelease(int, int)}) and for providing a solution to time-step 
 * logic updating ({@link #update()}).
 * 
 * @author Pete Schmitz, May 9, 2013
 *
 */
public interface AndroidScreen {
	
	/** Activate all frame-by-frame actions of this AndroidScreen (Input, Update, Render). **/
	public void activate();
	
	/** Activate the renderer. Active by default. - An {@link AndroidRenderer} should only render the display of a screen that has an activated renderer. **/
	public void activateRender();
	
	/** Activate the updater. Active by default. - An {@link AndroidRenderer} should only do a time-step update a screen that has an activated updater. **/
	public void activateUpdater();
	
	/** Activate the inputter. Active by default. - An {@link AndroidRenderer} should only broadcast inputs to a screen that has an activated inputter. **/
	public void activateInputter();
	
	/** Deactivate all frame-by-frame actions of this screen (Input, Update, Render). **/
	public void deactivate();
	
	/** Deactivate the renderer. Active by default. - An {@link AndroidRenderer} should only render the display of a screen that has an activated renderer. **/
	public void deactivateRender();
	
	/** Deactivate the updater. Active by default. - An {@link AndroidRenderer} should only do a time-step update a screen that has an activated updater. **/
	public void deactivateUpdater();
	
	/** Deactivate the inputter. Active by default. - An {@link AndroidRenderer} should only broadcast inputs to a screen that has an activated inputter. **/
	public void deactivateInputter();
	
	/** Disable all frame-by-frame activity but remember which aspects (Inputer, Update, Render) were enabled before the call. Use {@link #resume()} to restore functionality. **/
	public void pause();
	
	/** Resume functionality to the screen that was previously halted due to a {@link #pause()} call. **/
	public void resume();
	
	/** Return the number of {@link AndroidImage}s this screen is a parent to. **/
	public int numImages();
	
	/** 
	 * Retrieve an image from this AndroidScreen's display list at the supplied index.
	 * @param $index	The index to retrieve the AndroidImage at.
	 * @return			The AndroidImage at the display list index; null if out of range.
	 */
	public AndroidImage getImageAt(int $index);
	
	/**
	 * Retrieve the index location of an image in this AndroidScreen's display list.
	 * @param $image	The image to find the display index for.
	 * @return			The index of the supplied AndroidImage in the AndroidScreen's display list; -1 if this screen isn't a parent of the supplied image or the image is null.
	 */
	public int getImageIndex(AndroidImage $image);
	
	/**
	 * Add an image to this AndroidScreen's display list.
	 * @param $image	Image to be added.
	 */
	public void addImage(AndroidImage $image);
	
	/**
	 * Add an image at the specified display list index.
	 * @param $index	The index position to add this image at.
	 * @param $image	The image to add.
	 */
	public void addImageAt(int $index, AndroidImage $image);
	
	/**
	 * Remove an image from this AndroidScren's display list.
	 * @param $image	The image to remove.
	 * @return			Whether or not the supplied image was a child of this screen and was removed.
	 */
	public boolean removeImage(AndroidImage $image);
	
	/**
	 * Remove an image at the specified display list index.
	 * @param $index	The index position to remove the image at.
	 * @return			The image that was successfully removed; null otherwise.
	 */
	public AndroidImage removeImageAt(int $index);
	
	/** (Read-only) Return a reference of the display list that contains images this screen is a parent of. **/
	public ArrayList<AndroidImage> getImages();
	
	/** Remove all images this screen is parenting. **/
	public void removeImages();
	
	/** Return the number of {@link AndroidShape}s this screen is parenting. **/
	public int numShapes();
	
	/** 
	 * Retrieve a shape from this AndroidScreen's display list at the supplied index.
	 * @param $index	The index to retrieve the AndroidShape at.
	 * @return			The AndroidShape at the display list index; null if out of range.
	 */
	public AndroidShape getShapeAt(int $index);
	
	/**
	 * Retrieve the index location of a shape in this AndroidScreen's display list.
	 * @param $shape	The shape to find the display index for.
	 * @return			The index of the supplied AndroidShape in the AndroidScreen's display list; -1 if this screen isn't a parent of the supplied shape or the shape is null.
	 */
	public int getShapeIndex(AndroidShape $shape);
	
	/**
	 * Add a shape to this AndroidScreen's display list.
	 * @param $shape	Shape to be added.
	 */
	public void addShape(AndroidShape $shape);
	
	/**
	 * Add a shape at the specified display list index.
	 * @param $index	The index position to add this shape at.
	 * @param $shape	The shape to add.
	 */
	public void addShapeAt(int $index, AndroidShape $shape);
	
	/**
	 * Remove a shape from this AndroidScren's display list.
	 * @param $shape	The shape to remove.
	 * @return			Whether or not the supplied shape was a child of this screen and was removed.
	 */
	public boolean removeShape(AndroidShape $shape);
	
	/**
	 * Remove a shape at the specified display list index.
	 * @param $index	The index position to remove the shape at.
	 * @return			The shape that was successfully removed; null otherwise.
	 */
	public AndroidShape removeShapeAt(int $index);
	
	/** (Read-only) Return a reference of the display list containing shapes this screen is parenting. **/
	public ArrayList<AndroidShape> getShapes();
	
	/** Remove all shapes this screen is parenting. **/
	public void removeShapes();
	
	/** Get the {@link AndroidMain} reference this class is using. **/
	public AndroidMain getMain();
	
	/** Get the {@link AndroidMusicHandler} reference this class is using. **/
	public AndroidMusicHandler getMusic();
	
	/** Get the {@link AndroidSoundHandler} reference this class is using. **/
	public AndroidSoundHandler getSound();
	
	/** Remove this screen from {@link AndroidMain}'s display listing. **/
	public void remove();
	
	/** Queue this screen to be added to {@link AndroidMain}'s display listing. **/
	public void add();
	
	
	
	/** Time-step function. Invoked every frame when childing an {@link AndroidMain} class and when this AndroidScreen has an activated updater ({@link #activateUpdater()}). **/
	public abstract void update();
	
	/** Called from a {@link AndroidMain} broadcasting when the back button is pressed on the device's UI. **/
	public abstract void onBackPressed();
	
	/** 
	 * Input release. Invoked when childing an {@link AndroidMain} class and when this AndroidScreen has an activated inputter ({@link #activateInputter()}).
	 * @param $x		The X-pixel position of the input.
	 * @param $y		The Y-pixel position of the input.
	 */
	public abstract void touchRelease(int $x, int $y);
	
	/** 
	 * Input press. Invoked when childing an {@link AndroidMain} class and when this AndroidScreen has an activated inputter ({@link #activateInputter()}).
	 * @param $x		The X-pixel position of the input.
	 * @param $y		The Y-pixel position of the input.
	 */
	public abstract void touchPress(int $x, int $y);
	
	/**
	 * Input movement. Invoked when childing an {@link AndroidMain} class and when this AndroidScreen has an activated inputter ({@link #activateInputter()}).
	 * @param $x		The X-pixel position of the input.
	 * @param $y		The Y-pixel position of the input.
	 */
	public abstract void touchMove(int $x, int $y);
	
	
	
}
