package org.cocos2d.actions.grid;

import org.cocos2d.cocoa.CCGeometry.CCPoint;
import org.cocos2d.cocoa.CCGeometry.CCSize;
import org.cocos2d.support.CCPointExtension;
import org.cocos2d.types.CCVertex3D;

////////////////////////////////////////////////////////////

/** CCLens3D action */
public class CCLens3D extends CCGrid3DAction {
	CCPoint	position;
	float	radius;
	
	/** lens effect. Defaults to 0.7 - 0 means no effect, 1 is very strong effect */
	float	lensEffect;

	/** lens center position */	
	CCPoint	lastPosition;
	
	/** creates the action with center position, radius, a grid size and duration */
	public static CCLens3D action(CCPoint pos, float r, CCSize gridSize, float d) {
		return new CCLens3D(pos, r, gridSize, d);
	}

	/** initializes the action with center position, radius, a grid size and duration */
	public CCLens3D(CCPoint pos, float r, CCSize gridSize, float d) {
		super(gridSize, d);

		position = pos;
		radius = r;
		lensEffect = 0.7f;
		lastPosition = CCPointExtension.ccp(-1,-1);
	}
	
	@Override
	public CCLens3D copy() {
		CCLens3D copy = new CCLens3D(position, radius, gridSize, duration);
		return copy;
	}

	@Override
	public void update(float time) {
		if ( position.x != lastPosition.x || position.y != lastPosition.y ) {
			int i, j;
			
			for( i = 0; i < gridSize.width+1; i++ ) {
				for( j = 0; j < gridSize.height+1; j++ ) {
					CCVertex3D	v = originalVertex(CCPointExtension.ccp(i,j));
					CCPoint vect = CCPointExtension.ccpSub(position, CCPointExtension.ccp(v.x,v.y));
					float r = CCPointExtension.ccpLength(vect);
					
					if ( r < radius ) {
						r = radius - r;
						float pre_log = r / radius;
						if ( pre_log == 0 ) pre_log = 0.001f;
						float l = (float)Math.log(pre_log) * lensEffect;
						float new_r = (float)Math.exp( l ) * radius;
						
						if ( CCPointExtension.ccpLength(vect) > 0 ) {
							vect = CCPointExtension.ccpNormalize(vect);
							CCPoint new_vect = CCPointExtension.ccpMult(vect, new_r);
							v.z += CCPointExtension.ccpLength(new_vect) * lensEffect;
						}
					}
					
					setVertex(CCPointExtension.ccp(i,j), v);
				}
			}
			
			lastPosition = position;
		}
	}

}
