code:
/****************************************************************************
Copyright (c) 2010-2011  cocos2d-x.org
Copyright (c) 2008, 2009 Jason Booth

http://www.cocos2d-x.org

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#ifndef __CCMOTION_STREAK_H__
#define __CCMOTION_STREAK_H__

#include "CCNode.h"
#include "CCProtocols.h"

namespace cocos2d {

class CCRibbon;
/**
* @brief CCMotionStreak manages a Ribbon based on it's motion in absolute space.
* You construct it with a fadeTime, minimum segment size, texture path, texture
* length and color. The fadeTime controls how long it takes each vertex in
* the streak to fade out, the minimum segment size it how many pixels the
* streak will move before adding a new ribbon segement, and the texture
* length is the how many pixels the texture is stretched across. The texture
* is vertically aligned along the streak segemnts.
*
* Limitations:
*   CCMotionStreak, by default, will use the GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA blending function.
*   This blending function might not be the correct one for certain textures.
*   But you can change it by using:
*     [obj setBlendFunc: (ccBlendfunc) {new_src_blend_func, new_dst_blend_func}];
*
* @since v0.8.1
*/
class CC_DLL CCMotionStreak : public CCNode, public CCTextureProtocol
{
	/** Ribbon used by MotionStreak (weak reference) */
	CC_PROPERTY_READONLY(CCRibbon*, m_pRibbon, Ribbon)
	//CCTextureProtocol methods
	CC_PROPERTY(CCTexture2D*, m_pTexture, Texture)
	CC_PROPERTY(ccBlendFunc, m_tBlendFunc, BlendFunc)
public:
	CCMotionStreak()
		: m_pRibbon(NULL)
        , m_pTexture(NULL)
        , m_fSegThreshold(0.0)
		, m_fWidth(0.0)
	{}
	virtual ~CCMotionStreak(){}
	/** creates the a MotionStreak. The image will be loaded using the TextureMgr. */
	static CCMotionStreak * streakWithFade(float fade, float seg, const char *imagePath, float width, float length, const ccColor4B& color);

	/** initializes a MotionStreak. The file will be loaded using the TextureMgr. */
	bool initWithFade(float fade, float seg, const char *imagePath, float width, float length, const ccColor4B& color);

	/** polling function */
	void update(ccTime delta);
protected:
	float		m_fSegThreshold;
	float		m_fWidth;
	CCPoint		m_tLastLocation;
};

} // namespace cocos2d

#endif //__CCMOTION_STREAK_H__


code:
/****************************************************************************
Copyright (c) 2010 cocos2d-x.org

http://www.cocos2d-x.org

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/

#ifndef __COCOA_CC_MUTABLE_ARRAY_H__
#define __COCOA_CC_MUTABLE_ARRAY_H__

#include "CCObject.h"
#include "ccMacros.h"
#include <vector>
#include <stdarg.h>

namespace   cocos2d {

// the element should be pointer of CCObject or it's sub class
template<class T = CCObject*>
class CCMutableArray : public CCObject
{
public:
	typedef std::vector<T>								CCObjectArray;
	typedef typename CCObjectArray::iterator			CCMutableArrayIterator;
	typedef typename CCObjectArray::reverse_iterator	CCMutableArrayRevIterator;

public:
	CCMutableArray(unsigned int uSize = 0)
	{
		if (uSize != 0)
			m_array.reserve(uSize);
	}

	virtual ~CCMutableArray(void)
	{
		removeAllObjects();
	}

	inline unsigned int count(void)
	{
		return (unsigned int)m_array.size();
	}

	bool containsObject(T pObject)
	{
		if (m_array.empty() || (! pObject))
		{
			return false;
		}

		bool bRet = false;
		CCMutableArrayIterator iter;
		for (iter = m_array.begin(); iter != m_array.end(); ++iter)
		{
			if (*iter == pObject)
			{
				bRet = true;
				break;
			}
		}

		return bRet;
	}

	T getLastObject(void)
	{
		CCMutableArrayRevIterator iter = rbegin();

		if (iter != m_array.rend())
			return *iter;

                return 0;
	}

	T getObjectAtIndex(unsigned int uIndex)
	{
		CCAssert(uIndex < count(), "");

		if (uIndex >= count())
		{
                        return 0;
		}

		return m_array[uIndex];
	}

	// Adding objects
	void addObject(T pObject)
	{
		// make sure the pointer is not null
                if (pObject == 0)
		{
			return;
		}

		// add the refrence
		pObject->retain();

		m_array.push_back(pObject);
	}

	void addObjectsFromArray(CCMutableArray<T> *pArray)
	{
		if (pArray && pArray->count() > 0)
		{
			m_array.reserve(count() + pArray->count());
			CCMutableArrayIterator iter;
			for (iter = pArray->begin(); iter != pArray->end(); ++iter)
			{
				if (*iter)
                    (*iter)->retain();
				m_array.push_back(*iter);
			}
		}
	}

    void insertObjectAtIndex(T pObject, unsigned int uIndex)
	{
		CCAssert(uIndex <= count(), "");
		// make sure the object is not null
                if (pObject == 0)
		{
			return;
		}

		// add the reference of the object
		pObject->retain();

		// resize the capacity if the index out of it
		if (uIndex >= m_array.capacity())
		{
			m_array.reserve(uIndex + 1);
			m_array.push_back(pObject);
		}
		else	// insert the object
			m_array.insert(m_array.begin() + uIndex, pObject);
	}

	// Removing objects
	void removeLastObject(bool bDeleteObject = true)
	{
		CCMutableArrayRevIterator it = m_array.rbegin();
		if (it != m_array.rend())
		{
			if (bDeleteObject)
				(*it)->release();
			m_array.pop_back();
		}
	}

	void removeObject(T pObject, bool bDeleteObject = true)
	{
		if (m_array.empty() || (! pObject))
		{
			return;
		}

		CCMutableArrayIterator iter;
		int i;
		for (iter = m_array.begin(), i = 0; iter != m_array.end(); ++iter, ++i)
		{
			if (*iter == pObject)
			{
				m_array.erase(iter);

				if (bDeleteObject)
				{
                    pObject->release();
				}

				break;
			}
		}
	}

	void removeObjectsInArray(CCMutableArray<T>* pDeleteArray)
	{
		if(pDeleteArray && pDeleteArray->count())
		{
			CCMutableArrayIterator it;
			for( it = pDeleteArray->m_array.begin(); it != pDeleteArray->m_array.end(); ++it)
			{
				removeObject(*it);
			}
		}
	}

	void removeObjectAtIndex(unsigned int uIndex, bool bDeleteObject = true)
	{
		if (m_array.empty())
		{
			return;
		}

		if (bDeleteObject)
		{
			T pObject = m_array.at(uIndex);
			if (pObject)
			{
				pObject->release();
			}
		}

		m_array.erase(m_array.begin() + uIndex);
	}

	void removeAllObjects(bool bDeleteObject = true)
	{
		if (bDeleteObject)
		{
			CCMutableArrayIterator iter;
			for (iter = m_array.begin(); iter != m_array.end(); ++iter)
				(*iter)->release();
		}

		m_array.clear();
	}

	void replaceObjectAtIndex(unsigned int uIndex, T pObject, bool bDeleteObject = true)
	{
		if (bDeleteObject && m_array[uIndex])
		{
			m_array[uIndex]->release();
		}

		m_array[uIndex] = pObject;

		// add the ref
		if (pObject)
		{
			pObject->retain();
		}
	}

	inline CCMutableArrayIterator begin(void)
	{
		return m_array.begin();
	}

	inline CCMutableArrayRevIterator rbegin(void)
	{
		return m_array.rbegin();
	}

	CCMutableArrayIterator getLastValidIterator(void)
	{
		CCMutableArrayIterator iter;
		CCMutableArrayIterator ret;
		for (iter = m_array.begin(); iter != m_array.end(); ++iter)
		{
			ret = iter;
			if (! (*iter))
			{
				break;
			}
		}

		return ret;
	}

	/*
	 * end is a keyword of lua, so should use other name
	 * to export to lua
	*/
	inline CCMutableArrayIterator endToLua(void)
	{
		return m_array.end();
	}

	inline CCMutableArrayIterator end(void)
	{
		return m_array.end();
	}

	inline CCMutableArrayRevIterator rend(void)
	{
		return m_array.rend();
	}

	CCMutableArray<T>* copy(void)
	{
		CCMutableArray* pArray = new CCMutableArray();

		pArray->m_array.assign(m_array.begin(), m_array.end());

		if(pArray->count() > 0)
		{
			CCMutableArrayIterator it;
			for(it = pArray->begin(); it != pArray->end(); ++it)
			{
				if(*it)
				{
					(*it)->retain();
				}
			}
		}

		return pArray;
	}

public:
	static CCMutableArray<T>* arrayWithObjects(T pObject1, ...)
	{
		CCMutableArray<T> *pArray = new CCMutableArray<T>();
        pArray->autorelease();

		va_list params;
		va_start(params, pObject1);

		T pFirst = pObject1;
		while (pFirst)
		{
			pArray->addObject(pFirst);
			pFirst = va_arg(params, T);
		}

		va_end(params);

		return pArray;
	}

	static CCMutableArray<T>* arrayWithArray(CCMutableArray<T> *pSrcArray)
	{
        CCMutableArray<T> *pDestArray = 0;

                if (pSrcArray == 0)
		{
            pDestArray = new CCMutableArray<T>();
		}
        else
        {
            pDestArray = pSrcArray->copy();
        }

        pDestArray->autorelease();

		return pDestArray;
	}

private:
	std::vector<T> m_array;
};

}//namespace   cocos2d

#endif // __COCOA_CC_MUTABLE_ARRAY_H__

license: mit


