package org.cocos2d.layers_scenes_transitions_nodes;

import java.util.ArrayList;
import java.util.Arrays;

import org.cocos2d.nodes.CCNode;

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

/** @brief CCMultipleLayer is a CCLayer with the ability to multiplex it's children.
 * Features:
 * - It supports one or more children
 * - Only one children will be active a time
 */
public class CCLayerMultiplex extends CCLayer {

	protected int m_nEnabledLayer;
	protected ArrayList<CCLayer> m_pLayers;

	public CCLayerMultiplex() {
		m_nEnabledLayer = 0;
		m_pLayers = null;
	}

	public static CCLayerMultiplex create() {
		CCLayerMultiplex pMultiplexLayer = new CCLayerMultiplex();
		if((pMultiplexLayer != null) && pMultiplexLayer.init()) {
			return pMultiplexLayer;
		}
		pMultiplexLayer = null;
		return null;
	}

	/** creates a CCMultiplexLayer with an array of layers.
	 * @since v2.1
	 */
	public static CCLayerMultiplex createWithArray(ArrayList<CCLayer> arrayOfLayers) {
		CCLayerMultiplex pMultiplexLayer = new CCLayerMultiplex();
		if((pMultiplexLayer != null) && pMultiplexLayer.initWithArray(arrayOfLayers)) {
			return pMultiplexLayer;
		}
		pMultiplexLayer = null;
		return null;
	}

	/** creates a CCLayerMultiplex with one or more layers using a variable argument list. */
	public static CCLayerMultiplex create(CCLayer... layers) {
		return createWithLayer(layers);
	}

	/**
	 * lua script can not init with undetermined number of variables
	 * so add these functions to be used with lua.
	 */
	public static CCLayerMultiplex createWithLayer(CCLayer... layers) {
		CCLayerMultiplex pMultiplexLayer = new CCLayerMultiplex();
		if((pMultiplexLayer != null) && pMultiplexLayer.initWithLayers(layers)) {
			return pMultiplexLayer;
		}
		pMultiplexLayer = null;
		return null;
	}

	public void addLayer(CCLayer layer) {
		assert m_pLayers != null : "";
		m_pLayers.add(layer);
	}

	/** initializes a MultiplexLayer with one or more layers using a variable argument list. */
	public boolean initWithLayers(CCLayer... layers) {
		if(super.init()) {
			m_pLayers = new ArrayList<CCLayer>();

			m_pLayers.addAll(Arrays.asList(layers));

			m_nEnabledLayer = 0;
			this.addChild((CCNode)m_pLayers.get(m_nEnabledLayer));
			return true;
		}

		return false;
	}

	/** switches to a certain layer indexed by n. 
	 * The current (old) layer will be removed from it's parent with 'cleanup:YES'.
	 */

	/** initializes a CCMultiplexLayer with an array of layers
	 * @since v2.1
	 */
	public boolean initWithArray(ArrayList<CCLayer> arrayOfLayers) {
		if(super.init()) {
			m_pLayers = new ArrayList<CCLayer>();

			m_pLayers.addAll(arrayOfLayers);

			m_nEnabledLayer = 0;
			this.addChild((CCNode)m_pLayers.get(m_nEnabledLayer));
			return true;
		}
		return false;
	}

	public void switchTo(int n) {
		assert n < m_pLayers.size() : "Invalid index in MultiplexLayer switchTo message";

		this.removeChild(m_pLayers.get(m_nEnabledLayer), true);

		m_nEnabledLayer = n;

		this.addChild((CCNode)m_pLayers.get(m_nEnabledLayer));
	}

	/** release the current layer and switches to another layer indexed by n.
	 * The current (old) layer will be removed from it's parent with 'cleanup:YES'.
	 */
	public void switchToAndReleaseMe(int n) {
		assert n < m_pLayers.size() : "Invalid index in MultiplexLayer switchTo message" ;

		this.removeChild((CCNode)m_pLayers.get(m_nEnabledLayer), true);

		//[layers replaceObjectAtIndex:enabledLayer withObject:[NSNull null]];
		m_pLayers.add(m_nEnabledLayer, null);

		m_nEnabledLayer = n;

		this.addChild((CCNode)m_pLayers.get(n));
	}
}

// end of layer group
/// @}
