package org.cocos2d.layers_scenes_transitions_nodes;

import org.cocos2d.include.CCProtocols.CCRGBAProtocol;
import org.cocos2d.include.ccTypes.ccColor3B;

/**
 * @addtogroup layer
 * @{
 */

/** CCLayerRGBA is a subclass of CCLayer that implements the CCRGBAProtocol protocol using a solid color as the background.
 * 
 * All features from CCLayer are valid, plus the following new features that propagate into children that conform to the CCRGBAProtocol:
 * - opacity
 * - RGB colors
 * @since 2.1
 */
public class CCLayerRGBA extends CCLayer implements CCRGBAProtocol {

	public static CCLayerRGBA create() {
		CCLayerRGBA pRet = new CCLayerRGBA();
		if(! pRet.init()) {
			pRet = null;
		}
		return pRet;
	}

	public CCLayerRGBA() {
		_displayedOpacity = 255;
		_realOpacity = 255;
		_displayedColor.set(ccColor3B.ccWHITE);
		_realColor.set(ccColor3B.ccWHITE);
		_cascadeOpacityEnabled = false;
		_cascadeColorEnabled = false;
	}

	@Override
	public boolean init() {
		if(super.init()) {
			_displayedOpacity = _realOpacity = 255;
			_displayedColor.set(ccColor3B.ccWHITE);
			_realColor.set(ccColor3B.ccWHITE);
			setCascadeOpacityEnabled(false);
			setCascadeColorEnabled(false);

			return true;
		} else {
			return false;
		}
	}

	@Override
	public int getOpacity() {
		return _realOpacity;
	}

	@Override
	public int getDisplayedOpacity() {
		return _displayedOpacity;
	}

	@Override
	public void setOpacity(int opacity) {
		_displayedOpacity = _realOpacity = opacity;

		if(_cascadeOpacityEnabled) {
			int parentOpacity = 255;
			CCRGBAProtocol parent = (CCRGBAProtocol)m_pParent;
			if((parent != null) && parent.isCascadeOpacityEnabled()) {
				parentOpacity = parent.getDisplayedOpacity();
			}
			updateDisplayedOpacity(parentOpacity);
		}
	}

	@Override
	public void updateDisplayedOpacity(int parentOpacity) {
		_displayedOpacity = (int)(_realOpacity * parentOpacity/255.0);

		if(_cascadeOpacityEnabled) {
			for(Object obj : m_pChildren) {
				CCRGBAProtocol item = (CCRGBAProtocol)obj;
				if(item != null) {
					item.updateDisplayedOpacity(_displayedOpacity);
				}
			}
		}
	}

	@Override
	public boolean isCascadeOpacityEnabled() {
		return _cascadeOpacityEnabled;
	}

	@Override
	public void setCascadeOpacityEnabled(boolean cascadeOpacityEnabled) {
		_cascadeOpacityEnabled = cascadeOpacityEnabled;
	}

	@Override
	public ccColor3B getColor() {
		return _realColor;
	}

	@Override
	public ccColor3B getDisplayedColor() {
		return _displayedColor;
	}

	@Override
	public void setColor(final ccColor3B color) {
		_displayedColor.set(color);
		_realColor.set(color);

		if(_cascadeColorEnabled) {
			ccColor3B parentColor = ccColor3B.ccWHITE;
			CCRGBAProtocol parent = (CCRGBAProtocol)m_pParent;
			if((parent != null) && parent.isCascadeColorEnabled()) {
				parentColor = parent.getDisplayedColor();
			}

			updateDisplayedColor(parentColor);
		}
	}

	@Override
	public void updateDisplayedColor(final ccColor3B parentColor) {
		_displayedColor.r = (int)(_realColor.r * parentColor.r/255.0);
		_displayedColor.g = (int)(_realColor.g * parentColor.g/255.0);
		_displayedColor.b = (int)(_realColor.b * parentColor.b/255.0);

		if(_cascadeColorEnabled) {
			for(Object obj : m_pChildren) {
				CCRGBAProtocol item = (CCRGBAProtocol)obj;
				if(item != null) {
					item.updateDisplayedColor(_displayedColor);
				}
			}
		}
	}

	@Override
	public boolean isCascadeColorEnabled() {
		return _cascadeColorEnabled;
	}

	@Override
	public void setCascadeColorEnabled(boolean cascadeColorEnabled) {
		_cascadeColorEnabled = cascadeColorEnabled;
	}

	@Override
	public void setOpacityModifyRGB(boolean bValue) {
	}

	@Override
	public boolean isOpacityModifyRGB() {
		return false;
	}

	protected int _displayedOpacity, _realOpacity;
	protected ccColor3B _displayedColor = new ccColor3B();
	protected ccColor3B _realColor = new ccColor3B();
	protected boolean _cascadeOpacityEnabled, _cascadeColorEnabled;
}

// end of layer group
/// @}