code:
/****************************************************************************
Copyright (c) 2010 cocos2d-x.org

http://www.cocos2d-x.org

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#ifndef __CCMUTABLE_DICTIONARY_H__
#define __CCMUTABLE_DICTIONARY_H__

#include <map>
#include <vector>
#include <string>
#include "CCObject.h"
#include "CCMutableArray.h"
#include "ccMacros.h"

using namespace std;
namespace   cocos2d {
class CCString;

template<class _KeyT, class _ValueT = CCObject*>
class CCMutableDictionary : public CCObject
{
public:
	typedef std::map<_KeyT, _ValueT>	CCObjectMap;
	typedef typename CCObjectMap::iterator	CCObjectMapIter;

protected:
	typedef pair<_KeyT, _ValueT> Int_Pair;
	CCObjectMap		m_Map;
	bool			m_bBegin;
	CCObjectMapIter m_MapIter;

public:
	CCMutableDictionary(void)
	{
		m_bBegin = false;
	}

	~CCMutableDictionary(void)
	{
		removeAllObjects();
	}

	/// return the number of items
	unsigned int count()
	{
		return m_Map.size();
	}

	/// return all the keys
	std::vector<_KeyT> allKeys()
	{
		std::vector<_KeyT> tRet;
		if (m_Map.size() > 0)
		{
			CCObjectMapIter it;
			for( it = m_Map.begin(); it != m_Map.end(); ++it)
			{
				tRet.push_back(it->first);
			}
		}
		return tRet;
	}

	/** @warning : We use '==' to compare two objects*/
	std::vector<_KeyT> allKeysForObject(_ValueT object)
	{
		std::vector<_KeyT> tRet;
		if (m_Map.size() > 0)
		{
			CCObjectMapIter it;
			for( it= m_Map.begin(); it != m_Map.end(); ++it)
			{
				if (it->second == object)
				{
					tRet.push_back(it->first);
				}
			}
		}
		return tRet;
	}

	_ValueT objectForKey(const _KeyT& key)			///<
	{
		CCObjectMapIter it;

		it = m_Map.find(key);

		if(it == m_Map.end()) //no match case
			return NULL;

		return it->second;
	}

	bool setObject(_ValueT pObject, const _KeyT& key)
	{
		pair<CCObjectMapIter, bool > pr;

		pr = m_Map.insert( Int_Pair(key, pObject) );

		if(pr.second == true)
		{
			pObject->retain();
			return true;
		}

		return false;
	}

	void removeObjectForKey(const _KeyT& key)
	{
		CCObjectMapIter it;

		it = m_Map.find(key);

		if(it == m_Map.end()) //no match case
			return;

		if(it->second )
		{
			it->second->release() ;
			m_Map.erase(it);
		}
	}

	bool begin()
	{
		if(m_Map.size() == 0)
			return false;

		m_MapIter = m_Map.begin();
		m_bBegin = true;

		return true;
	}

	_ValueT next(_KeyT* key = NULL)
	{
		if(!m_bBegin)
			return NULL;

		_ValueT pObject = m_MapIter->second;

		if(m_MapIter == m_Map.end())
		{
			m_bBegin = false;
		}
		else
		{
			if(key)
			{
				*key = m_MapIter->first;
			}

			++m_MapIter;

			if(m_MapIter == m_Map.end())
			{
				m_bBegin = false;
			}
		}

		return pObject;
	}

	/*
	* end is a keyword of lua, so should use other name
	* to export to lua
	*/
	void endToLua()
	{
		end();
	}

	void end()
	{
		m_bBegin = false;
	}

	void removeAllObjects()
	{
		if (m_Map.size() > 0)
		{
			CCObjectMapIter it;
			for( it = m_Map.begin(); it != m_Map.end(); ++it)
			{
				if (it->second)
				{
					it->second->release();
				}
			}
		}
		m_Map.clear();
	}

	static CCMutableDictionary<_KeyT, _ValueT>* dictionaryWithDictionary(CCMutableDictionary<_KeyT, _ValueT>* srcDict)
	{
		CCMutableDictionary<_KeyT, _ValueT>* pNewDict = new CCMutableDictionary<_KeyT, _ValueT>();

		srcDict->begin();

		_KeyT key;
		_ValueT value;

		while( (value = srcDict->next(&key)) )
		{
			pNewDict->setObject(value, key);
		}

		srcDict->end();

		return pNewDict;
	}
};

#define CCDictionary	CCMutableDictionary
typedef CCDictionary<std::string, CCString*> CCStringToStringDictionary;
}//namespace   cocos2d

#endif //__CCMUTABLE_DICTIONARY_H__


code:
/****************************************************************************
 Copyright (c) 2010-2011 cocos2d-x.org
 Copyright (c) 2008-2010 Ricardo Quesada
 Copyright (c) 2009      Valentin Milea
 Copyright (c) 2011      Zynga Inc.

 http://www.cocos2d-x.org

 Permission is hereby granted, free of charge, to any person obtaining a copy
 of this software and associated documentation files (the "Software"), to deal
 in the Software without restriction, including without limitation the rights
 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 copies of the Software, and to permit persons to whom the Software is
 furnished to do so, subject to the following conditions:

 The above copyright notice and this permission notice shall be included in
 all copies or substantial portions of the Software.

 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 THE SOFTWARE.
 ****************************************************************************/

#ifndef __PLATFOMR_CCNODE_H__
#define __PLATFOMR_CCNODE_H__

#include "ccMacros.h"
#include "CCAffineTransform.h"
#include "CCArray.h"
#include "CCGL.h"

namespace   cocos2d {
	class CCCamera;
	class CCGridBase;
	class CCPoint;
	class CCTouch;
	class CCAction;
	class CCRGBAProtocol;
	class CCLabelProtocol;

	enum {
		kCCNodeTagInvalid = -1,
	};

    enum {
        kCCNodeOnEnter,
        kCCNodeOnExit
    };

	/** @brief CCNode is the main element. Anything thats gets drawn or contains things that get drawn is a CCNode.
     The most popular CCNodes are: CCScene, CCLayer, CCSprite, CCMenu.

     The main features of a CCNode are:
     - They can contain other CCNode nodes (addChild, getChildByTag, removeChild, etc)
     - They can schedule periodic callback (schedule, unschedule, etc)
     - They can execute actions (runAction, stopAction, etc)

     Some CCNode nodes provide extra functionality for them or their children.

     Subclassing a CCNode usually means (one/all) of:
     - overriding init to initialize resources and schedule callbacks
     - create callbacks to handle the advancement of time
     - overriding draw to render the node

     Features of CCNode:
     - position
     - scale (x, y)
     - rotation (in degrees, clockwise)
     - CCCamera (an interface to gluLookAt )
     - CCGridBase (to do mesh transformations)
     - anchor point
     - size
     - visible
     - z-order
     - openGL z position

     Default values:
     - rotation: 0
     - position: (x=0,y=0)
     - scale: (x=1,y=1)
     - contentSize: (x=0,y=0)
     - anchorPoint: (x=0,y=0)

     Limitations:
     - A CCNode is a "void" object. It doesn't have a texture

     Order in transformations with grid disabled
     -# The node will be translated (position)
     -# The node will be rotated (rotation)
     -# The node will be scaled (scale)
     -# The node will be moved according to the camera values (camera)

     Order in transformations with grid enabled
     -# The node will be translated (position)
     -# The node will be rotated (rotation)
     -# The node will be scaled (scale)
     -# The grid will capture the screen
     -# The node will be moved according to the camera values (camera)
     -# The grid will render the captured screen

     Camera:
     - Each node has a camera. By default it points to the center of the CCNode.
     */

	class CC_DLL CCNode : public CCObject
	{

		// variable property

		/** The z order of the node relative to it's "brothers": children of the same parent */
		CC_PROPERTY_READONLY(int, m_nZOrder, ZOrder)

        /** The real openGL Z vertex.
         Differences between openGL Z vertex and cocos2d Z order:
         - OpenGL Z modifies the Z vertex, and not the Z order in the relation between parent-children
         - OpenGL Z might require to set 2D projection
         - cocos2d Z order works OK if all the nodes uses the same openGL Z vertex. eg: vertexZ = 0
         @warning: Use it at your own risk since it might break the cocos2d parent-children z order
         @since v0.8
         */
        CC_PROPERTY(float, m_fVertexZ, VertexZ)

        /** The rotation (angle) of the node in degrees. 0 is the default rotation angle. Positive values rotate node CW. */
        CC_PROPERTY(float, m_fRotation, Rotation)

        /** Get the scale factor of the node.
         @warning: Assert when m_fScaleX != m_fScaleY.
         */
        float getScale();
		/** The scale factor of the node. 1.0 is the default scale factor. It modifies the X and Y scale at the same time. */
		void setScale(float scale);

		/** The scale factor of the node. 1.0 is the default scale factor. It only modifies the X scale factor. */
		CC_PROPERTY(float, m_fScaleX, ScaleX)

        /** The scale factor of the node. 1.0 is the default scale factor. It only modifies the Y scale factor. */
        CC_PROPERTY(float, m_fScaleY, ScaleY)

        /** Position (x,y) of the node in OpenGL coordinates. (0,0) is the left-bottom corner. */
        CC_PROPERTY_PASS_BY_REF(CCPoint, m_tPosition, Position)
        CC_PROPERTY_PASS_BY_REF(CCPoint, m_tPositionInPixels, PositionInPixels)

        /** get/set Position for Lua (pass number faster than CCPoint object)

         lua code:
         local pos  = node:getPositionLua() -- return CCPoint object from C++
         local x, y = node:getPosition()    -- return x, y values from C++
         local x    = node:getPositionX()
         local y    = node:getPositionY()
         node:setPosition(x, y)             -- pass x, y values to C++
         node:setPositionX(x)
         node:setPositionY(y)
         node:setPositionInPixels(x, y)     -- pass x, y values to C++
         */
        const CCPoint& getPositionLua(void);
        void getPosition(float* x, float* y);
        float getPositionX(void);
        float getPositionY(void);
        void setPositionX(float x);
        void setPositionY(float y);
        void setPosition(float x, float y);
        void setPositionInPixels(float x, float y);

        /** The X skew angle of the node in degrees.
         This angle describes the shear distortion in the X direction.
         Thus, it is the angle between the Y axis and the left edge of the shape
         The default skewX angle is 0. Positive values distort the node in a CW direction.
         */
        CC_PROPERTY(float, m_fSkewX, SkewX)

        /** The Y skew angle of the node in degrees.
         This angle describes the shear distortion in the Y direction.
         Thus, it is the angle between the X axis and the bottom edge of the shape
         The default skewY angle is 0. Positive values distort the node in a CCW direction.
         */
        CC_PROPERTY(float, m_fSkewY, SkewY)

        CC_PROPERTY_READONLY(CCArray*, m_pChildren, Children)

        /** Get children count */
        unsigned int getChildrenCount(void);

        /** A CCCamera object that lets you move the node using a gluLookAt
         */
        CC_PROPERTY_READONLY(CCCamera *, m_pCamera, Camera)

        /** A CCGrid object that is used when applying effects */
        CC_PROPERTY(CCGridBase *, m_pGrid, Grid)

        /** Whether of not the node is visible. Default is true */
        CC_PROPERTY(bool, m_bIsVisible, IsVisible)

        /** anchorPoint is the point around which all transformations and positioning manipulations take place.
         It's like a pin in the node where it is "attached" to its parent.
         The anchorPoint is normalized, like a percentage. (0,0) means the bottom-left corner and (1,1) means the top-right corner.
         But you can use values higher than (1,1) and lower than (0,0) too.
         The default anchorPoint is (0.5,0.5), so it starts in the center of the node.
         @since v0.8
         */
        CC_PROPERTY_PASS_BY_REF(CCPoint, m_tAnchorPoint, AnchorPoint)

        /** The anchorPoint in absolute pixels.
         Since v0.8 you can only read it. If you wish to modify it, use anchorPoint instead
         */
        CC_PROPERTY_READONLY_PASS_BY_REF(CCPoint, m_tAnchorPointInPixels, AnchorPointInPixels)

        /** The untransformed size of the node.
         The contentSize remains the same no matter the node is scaled or rotated.
         All nodes has a size. Layer and Scene has the same size of the screen.
         @since v0.8
         */
        CC_PROPERTY_PASS_BY_REF(CCSize, m_tContentSize, ContentSize)

        /** The untransformed size of the node in Pixels
         The contentSize remains the same no matter the node is scaled or rotated.
         All nodes has a size. Layer and Scene has the same size of the screen.
         @since v0.8
         */
        CC_PROPERTY_PASS_BY_REF(CCSize, m_tContentSizeInPixels, ContentSizeInPixels)

