package com.backfire.Animation;

import android.graphics.Bitmap;
import android.graphics.Matrix;

import com.backfire.arithmetic.Card;
import com.backfire.doudizhu.common.DdzApplication;
import com.backfire.graphics.PCanvas;
import com.backfire.room.data.ConfigCenter;
import com.backfire.room.data.ResCenter;

/**
 * @Title: AnimationRotteMoveLaizi.java
 * @Package com.backfire.Animation
 * @Description: 翻转和从屏幕中间移动指定位置的癞子牌动画
 * @author Potter
 * @date 2013-11-27 下午10:03:50
 * @version V2.0
 */
public class AnimationTurnMoveLaizi extends Animation {

	private static enum Dir {
		LEFT, RIGHT
	}

	private static enum State {
		TURN, MOVE, FINISH
	}

	private static enum Toward {
		FRONT, BACK// 正面和背面
	}

	private long startTime = 0;
	private int lastTime = 0;
	private long playTime = 6;
	private float turnAngle = 180;

	private State state = State.TURN;
	private Toward toward = Toward.BACK;

	private static final float startX = (DdzApplication.getApplication().screenWidth - ConfigCenter.self_hand_card_W) / 2;
	private static final float startY = (DdzApplication.getApplication().screenHeight - ConfigCenter.self_hand_card_H) / 2;
	private static final int desW = ConfigCenter.out_card_W;
	private static final int desH = ConfigCenter.out_card_H;

	private int desX = 0;// 目的x坐标
	private int desY = 0;// 目的y坐标

	private float desScaleX = ConfigCenter.out_card_W
			/ (float) ConfigCenter.self_hand_card_W;
	private float desScaleY = ConfigCenter.out_card_H
			/ (float) ConfigCenter.self_hand_card_H;

	private float moveStepVX = 0;// 移动过程，移动x方向的移动速度
	private float moveStepVY = 0;// 移动过程，移动y方向的移动速度
	private float moveScaleXV = 0;// 移动过程，移动x方向的缩放速度
	private float moveScaleYV = 0;// 移动过程，移动y方向的缩放速度

	private float moveScaleX = 1;
	private float moveScaleY = 1;

	private float posX = 0;
	private float posY = 0;

	private float turnScaleX = 1;// 旋转过程，x方向的缩放值
	private float trunScaleXV = 0;// 旋转过程，x方向的缩放速度

	private float offsetX = 0;

	private Dir dir = Dir.LEFT;

	private long userTime = 0;

	private Matrix matrix;

	private Card card = null;

	/**
	 * @param time
	 *            单位毫秒
	 * @param desX
	 * @param desY
	 * @param bitmap
	 */
	public AnimationTurnMoveLaizi(int time, int desX, int desY, Card card) {
		this.deleteFlag = false;
		lastTime = time;
		this.desX = desX;
		this.desY = desY;
		
		this.posX = startX;
		this.posY = startY;
		
		this.moveStepVX = (desX - startX) / (float) time;
		this.moveStepVY = (desY - startY) / (float) time;
		this.moveScaleXV = (ConfigCenter.self_hand_card_W - ConfigCenter.out_card_W)
				/ (float) time;
		this.moveScaleYV = (ConfigCenter.self_hand_card_H - ConfigCenter.out_card_H)
				/ (float) time;
		trunScaleXV = (1 / (float) time) * ConfigCenter.burst_laizi_anim_turnV;// 40旋转速度比较合适

		this.card = card;

		if (desX > startX) {
			dir = Dir.LEFT;
		} else {
			dir = Dir.RIGHT;
		}

		matrix = new Matrix();

		startTime = System.currentTimeMillis() / 1000;
	}

