package org.cocos2d.base_nodes;

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

/**
 * @addtogroup base_nodes
 * @{
 */

/** CCNodeRGBA is a subclass of CCNode that implements the CCRGBAProtocol protocol.
 *
 * All features from CCNode are valid, plus the following new features:
 * - opacity
 * - RGB colors
 * 
 * Opacity/Color propagates into children that conform to the CCRGBAProtocol if cascadeOpacity/cascadeColor is enabled.
 * @since v2.1
 */
public class CCNodeRGBA extends CCNode implements CCRGBAProtocol {
	public CCNodeRGBA() {
		_displayedOpacity = 255;
		_realOpacity = 255;
		_displayedColor.set(ccColor3B.ccWHITE);
		_realColor.set(ccColor3B.ccWHITE);
		_cascadeColorEnabled = false;
		_cascadeOpacityEnabled = false;
	}

	public boolean init() {
		if(super.init()) {
			_displayedOpacity = _realOpacity = 255;
			_displayedColor.set(ccColor3B.ccWHITE);
			_realColor.set(ccColor3B.ccWHITE);
			_cascadeOpacityEnabled = _cascadeColorEnabled = false;
			return true;
		}
		return false;
	}

	public int getOpacity() {
		return _realOpacity;
	}

	public int getDisplayedOpacity() {
		return _displayedOpacity;
	}

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

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

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

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

	public boolean isCascadeOpacityEnabled() {
		return _cascadeOpacityEnabled;
	}

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

	public ccColor3B getColor() {
		return _realColor;
	}

	public ccColor3B getDisplayedColor() {
		return _displayedColor;
	}

	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);
		}
	}

	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(CCNode obj : m_pChildren) {
				CCRGBAProtocol item = (CCRGBAProtocol)obj;
				if(item != null) {
					item.updateDisplayedColor(_displayedColor);
				}
			}
		}
	}

	public boolean isCascadeColorEnabled() {
		return _cascadeColorEnabled;
	}

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

	public void setOpacityModifyRGB(boolean bValue) {
	}

	public boolean isOpacityModifyRGB() {
		return false;
	}

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

// end of base_node group
/// @}