        /** whether or not the node is running */
        CC_PROPERTY_READONLY(bool, m_bIsRunning, IsRunning)

        /** A weak reference to the parent */
        CC_PROPERTY(CCNode *, m_pParent, Parent)

        /** If true the transformtions will be relative to it's anchor point.
         * Sprites, Labels and any other sizeble object use it have it enabled by default.
         * Scenes, Layers and other "whole screen" object don't use it, have it disabled by default.
         */
        CC_PROPERTY(bool, m_bIsRelativeAnchorPoint, IsRelativeAnchorPoint)

        /** A tag used to identify the node easily */
        CC_PROPERTY(int, m_nTag, Tag)

        /** A custom user data pointer */
        CC_PROPERTY(void *, m_pUserData, UserData)

	protected:

		// transform
		CCAffineTransform m_tTransform, m_tInverse;

#ifdef	CC_NODE_TRANSFORM_USING_AFFINE_MATRIX
		GLfloat	m_pTransformGL[16];
#endif
		// To reduce memory, place bools that are not properties here:
		bool m_bIsTransformDirty;
		bool m_bIsInverseDirty;

#ifdef	CC_NODE_TRANSFORM_USING_AFFINE_MATRIX
		bool m_bIsTransformGLDirty;
#endif

        int m_nScriptHandler;

	private:

		//! lazy allocs
		void childrenAlloc(void);

		//! helper that reorder a child
		void insertChild(CCNode* child, int z);

		//! used internally to alter the zOrder variable. DON'T call this method manually
		void setZOrder(int z);

		void detachChild(CCNode *child, bool doCleanup);

		typedef void (CCNode::*callbackFunc)(void);

		void arrayMakeObjectsPerformSelector(CCArray* pArray, callbackFunc func);

		CCPoint convertToWindowSpace(const CCPoint& nodePoint);

	public:

		CCNode(void);

		virtual ~CCNode(void);

		char * description(void);

		/** allocates and initializes a node.
         The node will be created as "autorelease".
         */
		static CCNode * node(void);

		//scene managment

		/** callback that is called every time the CCNode enters the 'stage'.
         If the CCNode enters the 'stage' with a transition, this callback is called when the transition starts.
         During onEnter you can't a "sister/brother" node.
         */
		virtual void onEnter();

		/** callback that is called when the CCNode enters in the 'stage'.
         If the CCNode enters the 'stage' with a transition, this callback is called when the transition finishes.
         @since v0.8
         */
		virtual void onEnterTransitionDidFinish();

		/** callback that is called every time the CCNode leaves the 'stage'.
         If the CCNode leaves the 'stage' with a transition, this callback is called when the transition finishes.
         During onExit you can't access a sibling node.
         */
		virtual void onExit();

        /** Register onEnter/onExit handler script function

         Script handler auto unregister after onEnter().
         */
        virtual void registerScriptHandler(int nHandler);
        virtual void unregisterScriptHandler(void);

		// composition: ADD

		/** Adds a child to the container with z-order as 0.
         If the child is added to a 'running' node, then 'onEnter' and 'onEnterTransitionDidFinish' will be called immediately.
         @since v0.7.1
         */
		virtual void addChild(CCNode * child);

		/** Adds a child to the container with a z-order
         If the child is added to a 'running' node, then 'onEnter' and 'onEnterTransitionDidFinish' will be called immediately.
         @since v0.7.1
         */
		virtual void addChild(CCNode * child, int zOrder);

		/** Adds a child to the container with z order and tag
         If the child is added to a 'running' node, then 'onEnter' and 'onEnterTransitionDidFinish' will be called immediately.
         @since v0.7.1
         */
		virtual void addChild(CCNode * child, int zOrder, int tag);

		// composition: REMOVE

		/** Remove itself from its parent node. If cleanup is true, then also remove all actions and callbacks.
         If the node orphan, then nothing happens.
         @since v0.99.3
         */
		void removeFromParentAndCleanup(bool cleanup);

		/** Removes a child from the container. It will also cleanup all running actions depending on the cleanup parameter.
         @since v0.7.1
         */
		virtual void removeChild(CCNode* child, bool cleanup);

		/** Removes a child from the container by tag value. It will also cleanup all running actions depending on the cleanup parameter
         @since v0.7.1
         */
		void removeChildByTag(int tag, bool cleanup);

		/** Removes all children from the container and do a cleanup all running actions depending on the cleanup parameter.
         @since v0.7.1
         */
		virtual void removeAllChildrenWithCleanup(bool cleanup);

		// composition: GET
		/** Gets a child from the container given its tag
         @return returns a CCNode object
         @since v0.7.1
         */
		CCNode * getChildByTag(int tag);

		/** Reorders a child according to a new z value.
         * The child MUST be already added.
         */
		virtual void reorderChild(CCNode * child, int zOrder);

		/** Stops all running actions and schedulers
         @since v0.8
         */
		virtual void cleanup(void);

		// draw

		/** Override this method to draw your own node.
         The following GL states will be enabled by default:
         - glEnableClientState(GL_VERTEX_ARRAY);
         - glEnableClientState(GL_COLOR_ARRAY);
         - glEnableClientState(GL_TEXTURE_COORD_ARRAY);
         - glEnable(GL_TEXTURE_2D);

         AND YOU SHOULD NOT DISABLE THEM AFTER DRAWING YOUR NODE

         But if you enable any other GL state, you should disable it after drawing your node.
         */
		virtual void draw(void);

		/** recursive method that visit its children and draw them */
		virtual void visit(void);

		// transformations

		/** performs OpenGL view-matrix transformation based on position, scale, rotation and other attributes. */
		void transform(void);

		/** performs OpenGL view-matrix transformation of it's ancestors.
         Generally the ancestors are already transformed, but in certain cases (eg: attaching a FBO)
         it's necessary to transform the ancestors again.
         @since v0.7.2
         */
		void transformAncestors(void);

		/** returns a "local" axis aligned bounding box of the node.
         The returned box is relative only to its parent.

         @since v0.8.2
         */
		CCRect boundingBox(void);

		/** returns a "local" axis aligned bounding box of the node in pixels.
         The returned box is relative only to its parent.
         The returned box is in Points.

         @since v0.99.5
         */
		CCRect boundingBoxInPixels(void);

		// actions

		/** Executes an action, and returns the action that is executed.
         The node becomes the action's target.
         @warning Starting from v0.8 actions don't retain their target anymore.
         @since v0.7.1
         @return An Action pointer
         */

		CCAction* runAction(CCAction* action);

		/** Removes all actions from the running action list */
		void stopAllActions(void);

		/** Removes an action from the running action list */
		void stopAction(CCAction* action);

		/** Removes an action from the running action list given its tag
         @since v0.7.1
         */
		void stopActionByTag(int tag);

		/** Gets an action from the running action list given its tag
         @since v0.7.1
         @return the Action the with the given tag
         */
		CCAction* getActionByTag(int tag);

		/** Returns the numbers of actions that are running plus the ones that are schedule to run (actions in actionsToAdd and actions arrays).
         * Composable actions are counted as 1 action. Example:
         *    If you are running 1 Sequence of 7 actions, it will return 1.
         *    If you are running 7 Sequences of 2 actions, it will return 7.
         */
		unsigned int numberOfRunningActions(void);

		// timers

		/** check whether a selector is scheduled. */
		bool isScheduled(SEL_SCHEDULE selector);

		/** schedules the "update" method. It will use the order number 0. This method will be called every frame.
         Scheduled methods with a lower order value will be called before the ones that have a higher order value.
         Only one "update" method could be scheduled per node.

         @since v0.99.3
         */
		void scheduleUpdate(void);

		/** schedules the "update" selector with a custom priority. This selector will be called every frame.
         Scheduled selectors with a lower priority will be called before the ones that have a higher value.
         Only one "update" selector could be scheduled per node (You can't have 2 'update' selectors).

         @since v0.99.3
         */
		void scheduleUpdateWithPriority(int priority);

		/* unschedules the "update" method.

         @since v0.99.3
         */
		void unscheduleUpdate(void);

		/** schedules a selector.
         The scheduled selector will be ticked every frame
         */
		void schedule(SEL_SCHEDULE selector);

		/** schedules a custom selector with an interval time in seconds.
         If time is 0 it will be ticked every frame.
         If time is 0, it is recommended to use 'scheduleUpdate' instead.
         If the selector is already scheduled, then the interval parameter
         will be updated without scheduling it again.
         */
		void schedule(SEL_SCHEDULE selector, ccTime interval);

		/** unschedules a custom selector.*/
		void unschedule(SEL_SCHEDULE selector);

		/** unschedule all scheduled selectors: custom selectors, and the 'update' selector.
         Actions are not affected by this method.
         @since v0.99.3
         */
		void unscheduleAllSelectors(void);

		/** resumes all scheduled selectors and actions.
         Called internally by onEnter
         */
		void resumeSchedulerAndActions(void);
		/** pauses all scheduled selectors and actions.
         Called internally by onExit
         */
		void pauseSchedulerAndActions(void);

		// transformation methods

		/** Returns the matrix that transform the node's (local) space coordinates into the parent's space coordinates.
         The matrix is in Pixels.
         @since v0.7.1
         */
		CCAffineTransform nodeToParentTransform(void);

		/** Returns the matrix that transform parent's space coordinates to the node's (local) space coordinates.
         The matrix is in Pixels.
         @since v0.7.1
         */
		CCAffineTransform parentToNodeTransform(void);

		/** Retrusn the world affine transform matrix. The matrix is in Pixels.
         @since v0.7.1
         */
		CCAffineTransform nodeToWorldTransform(void);

		/** Returns the inverse world affine transform matrix. The matrix is in Pixels.
         @since v0.7.1
         */
		CCAffineTransform worldToNodeTransform(void);

		/** Converts a Point to node (local) space coordinates. The result is in Points.
         @since v0.7.1
         */
		CCPoint convertToNodeSpace(const CCPoint& worldPoint);
		/** Converts a Point to world space coordinates. The result is in Points.
         @since v0.7.1
         */
		CCPoint convertToWorldSpace(const CCPoint& nodePoint);
		/** Converts a Point to node (local) space coordinates. The result is in Points.
         treating the returned/received node point as anchor relative.
         @since v0.7.1
         */
		CCPoint convertToNodeSpaceAR(const CCPoint& worldPoint);
		/** Converts a local Point to world space coordinates.The result is in Points.
         treating the returned/received node point as anchor relative.
         @since v0.7.1
         */
		CCPoint convertToWorldSpaceAR(const CCPoint& nodePoint);

		/** convenience methods which take a CCTouch instead of CCPoint
         @since v0.7.1
         */
		CCPoint convertTouchToNodeSpace(CCTouch * touch);

		/** converts a CCTouch (world coordinates) into a local coordiante. This method is AR (Anchor Relative).
         @since v0.7.1
         */
		CCPoint convertTouchToNodeSpaceAR(CCTouch * touch);
	};
}//namespace   cocos2d

#endif // __PLATFOMR_CCNODE_H__


