package org.cocos2d.include;

import org.cocos2d.include.ccTypes.ccBlendFunc;
import org.cocos2d.include.ccTypes.ccColor3B;
import org.cocos2d.textures.CCTexture2D;

public interface CCProtocols {

	/**
	 * RGBA protocol that affects CCNode's color and opacity
	 */
	public interface CCRGBAProtocol {
		/** 
		 * Changes the color with R,G,B bytes
		 *
		 * @param color Example: ccc3(255,100,0) means R=255, G=100, B=0
		 */
		public void setColor(final ccColor3B color);

		/**
		 * Returns color that is currently used.
		 *
		 * @return The ccColor3B contains R,G,B bytes.
		 */
		public ccColor3B getColor();

		/**
		 * Returns the displayed color.
		 *
		 * @return The ccColor3B contains R,G,B bytes.
		 */
		public ccColor3B getDisplayedColor();

		/**
		 * Returns the displayed opacity.
		 *
		 * @return  The opacity of sprite, from 0 ~ 255
		 */
		public int getDisplayedOpacity();

		/**
		 * Returns the opacity.
		 *
		 * The opacity which indicates how transparent or opaque this node is.
		 * 0 indicates fully transparent and 255 is fully opaque.
		 *
		 * @return  The opacity of sprite, from 0 ~ 255
		 */
		public int getOpacity();

		/**
		 * Changes the opacity.
		 *
		 * @param   value   Goes from 0 to 255, where 255 means fully opaque and 0 means fully transparent.
		 */
		public void setOpacity(int opacity);

		// optional

		/**
		 * Changes the OpacityModifyRGB property.
		 * If thie property is set to true, then the rendered color will be affected by opacity.
		 * Normally, r = r * opacity/255, g = g * opacity/255, b = b * opacity/255.
		 *
		 * @param   bValue	true then the opacity will be applied as: glColor(R,G,B,opacity);
		 * 					false then the opacity will be applied as: glColor(opacity, opacity, opacity, opacity);
		 */
		public void setOpacityModifyRGB(boolean bValue);

		/**
		 * Returns whether or not the opacity will be applied using glColor(R,G,B,opacity) 
		 * or glColor(opacity, opacity, opacity, opacity)
		 *
		 * @return  Returns opacity modify flag.
		 */
		public boolean isOpacityModifyRGB();

		/**
		 *  whether or not color should be propagated to its children.
		 */
		public boolean isCascadeColorEnabled();
		public void setCascadeColorEnabled(boolean cascadeColorEnabled);

		/** 
		 *  recursive method that updates display color 
		 */
		public void updateDisplayedColor(final ccColor3B color);

		/** 
		 *  whether or not opacity should be propagated to its children.
		 */
		public boolean isCascadeOpacityEnabled();
		public void setCascadeOpacityEnabled(boolean cascadeOpacityEnabled);

		/**
		 *  recursive method that updates the displayed opacity.
		 */
		public void updateDisplayedOpacity(int opacity);
	}

	/**
	 * Specify the blending function according glBlendFunc
	 * Please refer to glBlendFunc in OpenGL ES Manual
	 * http://www.khronos.org/opengles/sdk/docs/man/xhtml/glBlendFunc.xml for more details.
	 */
	public interface CCBlendProtocol {
		/**
		 * Sets the source blending function.
		 *
		 * @param blendFunc A structure with source and destination factor to specify pixel arithmetic, 
		 * 					e.g. {GL_ONE, GL_ONE}, {GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA}.
		 *
		 */
		public void setBlendFunc(ccBlendFunc blendFunc);

		/**
		 * Returns the blending function that is currently being used.
		 * 
		 * @return A ccBlendFunc structure with source and destination factor which specified pixel arithmetic.
		 */
		public ccBlendFunc getBlendFunc();
	}

	/** 
	 * CCNode objects that uses a CCTexture2D to render the images.
	 * The texture can have a blending function.
	 * If the texture has alpha premultiplied the default blending function is:
	 *   src=GL_ONE dst= GL_ONE_MINUS_SRC_ALPHA
	 * else
	 *   src=GL_SRC_ALPHA dst= GL_ONE_MINUS_SRC_ALPHA
	 * But you can change the blending function at any time.
	 */
	public interface CCTextureProtocol extends CCBlendProtocol {
		/**
		 * Returns the currently used texture
		 *
		 * @return  The texture that is currenlty being used.
		 */
		public CCTexture2D getTexture();

		/**
		 * Sets a new texuture. It will be retained.
		 *
		 * @param   texture A valid CCTexture2D object, which will be applied to this sprite object.
		 */
		public void setTexture(CCTexture2D texture);
	}

	/**
	 * Common interface for Labels
	 */
	public interface CCLabelProtocol {
		/**
		 * Sets a new label using an string
		 *
		 * @param A null terminated string 
		 */
		public void setString(String label);

		/** 
		 * Returns the string that is currently being used in this label 
		 *
		 * @return The string that is currently being used in this label
		 */
		public String getString();
	}

	/** 
	 * OpenGL projection protocol 
	 */
	public interface CCDirectorDelegate {
		/** 
		 * Will be called by CCDirector when the projection is updated, and "custom" projection is used
		 */
		public void updateProjection();
	}

}
