package com.fingerHurdle.www;

import org.andengine.engine.camera.Camera;
import org.andengine.engine.handler.physics.PhysicsHandler;
import org.andengine.engine.options.EngineOptions;
import org.andengine.engine.options.ScreenOrientation;
import org.andengine.engine.options.resolutionpolicy.FillResolutionPolicy;
import org.andengine.entity.scene.Scene;
import org.andengine.entity.scene.background.Background;
import org.andengine.entity.sprite.AnimatedSprite;
import org.andengine.entity.util.FPSLogger;
import org.andengine.opengl.texture.TextureOptions;
import org.andengine.opengl.texture.atlas.bitmap.BitmapTextureAtlas;
import org.andengine.opengl.texture.atlas.bitmap.BitmapTextureAtlasTextureRegionFactory;
import org.andengine.opengl.texture.region.TiledTextureRegion;
import org.andengine.opengl.vbo.VertexBufferObjectManager;
import org.andengine.ui.activity.SimpleBaseGameActivity;

/**
 * (c) 2010 Nicolas Gramlich (c) 2011 Zynga
 * 
 * @author Nicolas Gramlich
 * @since 11:54:51 - 03.04.2010
 */
public class JumpSampleAni extends SimpleBaseGameActivity {

	private Camera camera;
	private static final int CAMERA_WIDTH = 800;
	private static final int CAMERA_HEIGHT = 480;

	// 점프감도를 높이기 위해서 300.0f로 수치를 넣어 보았습니다. 숫자가 클 수록 속도가 빨라집니다.
	private static final float DEMO_VELOCITY = 300.0f;
	static boolean bUp = false;
	static boolean bDown = false;

	private BitmapTextureAtlas mBitmapTextureAtlasJump;
	private TiledTextureRegion mFaceTextureRegionJump;

	@Override
	public EngineOptions onCreateEngineOptions() {
		camera = new Camera(0, 0, CAMERA_WIDTH, CAMERA_HEIGHT);
		EngineOptions engineOptions = new EngineOptions(true,
				ScreenOrientation.LANDSCAPE_FIXED, new FillResolutionPolicy(),
				camera);
		return engineOptions;
	}

	@Override
	public void onCreateResources() {
		BitmapTextureAtlasTextureRegionFactory.setAssetBasePath("gfx/");

		// 한장 짜리 점프 이미지를 사용합니다.
		this.mBitmapTextureAtlasJump = new BitmapTextureAtlas(
				this.getTextureManager(), 200, 100, TextureOptions.BILINEAR);
		this.mFaceTextureRegionJump = BitmapTextureAtlasTextureRegionFactory
				.createTiledFromAsset(this.mBitmapTextureAtlasJump, this,
						"jump_ani_tr.gif", 0, 0, 2, 1);

		this.mBitmapTextureAtlasJump.load();
	}

	@Override
	public Scene onCreateScene() {
		System.gc();
		this.mEngine.registerUpdateHandler(new FPSLogger());

		final Scene scene = new Scene();
		scene.setBackground(new Background(0.09804f, 0.6274f, 0.8784f));

		// 예제 소스의 시작점은 한가운데임
		// 화면상에서 하단 가운데에 있다가 점프하는 효과를 주기 위해서
		// 시작점을 한가운데 아래로 설정
		final float centerX = (JumpSampleAni.CAMERA_WIDTH - this.mFaceTextureRegionJump
				.getWidth()) / 2;
		final float centerY = JumpSampleAni.CAMERA_HEIGHT
				- this.mFaceTextureRegionJump.getWidth() / 2;
		final Jump jump = new Jump(centerX, centerY,
				this.mFaceTextureRegionJump,
				this.getVertexBufferObjectManager());
		// 속도는 프레임 지연을 의미한다. 숫자가 작을 수록 빠르게 움직인다. 
		// {}안의 ,는 스프라이트애니의 갯수대로 선언, 
		// 맨 마지막 boolean은 반복을 의미
		// 인덱스는 스프라이트가 2개라면 차례대로 0,1이 되고, 3개라면 0,2가 된다. 
		jump.animate(new long[] { 400, 400}, 0, 1, true);
		scene.attachChild(jump);

		return scene;
	}

	private static class Jump extends AnimatedSprite {
		private final PhysicsHandler mPhysicsHandler;

		public Jump(final float pX, final float pY,
				final TiledTextureRegion pTextureRegion,
				final VertexBufferObjectManager pVertexBufferObjectManager) {
			super(pX, pY, pTextureRegion, pVertexBufferObjectManager);
			this.mPhysicsHandler = new PhysicsHandler(this);
			this.registerUpdateHandler(this.mPhysicsHandler);

			// X,Y 축으로 속도를 주려면 setVelocity를 사용하지만,
			// 수직 점프는 setVelocityY만 사용하면 됩니다.
			this.mPhysicsHandler.setVelocityY(JumpSampleAni.DEMO_VELOCITY);
		}

		@Override
		protected void onManagedUpdate(final float pSecondsElapsed) {

			if (bUp == false || bDown == false) {

				// 여기서 이해해야 할 것은 Y좌표가 0이면 화면상에서 최상단이라는 것입니다.
				// 0이면 화면 최상단까지 간 것입니다.
				// 그래서 velocity값이 +이면 Y축 값이 늘어나므로 화면 아래로 떨어지게 됩니다.
				// 우리의 점프는 다음 단계를 거칩니다.
				// 번호 1.점점 올라가다가
				// 2. Y좌표 200에 도달하면 점점 아래로 떨어지다가
				// 3. 결국 속도가 0가 됩니다.

				// 2. 점점 떨어지게 함
				if (this.mY < 200) {
					this.mPhysicsHandler.setVelocityY(JumpSampleAni.DEMO_VELOCITY);
					bDown = true;

				}
				// 1. 점점 올라가게함
				else if (this.mY + this.getHeight() > JumpSampleAni.CAMERA_HEIGHT) {
					this.mPhysicsHandler
							.setVelocityY(-JumpSampleAni.DEMO_VELOCITY);
					bUp = true;
				}

			}

			// 3. 최종 단계로 velocity값을 0로 셋팅해서 속도를 없앱니다.
			if (bUp == true && bDown == true) {
				if (this.mY + this.getHeight() > JumpSampleAni.CAMERA_HEIGHT) {
					this.mPhysicsHandler.setVelocityY(0);
				}

			}
			super.onManagedUpdate(pSecondsElapsed);
		}
	}
}