code:
/****************************************************************************
Copyright (c) 2010 cocos2d-x.org

http://www.cocos2d-x.org

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/

#ifndef __COCOA_NSOBJECT_H__
#define __COCOA_NSOBJECT_H__

#include "CCCommon.h"
#include "ccTypes.h"

namespace   cocos2d {
class CCZone;
class CCObject;
class CCString;
class CCNode;
class CCEvent;

class CC_DLL CCCopying
{
public:
    virtual CCObject* copyWithZone(CCZone* pZone);
};

class CC_DLL CCObject : public CCCopying
{
public:
    // object id, CCScriptSupport need public m_uID
    unsigned int		m_uID;
    // Lua reference id
    int                 m_nLuaID;
protected:
    // count of refrence
    unsigned int		m_uReference;
    // is the object autoreleased
    bool		m_bManaged;
public:
    CCObject(void);
    virtual ~CCObject(void);

    void release(void);
    void retain(void);
    CCObject* autorelease(void);
    CCObject* copy(void);
    bool isSingleRefrence(void);
    unsigned int retainCount(void);
    virtual bool isEqual(const CCObject* pObject);

    virtual void update(ccTime dt) {CC_UNUSED_PARAM(dt);};

    friend class CCAutoreleasePool;
};

typedef void (CCObject::*SEL_SCHEDULE)(ccTime);
typedef void (CCObject::*SEL_CallFunc)();
typedef void (CCObject::*SEL_CallFuncN)(CCNode*);
typedef void (CCObject::*SEL_CallFuncND)(CCNode*, void*);
typedef void (CCObject::*SEL_CallFuncO)(CCObject*);
typedef void (CCObject::*SEL_MenuHandler)(CCObject*);
typedef void (CCObject::*SEL_EventHandler)(CCEvent*);

#define schedule_selector(_SELECTOR) (SEL_SCHEDULE)(&_SELECTOR)
#define callfunc_selector(_SELECTOR) (SEL_CallFunc)(&_SELECTOR)
#define callfuncN_selector(_SELECTOR) (SEL_CallFuncN)(&_SELECTOR)
#define callfuncND_selector(_SELECTOR) (SEL_CallFuncND)(&_SELECTOR)
#define callfuncO_selector(_SELECTOR) (SEL_CallFuncO)(&_SELECTOR)
#define menu_selector(_SELECTOR) (SEL_MenuHandler)(&_SELECTOR)
#define event_selector(_SELECTOR) (SEL_EventHandler)(&_SELECTOR)

}//namespace   cocos2d

#endif // __COCOA_NSOBJECT_H__


code:
/****************************************************************************
Copyright (c) 2010-2011 cocos2d-x.org
Copyright (c) 2009-2010 Ricardo Quesada
Copyright (c) 2011      Zynga Inc.

http://www.cocos2d-x.org

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#ifndef __CCPARALLAX_NODE_H__
#define __CCPARALLAX_NODE_H__

#include "CCNode.h"
/*#include "support/data_support/ccArray.h"*/

namespace cocos2d {
	struct _ccArray;

	/** @brief CCParallaxNode: A node that simulates a parallax scroller

	The children will be moved faster / slower than the parent according the the parallax ratio.

	*/
	class CC_DLL CCParallaxNode : public CCNode
	{
		/** array that holds the offset / ratio of the children */
		CC_SYNTHESIZE(struct _ccArray *, m_pParallaxArray, ParallaxArray)

	public:
		/** Adds a child to the container with a z-order, a parallax ratio and a position offset
		It returns self, so you can chain several addChilds.
		@since v0.8
		*/
		CCParallaxNode();
		virtual ~CCParallaxNode();
		static CCParallaxNode * node();
		virtual void addChild(CCNode * child, int z, const CCPoint& parallaxRatio, const CCPoint& positionOffset);
		// super methods
		virtual void addChild(CCNode * child, int zOrder, int tag);
		virtual void removeChild(CCNode* child, bool cleanup);
		virtual void removeAllChildrenWithCleanup(bool cleanup);
		virtual void visit(void);
	protected:
		CCPoint	m_tLastPosition;
		virtual CCPoint absolutePosition();
	};

} // namespace cocos2d
#endif //__CCPARALLAX_NODE_H__


code:
/****************************************************************************
Copyright (c) 2010-2011 cocos2d-x.org
Copyright (c) 2008-2010 Ricardo Quesada
Copyright (c) 2011      Zynga Inc.

http://www.cocos2d-x.org

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#ifndef __CCPARTICLE_EXAMPLE_H__
#define __CCPARTICLE_EXAMPLE_H__

#include "platform/CCArchOptimalParticleSystem.h"

namespace cocos2d {

//! @brief A fire particle system
class CC_DLL CCParticleFire : public ARCH_OPTIMAL_PARTICLE_SYSTEM
{
public:
	CCParticleFire(){}
	virtual ~CCParticleFire(){}
	bool init(){ return initWithTotalParticles(250); }
	virtual bool initWithTotalParticles(unsigned int numberOfParticles);
	static CCParticleFire * node()
	{
		CCParticleFire *pRet = new CCParticleFire();
		if (pRet->init())
		{
			pRet->autorelease();
			return pRet;
		}
		CC_SAFE_DELETE(pRet)
		return NULL;
	}
};

//! @brief A fireworks particle system
class CC_DLL CCParticleFireworks : public ARCH_OPTIMAL_PARTICLE_SYSTEM
{
public:
	CCParticleFireworks(){}
	virtual ~CCParticleFireworks(){}
	bool init(){ return initWithTotalParticles(1500); }
	virtual bool initWithTotalParticles(unsigned int numberOfParticles);
	static CCParticleFireworks * node()
	{
		CCParticleFireworks *pRet = new CCParticleFireworks();
		if (pRet->init())
		{
			pRet->autorelease();
			return pRet;
		}
		CC_SAFE_DELETE(pRet)
		return NULL;
	}
};

//! @brief A sun particle system
class CC_DLL CCParticleSun : public ARCH_OPTIMAL_PARTICLE_SYSTEM
{
public:
	CCParticleSun(){}
	virtual ~CCParticleSun(){}
	bool init(){ return initWithTotalParticles(350); }
	virtual bool initWithTotalParticles(unsigned int numberOfParticles);
	static CCParticleSun * node()
	{
		CCParticleSun *pRet = new CCParticleSun();
		if (pRet->init())
		{
			pRet->autorelease();
			return pRet;
		}
		CC_SAFE_DELETE(pRet)
		return NULL;
	}
};

//! @brief A galaxy particle system
class CC_DLL CCParticleGalaxy : public ARCH_OPTIMAL_PARTICLE_SYSTEM
{
public:
	CCParticleGalaxy(){}
	virtual ~CCParticleGalaxy(){}
	bool init(){ return initWithTotalParticles(200); }
	virtual bool initWithTotalParticles(unsigned int numberOfParticles);
	static CCParticleGalaxy * node()
	{
		CCParticleGalaxy *pRet = new CCParticleGalaxy();
		if (pRet->init())
		{
			pRet->autorelease();
			return pRet;
		}
		CC_SAFE_DELETE(pRet)
		return NULL;
	}
};

//! @brief A flower particle system
class CC_DLL CCParticleFlower : public ARCH_OPTIMAL_PARTICLE_SYSTEM
{
public:
	CCParticleFlower(){}
	virtual ~CCParticleFlower(){}
	bool init(){ return initWithTotalParticles(250); }
	virtual bool initWithTotalParticles(unsigned int numberOfParticles);
	static CCParticleFlower * node()
	{
		CCParticleFlower *pRet = new CCParticleFlower();
		if (pRet->init())
		{
			pRet->autorelease();
			return pRet;
		}
		CC_SAFE_DELETE(pRet)
		return NULL;
	}
};

//! @brief A meteor particle system
class CC_DLL CCParticleMeteor : public ARCH_OPTIMAL_PARTICLE_SYSTEM
{
public:
	CCParticleMeteor(){}
	virtual ~CCParticleMeteor(){}
	bool init(){ return initWithTotalParticles(150); }
	virtual bool initWithTotalParticles(unsigned int numberOfParticles);
	static CCParticleMeteor * node()
	{
		CCParticleMeteor *pRet = new CCParticleMeteor();
		if (pRet->init())
		{
			pRet->autorelease();
			return pRet;
		}
		CC_SAFE_DELETE(pRet)
		return NULL;
	}
};

//! @brief An spiral particle system
class CC_DLL CCParticleSpiral : public ARCH_OPTIMAL_PARTICLE_SYSTEM
{
public:
	CCParticleSpiral(){}
	virtual ~CCParticleSpiral(){}
	bool init(){ return initWithTotalParticles(500); }
	virtual bool initWithTotalParticles(unsigned int numberOfParticles);
	static CCParticleSpiral * node()
	{
		CCParticleSpiral *pRet = new CCParticleSpiral();
		if (pRet->init())
		{
			pRet->autorelease();
			return pRet;
		}
		CC_SAFE_DELETE(pRet)
		return NULL;
	}
};

//! @brief An explosion particle system
class CC_DLL CCParticleExplosion : public ARCH_OPTIMAL_PARTICLE_SYSTEM
{
public:
	CCParticleExplosion(){}
	virtual ~CCParticleExplosion(){}
	bool init(){ return initWithTotalParticles(700); }
	virtual bool initWithTotalParticles(unsigned int numberOfParticles);
	static CCParticleExplosion * node()
	{
		CCParticleExplosion *pRet = new CCParticleExplosion();
		if (pRet->init())
		{
			pRet->autorelease();
			return pRet;
		}
		CC_SAFE_DELETE(pRet)
		return NULL;
	}
};

//! @brief An smoke particle system
class CC_DLL CCParticleSmoke : public ARCH_OPTIMAL_PARTICLE_SYSTEM
{
public:
	CCParticleSmoke(){}
	virtual ~CCParticleSmoke(){}
	bool init(){ return initWithTotalParticles(200); }
	virtual bool initWithTotalParticles(unsigned int numberOfParticles);
	static CCParticleSmoke * node()
	{
		CCParticleSmoke *pRet = new CCParticleSmoke();
		if (pRet->init())
		{
			pRet->autorelease();
			return pRet;
		}
		CC_SAFE_DELETE(pRet)
		return NULL;
	}
};

//! @brief An snow particle system
class CC_DLL CCParticleSnow : public ARCH_OPTIMAL_PARTICLE_SYSTEM
{
public:
	CCParticleSnow(){}
	virtual ~CCParticleSnow(){}
	bool init(){ return initWithTotalParticles(700); }
	virtual bool initWithTotalParticles(unsigned int numberOfParticles);
	static CCParticleSnow * node()
	{
		CCParticleSnow *pRet = new CCParticleSnow();
		if (pRet->init())
		{
			pRet->autorelease();
			return pRet;
		}
		CC_SAFE_DELETE(pRet)
		return NULL;
	}
};

//! @brief A rain particle system
class CC_DLL CCParticleRain : public ARCH_OPTIMAL_PARTICLE_SYSTEM
{
public:
	CCParticleRain(){}
	virtual ~CCParticleRain(){}
	bool init(){ return initWithTotalParticles(1000); }
	virtual bool initWithTotalParticles(unsigned int numberOfParticles);
	static CCParticleRain * node()
	{
		CCParticleRain *pRet = new CCParticleRain();
		if (pRet->init())
		{
			pRet->autorelease();
			return pRet;
		}
		CC_SAFE_DELETE(pRet)
		return NULL;
	}
};

}// namespace cocos2d

#endif //__CCPARTICLE_EXAMPLE_H__


code:
/****************************************************************************
Copyright (c) 2010-2011 cocos2d-x.org
Copyright (c) 2008-2010 Ricardo Quesada
Copyright (c) 2011      Zynga Inc.

http://www.cocos2d-x.org

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#ifndef __CCPARTICLE_SYSTEM_H__
#define __CCPARTICLE_SYSTEM_H__

#include "CCProtocols.h"
#include "CCNode.h"
#include "CCMutableDictionary.h"
#include "CCString.h"

namespace cocos2d {

#if CC_ENABLE_PROFILERS
	class CCProfilingTimer;
#endif

//* @enum
enum {
	/** The Particle emitter lives forever */
	kCCParticleDurationInfinity = -1,

	/** The starting size of the particle is equal to the ending size */
	kCCParticleStartSizeEqualToEndSize = -1,

	/** The starting radius of the particle is equal to the ending radius */
	kCCParticleStartRadiusEqualToEndRadius = -1,

	// backward compatible
	kParticleStartSizeEqualToEndSize = kCCParticleStartSizeEqualToEndSize,
	kParticleDurationInfinity = kCCParticleDurationInfinity,
};