	@Override
	public void exec(PCanvas canvas, long sleep) {
		super.exec(canvas, sleep);
		userTime += sleep;
		if (userTime > lastTime) {
			this.deleteFlag = true;
		} else {
			Card tmpCard = new Card();
			long timeHalf = lastTime / 2 - userTime;
			if (State.TURN == state && timeHalf >= 0) {
				state = State.TURN;
			} else {
				if (State.MOVE != state) {
					initMoveData();
				}
				state = State.MOVE;
			}
			float[] valuse = null;
			switch (state) {
			case TURN:
				valuse = new float[] { turnScaleX, 0, posX, 0, 1, startY, 0, 0,
						1 };
				matrix.reset();
				matrix.setValues(valuse);
				if (Toward.BACK == toward) {
					turnScaleX -= trunScaleXV;
					if (turnScaleX <= 0) {
						turnScaleX = 0f;
						toward = Toward.FRONT;
						tmpCard = card;
					}
				} else {
					tmpCard = card;
					turnScaleX += trunScaleXV;
					if (turnScaleX >= 1) {
						turnScaleX = 1;
						state = State.MOVE;
						initMoveData();
					}
				}
				if (State.TURN == state) {
					offsetX = ConfigCenter.self_hand_card_W * turnScaleX;
					posX = (DdzApplication.getApplication().screenWidth - offsetX) / 2;
				} else {
					matrix.reset();
					matrix.postTranslate(posX, posY);
				}
				break;
			case MOVE:
				tmpCard = card;
				matrix.reset();
				valuse = new float[] { moveScaleX, 0, posX, 0, moveScaleY,
						posY, 0, 0, 1 };
				matrix.setValues(valuse);
				posX = (posX + sleep * moveStepVX);
				posY = (posY + sleep * moveStepVY);
				if (isCheckBoundary()) {
					this.deleteFlag = true;
				}

				moveScaleX = moveScaleX - (sleep) * moveScaleXV;
				moveScaleY = moveScaleY - (sleep) * moveScaleYV;
				if (moveScaleX <= desScaleX || moveScaleY <= desScaleY) {
					moveScaleX = desScaleX;
					moveScaleY = desScaleY;
				}
				break;
			}
			drawCard(canvas, matrix, tmpCard);
		}
	}

	/**
	 * 是否到达边界
	 * 
	 * @return
	 */
	public boolean isCheckBoundary() {
		boolean result = false;
		switch (dir) {
		case LEFT:
			if (posX <= desX && posY <= desY) {
				result = true;
			}
			break;
		case RIGHT:
			if (posX >= desX && posY <= desY) {
				result = true;
			}
			break;
		}
		return result;
	}

	public void initMoveData() {
		posX = startX;
		moveScaleX = 1;
		moveScaleY = 1;
		this.moveStepVX = (desX - startX) / (float) (lastTime - userTime);
		this.moveStepVY = (desY - startY) / (float) (lastTime - userTime);

		this.moveScaleXV = (ConfigCenter.out_card_W / (float) ConfigCenter.self_hand_card_W)
				/ (float) (lastTime - userTime);
		this.moveScaleYV = (ConfigCenter.out_card_H / (float) ConfigCenter.self_hand_card_H)
				/ (float) (lastTime - userTime);
	}

	public void drawCard(PCanvas canvas, Matrix matrix, Card card) {
		if (null == card)
			return;

		Bitmap bitmap = ResCenter.getCardImg(card);
		if (null == bitmap)
			return;

		canvas.drawBitmap(bitmap, matrix, null);
		if (card.isSmallLaizi()) {
			Bitmap flower = ResCenter.getFlower();
			if (flower != null) {
				canvas.drawBitmap(flower, matrix, null);
			}
		}
	}

	@Override
	public void unload() {
		desX = 0;
		desY = 0;
		moveStepVX = 0;
		moveStepVY = 0;
		moveScaleXV = 0;
		moveScaleYV = 0;
		posX = 0;
		posY = 0;

		turnScaleX = 1;

		offsetX = 0;
		dir = Dir.LEFT;
		userTime = 0;
		desScaleX = ConfigCenter.out_card_W
				/ (float) ConfigCenter.self_hand_card_W;
		desScaleY = ConfigCenter.out_card_H
				/ (float) ConfigCenter.self_hand_card_H;
		moveScaleX = 1;
		moveScaleY = 1;

		trunScaleXV = 0;
	}

	@Override
	public void overstatue() {
		this.deleteFlag = true;
	}
}