//* @enum
enum {
	/** Gravity mode (A mode) */
	kCCParticleModeGravity,

	/** Radius mode (B mode) */
	kCCParticleModeRadius,
};

/** @typedef tCCPositionType
possible types of particle positions
*/
typedef enum {
    /** Living particles are attached to the world and are unaffected by emitter repositioning. */
	kCCPositionTypeFree,

    /** Living particles are attached to the world but will follow the emitter repositioning.
    Use case: Attach an emitter to an sprite, and you want that the emitter follows the sprite.
    */
    kCCPositionTypeRelative,

    /** Living particles are attached to the emitter and are translated along with it. */
	kCCPositionTypeGrouped,
}tCCPositionType;

// backward compatible
enum {
	kPositionTypeFree = kCCPositionTypeFree,
	kPositionTypeGrouped = kCCPositionTypeGrouped,
};

/**
Structure that contains the values of each particle
*/
typedef struct sCCParticle {
	CCPoint     pos;
	CCPoint     startPos;

	ccColor4F	color;
	ccColor4F	deltaColor;

	float		size;
	float		deltaSize;

	float		rotation;
	float		deltaRotation;

	ccTime		timeToLive;

	//! Mode A: gravity, direction, radial accel, tangential accel
	struct {
		CCPoint		dir;
		float		radialAccel;
		float		tangentialAccel;
	} modeA;

	//! Mode B: radius mode
	struct {
		float		angle;
		float		degreesPerSecond;
		float		radius;
		float		deltaRadius;
	} modeB;

}tCCParticle;

//typedef void (*CC_UPDATE_PARTICLE_IMP)(id, SEL, tCCParticle*, CCPoint);

class CCTexture2D;

/** @brief Particle System base class.
Attributes of a Particle System:
- emmision rate of the particles
- Gravity Mode (Mode A):
- gravity
- direction
- speed +-  variance
- tangential acceleration +- variance
- radial acceleration +- variance
- Radius Mode (Mode B):
- startRadius +- variance
- endRadius +- variance
- rotate +- variance
- Properties common to all modes:
- life +- life variance
- start spin +- variance
- end spin +- variance
- start size +- variance
- end size +- variance
- start color +- variance
- end color +- variance
- life +- variance
- blending function
- texture

cocos2d also supports particles generated by Particle Designer (http://particledesigner.71squared.com/).
'Radius Mode' in Particle Designer uses a fixed emit rate of 30 hz. Since that can't be guarateed in cocos2d,
cocos2d uses a another approach, but the results are almost identical.

cocos2d supports all the variables used by Particle Designer plus a bit more:
- spinning particles (supported when using CCParticleSystemQuad)
- tangential acceleration (Gravity mode)
- radial acceleration (Gravity mode)
- radius direction (Radius mode) (Particle Designer supports outwards to inwards direction only)

It is possible to customize any of the above mentioned properties in runtime. Example:

@code
emitter.radialAccel = 15;
emitter.startSpin = 0;
@endcode

*/
class CC_DLL CCParticleSystem : public CCNode, public CCTextureProtocol
{
protected:
	std::string m_sPlistFile;
	//! time elapsed since the start of the system (in seconds)
	float m_fElapsed;

	// Different modes
	//! Mode A:Gravity + Tangential Accel + Radial Accel
	struct {
		/** Gravity value. Only available in 'Gravity' mode. */
		CCPoint gravity;
		/** speed of each particle. Only available in 'Gravity' mode.  */
		float speed;
		/** speed variance of each particle. Only available in 'Gravity' mode. */
		float speedVar;
		/** tangential acceleration of each particle. Only available in 'Gravity' mode. */
		float tangentialAccel;
		/** tangential acceleration variance of each particle. Only available in 'Gravity' mode. */
		float tangentialAccelVar;
		/** radial acceleration of each particle. Only available in 'Gravity' mode. */
		float radialAccel;
		/** radial acceleration variance of each particle. Only available in 'Gravity' mode. */
		float radialAccelVar;
	} modeA;

	//! Mode B: circular movement (gravity, radial accel and tangential accel don't are not used in this mode)
	struct {
		/** The starting radius of the particles. Only available in 'Radius' mode. */
		float startRadius;
		/** The starting radius variance of the particles. Only available in 'Radius' mode. */
		float startRadiusVar;
		/** The ending radius of the particles. Only available in 'Radius' mode. */
		float endRadius;
		/** The ending radius variance of the particles. Only available in 'Radius' mode. */
		float endRadiusVar;
		/** Number of degress to rotate a particle around the source pos per second. Only available in 'Radius' mode. */
		float rotatePerSecond;
		/** Variance in degrees for rotatePerSecond. Only available in 'Radius' mode. */
		float rotatePerSecondVar;
	} modeB;

	//! Array of particles
	tCCParticle *m_pParticles;

	// color modulate
	//	BOOL colorModulate;

	//! How many particles can be emitted per second
	float m_fEmitCounter;

	//!  particle idx
	unsigned int m_uParticleIdx;

	// Optimization
	//CC_UPDATE_PARTICLE_IMP	updateParticleImp;
	//SEL						updateParticleSel;

	// profiling
#if CC_ENABLE_PROFILERS
	CCProfilingTimer* m_pProfilingTimer;
#endif

	/** Is the emitter active */
	CC_PROPERTY_READONLY(bool, m_bIsActive, IsActive)
	/** Quantity of particles that are being simulated at the moment */
	CC_PROPERTY_READONLY(unsigned int, m_uParticleCount, ParticleCount)
	/** How many seconds the emitter wil run. -1 means 'forever' */
	CC_PROPERTY(float, m_fDuration, Duration)
	/** sourcePosition of the emitter */
	CC_PROPERTY_PASS_BY_REF(CCPoint, m_tSourcePosition, SourcePosition)
	/** Position variance of the emitter */
	CC_PROPERTY_PASS_BY_REF(CCPoint, m_tPosVar, PosVar)
	/** life, and life variation of each particle */
	CC_PROPERTY(float, m_fLife, Life)
	/** life variance of each particle */
	CC_PROPERTY(float, m_fLifeVar, LifeVar)
	/** angle and angle variation of each particle */
	CC_PROPERTY(float, m_fAngle, Angle)
	/** angle variance of each particle */
	CC_PROPERTY(float, m_fAngleVar, AngleVar)

//////////////////////////////////////////////////////////////////////////
public:
	// mode A
	virtual const CCPoint& getGravity();
	virtual void setGravity(const CCPoint& g);
	virtual float getSpeed();
	virtual void setSpeed(float speed);
	virtual float getSpeedVar();
	virtual void setSpeedVar(float speed);
	virtual float getTangentialAccel();
	virtual void setTangentialAccel(float t);
	virtual float getTangentialAccelVar();
	virtual void setTangentialAccelVar(float t);
	virtual float getRadialAccel();
	virtual void setRadialAccel(float t);
	virtual float getRadialAccelVar();
	virtual void setRadialAccelVar(float t);
	// mode B
	virtual float getStartRadius();
	virtual void setStartRadius(float startRadius);
	virtual float getStartRadiusVar();
	virtual void setStartRadiusVar(float startRadiusVar);
	virtual float getEndRadius();
	virtual void setEndRadius(float endRadius);
	virtual float getEndRadiusVar();
	virtual void setEndRadiusVar(float endRadiusVar);
	virtual float getRotatePerSecond();
	virtual void setRotatePerSecond(float degrees);
	virtual float getRotatePerSecondVar();
	virtual void setRotatePerSecondVar(float degrees);
//////////////////////////////////////////////////////////////////////////

	/** start size in pixels of each particle */
	CC_PROPERTY(float, m_fStartSize, StartSize)
	/** size variance in pixels of each particle */
	CC_PROPERTY(float, m_fStartSizeVar, StartSizeVar)
	/** end size in pixels of each particle */
	CC_PROPERTY(float, m_fEndSize, EndSize)
	/** end size variance in pixels of each particle */
	CC_PROPERTY(float, m_fEndSizeVar, EndSizeVar)
	/** start color of each particle */
	CC_PROPERTY_PASS_BY_REF(ccColor4F, m_tStartColor, StartColor)
	/** start color variance of each particle */
	CC_PROPERTY_PASS_BY_REF(ccColor4F, m_tStartColorVar, StartColorVar)
	/** end color and end color variation of each particle */
	CC_PROPERTY_PASS_BY_REF(ccColor4F, m_tEndColor, EndColor)
	/** end color variance of each particle */
	CC_PROPERTY_PASS_BY_REF(ccColor4F, m_tEndColorVar, EndColorVar)
	//* initial angle of each particle
	CC_PROPERTY(float, m_fStartSpin, StartSpin)
	//* initial angle of each particle
	CC_PROPERTY(float, m_fStartSpinVar, StartSpinVar)
	//* initial angle of each particle
	CC_PROPERTY(float, m_fEndSpin, EndSpin)
	//* initial angle of each particle
	CC_PROPERTY(float, m_fEndSpinVar, EndSpinVar)
	/** emission rate of the particles */
	CC_PROPERTY(float, m_fEmissionRate, EmissionRate)
	/** maximum particles of the system */
	CC_PROPERTY(unsigned int, m_uTotalParticles, TotalParticles)
	/** conforms to CocosNodeTexture protocol */
	CC_PROPERTY(CCTexture2D*, m_pTexture, Texture)
	/** conforms to CocosNodeTexture protocol */
	CC_PROPERTY(ccBlendFunc, m_tBlendFunc, BlendFunc)
	/** whether or not the particles are using blend additive.
	If enabled, the following blending function will be used.
	@code
	source blend function = GL_SRC_ALPHA;
	dest blend function = GL_ONE;
	@endcode
	*/
	CC_PROPERTY(bool, m_bIsBlendAdditive, IsBlendAdditive)
	/** particles movement type: Free or Grouped
	@since v0.8
	*/
	CC_PROPERTY(tCCPositionType, m_ePositionType, PositionType)
	/** whether or not the node will be auto-removed when it has no particles left.
	By default it is false.
	@since v0.8
	*/
	CC_PROPERTY(bool, m_bIsAutoRemoveOnFinish, IsAutoRemoveOnFinish)
	/** Switch between different kind of emitter modes:
	- kCCParticleModeGravity: uses gravity, speed, radial and tangential acceleration
	- kCCParticleModeRadius: uses radius movement + rotation
	*/
	CC_PROPERTY(int, m_nEmitterMode, EmitterMode)

public:
	CCParticleSystem();
	virtual ~CCParticleSystem();
	/** creates an initializes a CCParticleSystem from a plist file.
	This plist files can be creted manually or with Particle Designer:
	http://particledesigner.71squared.com/
	@since v0.99.3
	*/
	static CCParticleSystem * particleWithFile(const char *plistFile);

	/** initializes a CCParticleSystem from a plist file.
	This plist files can be creted manually or with Particle Designer:
	http://particledesigner.71squared.com/
	@since v0.99.3
	*/
	bool initWithFile(const char *plistFile);

	/** initializes a CCQuadParticleSystem from a CCDictionary.
	@since v0.99.3
	*/
	bool initWithDictionary(CCDictionary<std::string, CCObject*> *dictionary);

	//! Initializes a system with a fixed number of particles
	virtual bool initWithTotalParticles(unsigned int numberOfParticles);
	//! Add a particle to the emitter
	bool addParticle();
	//! Initializes a particle
	void initParticle(tCCParticle* particle);
	//! stop emitting particles. Running particles will continue to run until they die
	void stopSystem();
	//! Kill all living particles.
	void resetSystem();
	//! whether or not the system is full
	bool isFull();

	//! should be overriden by subclasses
	virtual void updateQuadWithParticle(tCCParticle* particle, const CCPoint& newPosition);
	//! should be overriden by subclasses
	virtual void postStep();

	virtual void update(ccTime dt);
private:
	/** Private method, return the string found by key in dict.
	@return "" if not found; return the string if found.
	*/
	inline const char * valueForKey(const char *key, CCDictionary<std::string, CCObject*> *dict)
	{
		if (dict)
		{
			CCString *pString = (CCString*)dict->objectForKey(std::string(key));
			return pString ? pString->m_sString.c_str() : "";
		}
		return "";
	}
};

}// namespace cocos2d

#endif //__CCPARTICLE_SYSTEM_H__


code:
/****************************************************************************
Copyright (c) 2010-2011 cocos2d-x.org
Copyright (c) 2008-2010 Ricardo Quesada
Copyright (c) 2011      Zynga Inc.

http://www.cocos2d-x.org

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#ifndef __CC_PARTICLE_SYSTEM_POINT_MOBILE_H__
#define __CC_PARTICLE_SYSTEM_POINT_MOBILE_H__

/*#include "Availability.h"*/
#include "CCParticleSystem.h"
#if (CC_TARGET_PLATFORM == CC_PLATFORM_LINUX) || (CC_TARGET_PLATFORM == CC_PLATFORM_QNX)
#include "CCParticleSystemQuad.h"
#endif

namespace cocos2d {

#define CC_MAX_PARTICLE_SIZE 64

/** @brief CCParticleSystemPoint is a subclass of CCParticleSystem
Attributes of a Particle System:
* All the attributes of Particle System

Features:
* consumes small memory: uses 1 vertex (x,y) per particle, no need to assign tex coordinates
* size can't be bigger than 64
* the system can't be scaled since the particles are rendered using GL_POINT_SPRITE

Limitations:
* On 3rd gen iPhone devices and iPads, this node performs MUCH slower than CCParticleSystemQuad.
*/
#if (CC_TARGET_PLATFORM == CC_PLATFORM_LINUX) || (CC_TARGET_PLATFORM == CC_PLATFORM_QNX)
class CC_DLL CCParticleSystemPoint : public CCParticleSystemQuad{
	//nothing to do
};
#else
class CC_DLL CCParticleSystemPoint : public CCParticleSystem
{
public:
	CCParticleSystemPoint()
		:m_pVertices(NULL)
	{}
	virtual ~CCParticleSystemPoint();

    /** creates an initializes a CCParticleSystemPoint from a plist file.
    This plist files can be creted manually or with Particle Designer:
    */
    static CCParticleSystemPoint * particleWithFile(const char *plistFile);

	// super methods
	virtual bool initWithTotalParticles(unsigned int numberOfParticles);
	virtual void updateQuadWithParticle(tCCParticle* particle, const CCPoint& newPosition);
	virtual void postStep();
	virtual void draw();
	virtual void setStartSpin(float var);
	virtual void setStartSpinVar(float var);
	virtual void setEndSpin(float var);
	virtual void setEndSpinVar(float var);
	virtual void setStartSize(float var);
	virtual void setEndSize(float var);
protected:
	//! Array of (x,y,size)
	ccPointSprite *m_pVertices;
	//! vertices buffer id
# if CC_USES_VBO
	GLuint	m_uVerticesID;
#endif
};
#endif

}// namespace cocos2d

#endif //__CC_PARTICLE_SYSTEM_POINT_MOBILE_H__


code:
/****************************************************************************
Copyright (c) 2010-2011 cocos2d-x.org
Copyright (c) 2008-2010 Ricardo Quesada
Copyright (c) 2009      Leonardo Kasperavičius
Copyright (c) 2011      ynga Inc.

http://www.cocos2d-x.org

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#ifndef __CC_PARTICLE_SYSTEM_QUAD_H__
#define __CC_PARTICLE_SYSTEM_QUAD_H__

#include  "CCParticleSystem.h"

namespace cocos2d {

class CCSpriteFrame;

/** @brief CCParticleSystemQuad is a subclass of CCParticleSystem

It includes all the features of ParticleSystem.

Special features and Limitations:
- Particle size can be any float number.
- The system can be scaled
- The particles can be rotated
- On 1st and 2nd gen iPhones: It is only a bit slower that CCParticleSystemPoint
- On 3rd gen iPhone and iPads: It is MUCH faster than CCParticleSystemPoint
- It consumes more RAM and more GPU memory than CCParticleSystemPoint
- It supports subrects
@since v0.8
*/
class CC_DLL CCParticleSystemQuad : public CCParticleSystem
{
protected:
	ccV2F_C4B_T2F_Quad	*m_pQuads;		// quads to be rendered
	GLushort			*m_pIndices;	// indices
#if CC_USES_VBO
	GLuint				m_uQuadsID;	// VBO id
#endif
public:
	CCParticleSystemQuad()
		:m_pQuads(NULL)
		,m_pIndices(NULL)
	{}
	virtual ~CCParticleSystemQuad();

    /** creates an initializes a CCParticleSystemQuad from a plist file.
    This plist files can be creted manually or with Particle Designer:
    */
    static CCParticleSystemQuad * particleWithFile(const char *plistFile);

	/** initialices the indices for the vertices*/
	void initIndices();

    /** initilizes the texture with a rectangle measured Points */
	void initTexCoordsWithRect(const CCRect& rect);

	/** Sets a new CCSpriteFrame as particle.
	WARNING: this method is experimental. Use setTexture:withRect instead.
	@since v0.99.4
	*/
	void setDisplayFrame(CCSpriteFrame *spriteFrame);

    /** Sets a new texture with a rect. The rect is in Points.
	@since v0.99.4
	*/
	void setTextureWithRect(CCTexture2D *texture, const CCRect& rect);
	// super methods
	virtual bool initWithTotalParticles(unsigned int numberOfParticles);
	virtual void setTexture(CCTexture2D* texture);
	virtual void updateQuadWithParticle(tCCParticle* particle, const CCPoint& newPosition);
	virtual void postStep();
	virtual void draw();
};

}// namespace cocos2d

#endif //__CC_PARTICLE_SYSTEM_QUAD_H__


code:
/****************************************************************************
Copyright (c) 2010-2011 cocos2d-x.org
Copyright (c) 2007      Scott Lembcke
Copyright (c) 2010      Lam Pham

http://www.cocos2d-x.org

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/

#ifndef __SUPPORT_CGPOINTEXTENSION_H__
#define __SUPPORT_CGPOINTEXTENSION_H__

/**
 @file
 CCPoint extensions based on Chipmunk's cpVect file.
 These extensions work both with CCPoint and cpVect.

 The "ccp" prefix means: "CoCos2d Point"

 Examples:
  - ccpAdd( ccp(1,1), ccp(2,2) ); // preferred cocos2d way
  - ccpAdd( CCPointMake(1,1), CCPointMake(2,2) ); // also ok but more verbose

  - cpvadd( cpv(1,1), cpv(2,2) ); // way of the chipmunk
  - ccpAdd( cpv(1,1), cpv(2,2) ); // mixing chipmunk and cocos2d (avoid)
  - cpvadd( CCPointMake(1,1), CCPointMake(2,2) ); // mixing chipmunk and CG (avoid)
 */

#include "CCGeometry.h"

#include <math.h>
namespace   cocos2d {

/** Helper macro that creates a CCPoint
 @return CCPoint
 @since v0.7.2
 */
#define ccp(__X__,__Y__) cocos2d::CCPointMake((float)(__X__), (float)(__Y__))

/** Returns opposite of point.
 @return CCPoint
 @since v0.7.2
 */
static inline CCPoint
ccpNeg(const CCPoint& v)
{
	return ccp(-v.x, -v.y);
}

/** Calculates sum of two points.
 @return CCPoint
 @since v0.7.2
 */
static inline CCPoint
ccpAdd(const CCPoint& v1, const CCPoint& v2)
{
	return ccp(v1.x + v2.x, v1.y + v2.y);
}

/** Calculates difference of two points.
 @return CCPoint
 @since v0.7.2
 */
static inline CCPoint
ccpSub(const CCPoint& v1, const CCPoint& v2)
{
	return ccp(v1.x - v2.x, v1.y - v2.y);
}

/** Returns point multiplied by given factor.
 @return CCPoint
 @since v0.7.2
 */
static inline CCPoint
ccpMult(const CCPoint& v, const CGFloat s)
{
	return ccp(v.x*s, v.y*s);
}

/** Calculates midpoint between two points.
 @return CCPoint
 @since v0.7.2
 */
static inline CCPoint
ccpMidpoint(const CCPoint& v1, const CCPoint& v2)
{
	return ccpMult(ccpAdd(v1, v2), 0.5f);
}

/** Calculates dot product of two points.
 @return CGFloat
 @since v0.7.2
 */
static inline CGFloat
ccpDot(const CCPoint& v1, const CCPoint& v2)
{
	return v1.x*v2.x + v1.y*v2.y;
}

/** Calculates cross product of two points.
 @return CGFloat
 @since v0.7.2
 */
static inline CGFloat
ccpCross(const CCPoint& v1, const CCPoint& v2)
{
	return v1.x*v2.y - v1.y*v2.x;
}

/** Calculates perpendicular of v, rotated 90 degrees counter-clockwise -- cross(v, perp(v)) >= 0
 @return CCPoint
 @since v0.7.2
 */
static inline CCPoint
ccpPerp(const CCPoint& v)
{
	return ccp(-v.y, v.x);
}

/** Calculates perpendicular of v, rotated 90 degrees clockwise -- cross(v, rperp(v)) <= 0
 @return CCPoint
 @since v0.7.2
 */
static inline CCPoint
ccpRPerp(const CCPoint& v)
{
	return ccp(v.y, -v.x);
}

/** Calculates the projection of v1 over v2.
 @return CCPoint
 @since v0.7.2
 */
static inline CCPoint
ccpProject(const CCPoint& v1, const CCPoint& v2)
{
	return ccpMult(v2, ccpDot(v1, v2)/ccpDot(v2, v2));
}

/** Rotates two points.
 @return CCPoint
 @since v0.7.2
 */
static inline CCPoint
ccpRotate(const CCPoint& v1, const CCPoint& v2)
{
	return ccp(v1.x*v2.x - v1.y*v2.y, v1.x*v2.y + v1.y*v2.x);
}

/** Unrotates two points.
 @return CCPoint
 @since v0.7.2
 */
static inline CCPoint
ccpUnrotate(const CCPoint& v1, const CCPoint& v2)
{
	return ccp(v1.x*v2.x + v1.y*v2.y, v1.y*v2.x - v1.x*v2.y);
}

/** Calculates the square length of a CCPoint (not calling sqrt() )
 @return CGFloat
 @since v0.7.2
 */
static inline CGFloat
ccpLengthSQ(const CCPoint& v)
{
	return ccpDot(v, v);
}

/** Calculates distance between point an origin
 @return CGFloat
 @since v0.7.2
 */
CGFloat CC_DLL ccpLength(const CCPoint& v);

/** Calculates the distance between two points
 @return CGFloat
 @since v0.7.2
 */
CGFloat CC_DLL ccpDistance(const CCPoint& v1, const CCPoint& v2);

/** Returns point multiplied to a length of 1.
 @return CCPoint
 @since v0.7.2
 */
CCPoint CC_DLL ccpNormalize(const CCPoint& v);

/** Converts radians to a normalized vector.
 @return CCPoint
 @since v0.7.2
 */
CCPoint CC_DLL ccpForAngle(const CGFloat a);

/** Converts a vector to radians.
 @return CGFloat
 @since v0.7.2
 */
CGFloat CC_DLL ccpToAngle(const CCPoint& v);

/** Clamp a value between from and to.
 @since v0.99.1
 */
float CC_DLL clampf(float value, float min_inclusive, float max_inclusive);

/** Clamp a point between from and to.
 @since v0.99.1
 */
CCPoint CC_DLL ccpClamp(const CCPoint& p, const CCPoint& from, const CCPoint& to);

/** Quickly convert CCSize to a CCPoint
 @since v0.99.1
 */
CCPoint CC_DLL ccpFromSize(const CCSize& s);

/** Run a math operation function on each point component
 * absf, fllorf, ceilf, roundf
 * any function that has the signature: float func(float);
 * For example: let's try to take the floor of x,y
 * ccpCompOp(p,floorf);
 @since v0.99.1
 */
CCPoint CC_DLL ccpCompOp(const CCPoint& p, float (*opFunc)(float));

/** Linear Interpolation between two points a and b
 @returns
	alpha == 0 ? a
	alpha == 1 ? b
	otherwise a value between a..b
 @since v0.99.1
 */
CCPoint CC_DLL ccpLerp(const CCPoint& a, const CCPoint& b, float alpha);

/** @returns if points have fuzzy equality which means equal with some degree of variance.
 @since v0.99.1
 */
bool CC_DLL ccpFuzzyEqual(const CCPoint& a, const CCPoint& b, float variance);

/** Multiplies a nd b components, a.x*b.x, a.y*b.y
 @returns a component-wise multiplication
 @since v0.99.1
 */
CCPoint CC_DLL ccpCompMult(const CCPoint& a, const CCPoint& b);

/** @returns the signed angle in radians between two vector directions
 @since v0.99.1
 */
float CC_DLL ccpAngleSigned(const CCPoint& a, const CCPoint& b);

/** @returns the angle in radians between two vector directions
 @since v0.99.1
*/
float CC_DLL ccpAngle(const CCPoint& a, const CCPoint& b);

/** Rotates a point counter clockwise by the angle around a pivot
 @param v is the point to rotate
 @param pivot is the pivot, naturally
 @param angle is the angle of rotation cw in radians
 @returns the rotated point
 @since v0.99.1
 */
CCPoint CC_DLL ccpRotateByAngle(const CCPoint& v, const CCPoint& pivot, float angle);

/** A general line-line intersection test
 @param p1
	is the startpoint for the first line P1 = (p1 - p2)
 @param p2
	is the endpoint for the first line P1 = (p1 - p2)
 @param p3
	is the startpoint for the second line P2 = (p3 - p4)
 @param p4
	is the endpoint for the second line P2 = (p3 - p4)
 @param s
	is the range for a hitpoint in P1 (pa = p1 + s*(p2 - p1))
 @param t
	is the range for a hitpoint in P3 (pa = p2 + t*(p4 - p3))
 @return bool
	indicating successful intersection of a line
	note that to truly test intersection for segments we have to make
	sure that s & t lie within [0..1] and for rays, make sure s & t > 0
	the hit point is		p3 + t * (p4 - p3);
	the hit point also is	p1 + s * (p2 - p1);
 @since v0.99.1
 */
bool CC_DLL ccpLineIntersect(const CCPoint& p1, const CCPoint& p2,
					  const CCPoint& p3, const CCPoint& p4,
					  float *s, float *t);

/*
ccpSegmentIntersect returns YES if Segment A-B intersects with segment C-D
@since v1.0.0
*/
bool CC_DLL ccpSegmentIntersect(const CCPoint& A, const CCPoint& B, const CCPoint& C, const CCPoint& D);

/*
ccpIntersectPoint returns the intersection point of line A-B, C-D
@since v1.0.0
*/
CCPoint CC_DLL ccpIntersectPoint(const CCPoint& A, const CCPoint& B, const CCPoint& C, const CCPoint& D);

}//namespace   cocos2d

#endif // __SUPPORT_CGPOINTEXTENSION_H__


code:
/****************************************************************************
Copyright (c) 2010-2011 cocos2d-x.org
Copyright (c) 2010      Lam Pham

http://www.cocos2d-x.org

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#ifndef __MISC_NODE_CCPROGRESS_TIMER_H__
#define __MISC_NODE_CCPROGRESS_TIMER_H__

#include "CCSprite.h"

namespace cocos2d
{
/** Types of progress
 @since v0.99.1
 */
typedef enum {
	/// Radial Counter-Clockwise
	kCCProgressTimerTypeRadialCCW,
	/// Radial ClockWise
	kCCProgressTimerTypeRadialCW,
	/// Horizontal Left-Right
	kCCProgressTimerTypeHorizontalBarLR,
	/// Horizontal Right-Left
	kCCProgressTimerTypeHorizontalBarRL,
	/// Vertical Bottom-top
	kCCProgressTimerTypeVerticalBarBT,
	/// Vertical Top-Bottom
	kCCProgressTimerTypeVerticalBarTB,
} CCProgressTimerType;

/**
 @brief CCProgresstimer is a subclass of CCNode.
 It renders the inner sprite according to the percentage.
 The progress can be Radial, Horizontal or vertical.
 @since v0.99.1
 */
class CC_DLL CCProgressTimer : public CCNode
{
public:
	~CCProgressTimer(void);

	/**	Change the percentage to change progress. */
	inline CCProgressTimerType getType(void) { return m_eType; }

	/** Percentages are from 0 to 100 */
	inline float getPercentage(void) {return m_fPercentage; }

	/** The image to show the progress percentage, retain */
	inline CCSprite* getSprite(void) { return m_pSprite; }

	bool initWithFile(const char *pszFileName);
	bool initWithTexture(CCTexture2D *pTexture);

	void setPercentage(float fPercentage);
	void setSprite(CCSprite *pSprite);
	void setType(CCProgressTimerType type);

	virtual void draw(void);

public:
	static CCProgressTimer* progressWithFile(const char *pszFileName);
	static CCProgressTimer* progressWithTexture(CCTexture2D *pTexture);

protected:
	ccVertex2F vertexFromTexCoord(const CCPoint& texCoord);
	void updateProgress(void);
	void updateBar(void);
	void updateRadial(void);
	void updateColor(void);
	CCPoint boundaryTexCoord(char index);

protected:
	CCProgressTimerType m_eType;
	float m_fPercentage;
	CCSprite *m_pSprite;
	int m_nVertexDataCount;
	ccV2F_C4B_T2F *m_pVertexData;
};

}

#endif //__MISC_NODE_CCPROGRESS_TIMER_H__


code:
/****************************************************************************
Copyright (c) 2010-2011 cocos2d-x.org
Copyright (c) 2008-2010 Ricardo Quesada

http://www.cocos2d-x.org

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/

#ifndef __CCPROTOCOLS_H__
#define __CCPROTOCOLS_H__

#include "ccTypes.h"
#include "CCTexture2D.h"

#include <string>
namespace   cocos2d {

//! @brief  CC RGBA protocol
class CC_DLL CCRGBAProtocol
{
public:
    /** sets Color
     @since v0.8
     */
    virtual void setColor(const ccColor3B& color) = 0;

	/** returns the color
	 @since v0.8
	 */
	virtual const ccColor3B& getColor(void) = 0;

    // returns the opacity
    virtual GLubyte getOpacity(void) = 0;

	/** sets the opacity.
	 @warning If the the texture has premultiplied alpha then, the R, G and B channels will be modifed.
	 Values goes from 0 to 255, where 255 means fully opaque.
	 */
	virtual void setOpacity(GLubyte opacity) = 0;

	// optional

	/** sets the premultipliedAlphaOpacity property.
	 If set to NO then opacity will be applied as: glColor(R,G,B,opacity);
	 If set to YES then oapcity will be applied as: glColor(opacity, opacity, opacity, opacity );
	 Textures with premultiplied alpha will have this property by default on YES. Otherwise the default value is NO
	 @since v0.8
	 */
	virtual void setIsOpacityModifyRGB(bool bValue) = 0;

	/** returns whether or not the opacity will be applied using glColor(R,G,B,opacity) or glColor(opacity, opacity, opacity, opacity);
	 @since v0.8
	 */
	virtual bool getIsOpacityModifyRGB(void) = 0;
};

/**
 @brief You can specify the blending fuction.
 @since v0.99.0
 */
class CC_DLL CCBlendProtocol
{
public:
	// set the source blending function for the texture
	virtual void setBlendFunc(ccBlendFunc blendFunc) = 0;

	// returns the blending function used for the texture
	virtual ccBlendFunc getBlendFunc(void) = 0;
};

/** @brief CCNode objects that uses a Texture2D 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 funtion at any time.
 @since v0.8.0
 */
class CC_DLL CCTextureProtocol : public CCBlendProtocol
{
public:
	// returns the used texture
	virtual CCTexture2D* getTexture(void) = 0;

	// sets a new texture. it will be retained
    virtual void setTexture(CCTexture2D *texture) = 0;
};

//! @brief Common interface for Labels
class CC_DLL CCLabelProtocol
{
public:
	// sets a new label using an string
	virtual void setString(const char *label) = 0;

	/** returns the string that is rendered */
	virtual const char* getString(void) = 0;
};

/** OpenGL projection protocol */
class CC_DLL CCProjectionProtocol
{
public:
	/** Called by CCDirector when the porjection is updated, and "custom" projection is used
	@since v0.99.5
	*/
	virtual void updateProjection(void) = 0;
};

}//namespace   cocos2d

#endif // __CCPROTOCOLS_H__


code:
/****************************************************************************
Copyright (c) 2010-2011 cocos2d-x.org
Copyright (c) 2009      Jason Booth

http://www.cocos2d-x.org

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#ifndef __CCRENDER_TEXTURE_H__
#define __CCRENDER_TEXTURE_H__

#include "CCData.h"
#include "CCNode.h"
#include "CCSprite.h"

namespace cocos2d {

typedef enum eImageFormat
{
	kCCImageFormatJPG       = 0,
	kCCImageFormatPNG       = 1,
    kCCImageFormatRawData   = 2
} tImageFormat;
/**
@brief CCRenderTexture is a generic rendering target. To render things into it,
simply construct a render target, call begin on it, call visit on any cocos
scenes or objects to render them, and call end. For convienience, render texture
adds a sprite as it's display child with the results, so you can simply add
the render texture to your scene and treat it like any other CocosNode.
There are also functions for saving the render texture to disk in PNG or JPG format.

@since v0.8.1
*/
class CC_DLL CCRenderTexture : public CCNode
{
    /** The CCSprite being used.
    The sprite, by default, will use the following blending function: GL_ONE, GL_ONE_MINUS_SRC_ALPHA.
    The blending function can be changed in runtime by calling:
    - [[renderTexture sprite] setBlendFunc:(ccBlendFunc){GL_ONE, GL_ONE_MINUS_SRC_ALPHA}];
    */
	CC_PROPERTY(CCSprite*, m_pSprite, Sprite)
public:
	CCRenderTexture();
	virtual ~CCRenderTexture();
    /** creates a RenderTexture object with width and height in Points and a pixel format, only RGB and RGBA formats are valid */
    static CCRenderTexture * renderTextureWithWidthAndHeight(int w, int h, CCTexture2DPixelFormat eFormat);

    /** creates a RenderTexture object with width and height in Points, pixel format is RGBA8888 */
    static CCRenderTexture * renderTextureWithWidthAndHeight(int w, int h);

    /** initializes a RenderTexture object with width and height in Points and a pixel format, only RGB and RGBA formats are valid */
    bool initWithWidthAndHeight(int w, int h, CCTexture2DPixelFormat eFormat);

    /** starts grabbing */
	void begin();

    /** starts rendering to the texture while clearing the texture first.
    This is more efficient then calling -clear first and then -begin */
    void beginWithClear(float r, float g, float b, float a);

    /** end is key word of lua, use other name to export to lua. */
	inline void endToLua(){ end();};

	/** ends grabbing*/
	// para bIsTOCacheTexture       the parameter is only used for android to cache the texture
	void end(bool bIsTOCacheTexture = true);

    /** clears the texture with a color */
    void clear(float r, float g, float b, float a);

	/** saves the texture into a file */
	// para szFilePath      the absolute path to save
	// para x,y         the lower left corner coordinates of the buffer to save
	// pare nWidth,nHeight    the size of the buffer to save
	//                        when nWidth = 0 and nHeight = 0, the image size to save equals to buffer texture size
	bool saveBuffer(const char *szFilePath, int x = 0, int y = 0, int nWidth = 0, int nHeight = 0);

	/** saves the texture into a file. put format at the first argument, or ti will be overloaded with
	 * saveBuffer(const char *szFilePath, int x = 0, int y = 0, int nWidth = 0, int nHeight = 0) */
	// para name        the file name to save
	// para format      the image format to save, here it supports kCCImageFormatPNG and kCCImageFormatJPG */
	// para x,y         the lower left corner coordinates of the buffer to save
	// pare nWidth,nHeight    the size of the buffer to save
	//                        when nWidth = 0 and nHeight = 0, the image size to save equals to buffer texture size
	bool saveBuffer(int format, const char *name, int x = 0, int y = 0, int nWidth = 0, int nHeight = 0);

    /* get buffer as UIImage, can only save a render buffer which has a RGBA8888 pixel format */
    CCData *getUIImageAsDataFromBuffer(int format);

	/** save the buffer data to a CCImage */
	// para pImage      the CCImage to save
	// para x,y         the lower left corner coordinates of the buffer to save
	// pare nWidth,nHeight    the size of the buffer to save
	//                        when nWidth = 0 and nHeight = 0, the image size to save equals to buffer texture size
	bool getUIImageFromBuffer(CCImage *pImage, int x = 0, int y = 0, int nWidth = 0, int nHeight = 0);

protected:
	GLuint				m_uFBO;
	GLint				m_nOldFBO;
	CCTexture2D			*m_pTexture;
	CCImage				*m_pUITextureImage;
    GLenum				m_ePixelFormat;
};

} // namespace cocos2d

#endif //__CCRENDER_TEXTURE_H__


code:
/****************************************************************************
Copyright (c) 2010-2011  cocos2d-x.org
Copyright (c) 2008, 2009 Jason Booth

http://www.cocos2d-x.org

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#ifndef __CCRIBBON_H__
#define __CCRIBBON_H__

/*#include <GLES/egl.h>*/
#include "CCNode.h"
#include "CCProtocols.h"
#include "CCMutableArray.h"

namespace cocos2d {

class CCRibbonSegment;
/**
* @brief A CCRibbon is a dynamically generated list of polygons drawn as a single or series
* of triangle strips. The primary use of CCRibbon is as the drawing class of Motion Streak,
* but it is quite useful on it's own. When manually drawing a ribbon, you can call addPointAt
* and pass in the parameters for the next location in the ribbon. The system will automatically
* generate new polygons, texture them accourding to your texture width, etc, etc.
*
* CCRibbon data is stored in a CCRibbonSegment class. This class statically allocates enough verticies and
* texture coordinates for 50 locations (100 verts or 48 triangles). The ribbon class will allocate
* new segments when they are needed, and reuse old ones if available. The idea is to avoid constantly
* allocating new memory and prefer a more static method. However, since there is no way to determine
* the maximum size of some ribbons (motion streaks), a truely static allocation is not possible.
*
* @since v0.8.1
*/
class CC_DLL CCRibbon : public CCNode, public CCTextureProtocol
{
	/** Texture used by the ribbon. Conforms to CCTextureProtocol protocol */
	CC_PROPERTY(CCTexture2D*, m_pTexture, Texture)
	/** Texture lengths in pixels */
	CC_PROPERTY(float, m_fTextureLength, TextureLength)
	/** GL blendind function */
	CC_PROPERTY(ccBlendFunc, m_tBlendFunc, BlendFunc)
	/** color used by the Ribbon (RGBA) */
	CC_PROPERTY_PASS_BY_REF(ccColor4B, m_tColor, Color)

public:
    CCRibbon() : m_pTexture(0), m_pSegments(0), m_pDeletedSegments(0){}
	virtual ~CCRibbon();

	/** creates the ribbon */
	static CCRibbon * ribbonWithWidth(float w, const char *path, float length, const ccColor4B& color, float fade);
	/** init the ribbon */
	bool initWithWidth(float w, const char *path, float length, const ccColor4B& color, float fade);
	/** add a point to the ribbon */
	void addPointAt(CCPoint location, float width);
	/** polling function */
	void update(ccTime delta);
	/** determine side of line */
	float sideOfLine(const CCPoint& p, const CCPoint& l1, const CCPoint& l2);
	// super method
	virtual void draw();
private:
	/** rotates a point around 0, 0 */
	CCPoint rotatePoint(const CCPoint& vec, float rotation);
protected:
	CCMutableArray<CCRibbonSegment*> *m_pSegments;
	CCMutableArray<CCRibbonSegment*> *m_pDeletedSegments;

	CCPoint	m_tLastPoint1;
	CCPoint	m_tLastPoint2;
	CCPoint	m_tLastLocation;
// 	int		m_nVertCount_;
	float	m_fTexVPos;
	float	m_fCurTime;
	float	m_fFadeTime;
	float	m_fDelta;
	float	m_fLastWidth;
	float	m_fLastSign;
	bool	m_bPastFirstPoint;
};

/** @brief object to hold ribbon segment data */
class CC_DLL CCRibbonSegment : public CCObject
{
public:
	GLfloat	m_pVerts[50*6];
	GLfloat	m_pCoords[50*4];
	GLubyte	m_pColors[50*8];
	float	m_pCreationTime[50];
	bool	m_bFinished;
	unsigned int	m_uEnd;
	unsigned int	m_uBegin;
public:
	CCRibbonSegment()
		: m_bFinished(false)
        , m_uEnd(0)
		, m_uBegin(0)
	{}
	virtual ~CCRibbonSegment();
	char * description();
	bool init();
	void reset();
	void draw(float curTime, float fadeTime, const ccColor4B& color);
};

} // namespace cocos2d

#endif //__CCRIBBON_H__


code:
/****************************************************************************
Copyright (c) 2010-2011 cocos2d-x.org
Copyright (c) 2008-2010 Ricardo Quesada
Copyright (c) 2011      Zynga Inc.

http://www.cocos2d-x.org

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/

#ifndef __CCSCENE_H__
#define __CCSCENE_H__

#include "CCNode.h"

namespace   cocos2d {

/** @brief CCScene is a subclass of CCNode that is used only as an abstract concept.

CCScene an CCNode are almost identical with the difference that CCScene has it's
anchor point (by default) at the center of the screen.

For the moment CCScene has no other logic than that, but in future releases it might have
additional logic.

It is a good practice to use and CCScene as the parent of all your nodes.
*/
class CC_DLL CCScene : public CCNode
{
public:
	CCScene();
	virtual ~CCScene();
	bool init();
	static CCScene *node(void);
};
}//namespace   cocos2d

// for the subclass of CCScene, each has to implement the static "node" method
#define SCENE_NODE_FUNC(scene) \
static scene* node() \
{ \
	scene *pRet = new scene(); \
	if (pRet && pRet->init()) \
	{ \
		pRet->autorelease(); \
		return pRet; \
	} \
	else \
	{ \
		delete pRet; \
		pRet = NULL; \
		return NULL; \
	} \
};

#define SCENE_FUNC_PARAM(__TYPE__,__PARAMTYPE__,__PARAM__) \
	static cocos2d::CCScene* node(__PARAMTYPE__ __PARAM__) \
{ \
	cocos2d::CCScene * scene = NULL; \
	do  \
{ \
	scene = cocos2d::CCScene::node(); \
	CC_BREAK_IF(! scene); \
	__TYPE__ *layer = __TYPE__::node(__PARAM__); \
	CC_BREAK_IF(! layer); \
	scene->addChild(layer); \
} while (0); \
	return scene; \
};

#endif // __CCSCENE_H__