package extend.zp.uitl;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Stack;

import com.game.Global;
import extend.zp.EXPlayer;
import extend.zp.OpCard;
import extend.zp.RuleWeight;

public class WinCard {
	public int					pair_count;
	public int					long_count;
	public Stack<List<Integer>>	stack;
	public Stack<Integer>		stackHuxi;
	public List<Integer>		cardList;
	public int					drawCard;

	private void push(List<Integer> cardGroup) {
		this.stack.push(cardGroup);
	}

	private void rollBack() {
		List<Integer> cardGroup = this.stack.pop();
		for (Integer card : cardGroup) {
			this.cardList.add(card);
		}
		Collections.sort(this.cardList);
	}

	private boolean tryKezi(int card, EXPlayer player) {
		if (CardUtil.cardNum(card, this.cardList) >= 3) {
			CardUtil.removeCard(this.cardList, card, 3);
			List<Integer> cardGroup = new ArrayList<Integer>();
			cardGroup.add(card);
			cardGroup.add(card);
			cardGroup.add(card);
			this.push(cardGroup);
			int huXi = 0;
			if (player.getRoom().isTianHu && card == player.getRoom().drawCard) {
				huXi = Paixing.caclHuxi(RuleWeight.TYPE_KAN, card);
			} else {
				boolean flag = false;
				for (int i = 0; i < player.tiGroup.size(); i++) {
					int ti_card = player.tiGroup.get(i)[0];
					if (ti_card == card)
					{
						flag = true;
					}
				}
				if (flag)
				{
					huXi = Paixing.caclHuxi(RuleWeight.TYPE_KAN, card);
				}
				else {
					if (card == player.getRoom().drawCard)
					{
						huXi = Paixing.caclHuxi(RuleWeight.TYPE_WEI, card);
					}
					else {
					    //不可能出现这种情况
						huXi = Paixing.caclHuxi(RuleWeight.TYPE_PONG, card);
					}
				}
			}
			player.huXi += huXi;
			this.stackHuxi.push(huXi);
			return true;
		}
		return false;
	}

	private boolean tryShunzi1(int card, EXPlayer player) {
		if (card < 200 && card % 100 > 8) {
			return false;
		}
		if (CardUtil.cardNum(card + 1, this.cardList) > 0 && CardUtil.cardNum(card + 2, this.cardList) > 0) {
			CardUtil.removeCard(this.cardList, card, 1);
			CardUtil.removeCard(this.cardList, card + 1, 1);
			CardUtil.removeCard(this.cardList, card + 2, 1);
			List<Integer> cardGroup = new ArrayList<Integer>();
			cardGroup.add(card);
			cardGroup.add(card + 1);
			cardGroup.add(card + 2);
			this.push(cardGroup);

			int huXi = 0;
			if (card % 100 == 1) {
				//huXi = Paixing.caclHuxi(RuleWeight.TYPE_CHOW, card);
				//player.huXi += huXi;
			}

			this.stackHuxi.push(huXi);
			return true;
		}
		return false;
	}

	private boolean tryShunzi2(int card) {
		if (CardUtil.cardType(card) == RuleWeight.SMALL_CARD) {
			if (CardUtil.cardNum(card + 100, this.cardList) >= 1 && CardUtil.cardNum(card, this.cardList) >= 2) {
				CardUtil.removeCard(this.cardList, card, 2);
				CardUtil.removeCard(this.cardList, card + 100, 1);
				List<Integer> cardGroup = new ArrayList<Integer>();
				cardGroup.add(card);
				cardGroup.add(card);
				cardGroup.add(card + 100);
				this.push(cardGroup);
				this.stackHuxi.push(0);
				return true;
			}
			if (CardUtil.cardNum(card + 100, this.cardList) >= 2) {
				CardUtil.removeCard(this.cardList, card, 1);
				CardUtil.removeCard(this.cardList, card + 100, 2);
				List<Integer> cardGroup = new ArrayList<Integer>();
				cardGroup.add(card);
				cardGroup.add(card + 100);
				cardGroup.add(card + 100);
				this.push(cardGroup);
				this.stackHuxi.push(0);
				return true;
			}
		} else {
			if (CardUtil.cardNum(card - 100, this.cardList) >= 1 && CardUtil.cardNum(card, this.cardList) >= 2) {
				CardUtil.removeCard(this.cardList, card, 2);
				CardUtil.removeCard(this.cardList, card - 100, 1);
				List<Integer> cardGroup = new ArrayList<Integer>();
				cardGroup.add(card);
				cardGroup.add(card);
				cardGroup.add(card - 100);
				this.push(cardGroup);
				this.stackHuxi.push(0);
				return true;
			}
			if (CardUtil.cardNum(card - 100, this.cardList) >= 2) {
				CardUtil.removeCard(this.cardList, card, 1);
				CardUtil.removeCard(this.cardList, card - 100, 2);
				List<Integer> cardGroup = new ArrayList<Integer>();
				cardGroup.add(card);
				cardGroup.add(card - 100);
				cardGroup.add(card - 100);
				this.push(cardGroup);
				this.stackHuxi.push(0);
				return true;
			}
		}
		return false;
	}

	private boolean tryShunzi3(int card, EXPlayer player) {
		if (card % 100 == 2) {
			if (CardUtil.cardNum(card + 5, this.cardList) > 0 && CardUtil.cardNum(card + 8, this.cardList) > 0) {
				CardUtil.removeCard(this.cardList, card, 1);
				CardUtil.removeCard(this.cardList, card + 5, 1);
				CardUtil.removeCard(this.cardList, card + 8, 1);
				List<Integer> cardGroup = new ArrayList<Integer>();
				cardGroup.add(card);
				cardGroup.add(card + 5);
				cardGroup.add(card + 8);
				this.push(cardGroup);

				int huXi = Paixing.caclHuxi(RuleWeight.TYPE_CHOW, card);
				player.huXi += huXi;
				this.stackHuxi.push(huXi);
				return true;
			}
		}
		return false;
	}

	private boolean isSanHao(int card, EXPlayer player)
	{
		int handNum = CardUtil.cardNum(card, player.cardInhand);
		for (int i = 0; i < player.chowGroup.size(); i++) {
			if (card == player.chowGroup.get(i)[0]) {
				handNum++;
			}
			if (card == player.chowGroup.get(i)[2]) {
				handNum++;
			}
		}

		//算出吃到的
		int chiNum = 1; //本次算一次
		for (int i = 0; i < player.chowGroup.size(); i++) {
			if (card == player.chowGroup.get(i)[1]) {
				chiNum++;
			}
		}

		if (handNum == 1 && chiNum == 3)
		{
			return true;
		}
		return false;
	}

	private boolean tryPair(int card, EXPlayer player) {
		if (this.pair_count > 0) {
			return false;
		}
		if (CardUtil.cardNum(card, this.cardList) >= 2) {
			CardUtil.removeCard(this.cardList, card, 2);
			List<Integer> cardGroup = new ArrayList<Integer>();
			cardGroup.add(card);
			cardGroup.add(card);
			this.push(cardGroup);
			this.pair_count = 1;
			player.huXi += 1;
			this.stackHuxi.push(1);
			return true;
		}
		else if (CardUtil.cardNum(card, this.cardList) >= 1) {
			if (card % 100 <= 9)
			{
				if (CardUtil.cardNum(card+1, this.cardList) >= 1) {
					CardUtil.removeCard(this.cardList, card, 1);
					CardUtil.removeCard(this.cardList, card+1, 1);
					List<Integer> cardGroup = new ArrayList<Integer>();
					cardGroup.add(card);
					cardGroup.add(card+1);
					this.push(cardGroup);
					this.pair_count = 1;
					this.stackHuxi.push(0);
					return true;
				}
			}
			if (card % 100 <= 8)
			{
				if (CardUtil.cardNum(card+2, this.cardList) >= 1) {
					CardUtil.removeCard(this.cardList, card, 1);
					CardUtil.removeCard(this.cardList, card+2, 1);
					List<Integer> cardGroup = new ArrayList<Integer>();
					cardGroup.add(card);
					cardGroup.add(card+2);
					this.push(cardGroup);
					this.pair_count = 1;
					this.stackHuxi.push(0);
					return true;
				}
			}
			if (card % 100 >= 2)
			{
				if (CardUtil.cardNum(card-1, this.cardList) >= 1) {
					CardUtil.removeCard(this.cardList, card, 1);
					CardUtil.removeCard(this.cardList, card-1, 1);
					List<Integer> cardGroup = new ArrayList<Integer>();
					cardGroup.add(card);
					cardGroup.add(card-1);
					this.push(cardGroup);
					this.pair_count = 1;
					this.stackHuxi.push(0);
					return true;
				}
			}

			if (card % 100 >= 3)
			{
				if (CardUtil.cardNum(card-2, this.cardList) >= 1) {
					CardUtil.removeCard(this.cardList, card, 1);
					CardUtil.removeCard(this.cardList, card-2, 1);
					List<Integer> cardGroup = new ArrayList<Integer>();
					cardGroup.add(card);
					cardGroup.add(card-2);
					this.push(cardGroup);
					this.pair_count = 1;
					this.stackHuxi.push(0);
					return true;
				}
			}

			if (card % 100 == 2)
			{
				if (CardUtil.cardNum(card + 5, this.cardList) >= 1) {
					CardUtil.removeCard(this.cardList, card, 1);
					CardUtil.removeCard(this.cardList, card + 5, 1);
					List<Integer> cardGroup = new ArrayList<Integer>();
					cardGroup.add(card);
					cardGroup.add(card + 5);
					this.push(cardGroup);
					this.pair_count = 1;
					player.huXi += 1;
					this.stackHuxi.push(1);
					return true;
				}

				if (CardUtil.cardNum(card + 8, this.cardList) >= 1) {
					CardUtil.removeCard(this.cardList, card, 1);
					CardUtil.removeCard(this.cardList, card + 8, 1);
					List<Integer> cardGroup = new ArrayList<Integer>();
					cardGroup.add(card);
					cardGroup.add(card + 8);
					this.push(cardGroup);
					this.pair_count = 1;
					player.huXi += 1;
					this.stackHuxi.push(1);
					return true;
				}
			}

			if (card % 100 == 7)
			{
				if (CardUtil.cardNum(card - 5, this.cardList) >= 1) {
					CardUtil.removeCard(this.cardList, card, 1);
					CardUtil.removeCard(this.cardList, card - 5, 1);
					List<Integer> cardGroup = new ArrayList<Integer>();
					cardGroup.add(card);
					cardGroup.add(card - 5);
					this.push(cardGroup);
					this.pair_count = 1;
					player.huXi += 1;
					this.stackHuxi.push(1);
					return true;
				}

				if (CardUtil.cardNum(card + 3, this.cardList) >= 1) {
					CardUtil.removeCard(this.cardList, card, 1);
					CardUtil.removeCard(this.cardList, card + 3, 1);
					List<Integer> cardGroup = new ArrayList<Integer>();
					cardGroup.add(card);
					cardGroup.add(card + 3);
					this.push(cardGroup);
					this.pair_count = 1;
					player.huXi += 1;
					this.stackHuxi.push(1);
					return true;
				}
			}

			if (card % 100 == 10)
			{
				if (CardUtil.cardNum(card - 8, this.cardList) >= 1) {
					CardUtil.removeCard(this.cardList, card, 1);
					CardUtil.removeCard(this.cardList, card - 8, 1);
					List<Integer> cardGroup = new ArrayList<Integer>();
					cardGroup.add(card);
					cardGroup.add(card - 8);
					this.push(cardGroup);
					this.pair_count = 1;
					player.huXi += 1;
					this.stackHuxi.push(1);
					return true;
				}

				if (CardUtil.cardNum(card - 3, this.cardList) >= 1) {
					CardUtil.removeCard(this.cardList, card, 1);
					CardUtil.removeCard(this.cardList, card - 3, 1);
					List<Integer> cardGroup = new ArrayList<Integer>();
					cardGroup.add(card);
					cardGroup.add(card - 3);
					this.push(cardGroup);
					this.pair_count = 1;
					player.huXi += 1;
					this.stackHuxi.push(1);
					return true;
				}
			}
		}
		return false;
	}

	private boolean tryPair2(int card, EXPlayer player) {
		if (this.pair_count > 0) {
			return false;
		}
		if (CardUtil.cardNum(card, this.cardList) >= 1) {
			if (card % 100 == 2)
			{
				if (CardUtil.cardNum(card + 5, this.cardList) >= 1) {
					CardUtil.removeCard(this.cardList, card, 1);
					CardUtil.removeCard(this.cardList, card + 5, 1);
					List<Integer> cardGroup = new ArrayList<Integer>();
					cardGroup.add(card);
					cardGroup.add(card + 5);
					this.push(cardGroup);
					this.pair_count = 1;
					player.huXi += 1;
					this.stackHuxi.push(1);
					return true;
				}

				if (CardUtil.cardNum(card + 8, this.cardList) >= 1) {
					CardUtil.removeCard(this.cardList, card, 1);
					CardUtil.removeCard(this.cardList, card + 8, 1);
					List<Integer> cardGroup = new ArrayList<Integer>();
					cardGroup.add(card);
					cardGroup.add(card + 8);
					this.push(cardGroup);
					this.pair_count = 1;
					player.huXi += 1;
					this.stackHuxi.push(1);
					return true;
				}
			}

			if (card % 100 == 7)
			{
				if (CardUtil.cardNum(card - 5, this.cardList) >= 1) {
					CardUtil.removeCard(this.cardList, card, 1);
					CardUtil.removeCard(this.cardList, card - 5, 1);
					List<Integer> cardGroup = new ArrayList<Integer>();
					cardGroup.add(card);
					cardGroup.add(card - 5);
					this.push(cardGroup);
					this.pair_count = 1;
					player.huXi += 1;
					this.stackHuxi.push(1);
					return true;
				}

				if (CardUtil.cardNum(card + 3, this.cardList) >= 1) {
					CardUtil.removeCard(this.cardList, card, 1);
					CardUtil.removeCard(this.cardList, card + 3, 1);
					List<Integer> cardGroup = new ArrayList<Integer>();
					cardGroup.add(card);
					cardGroup.add(card + 3);
					this.push(cardGroup);
					this.pair_count = 1;
					player.huXi += 1;
					this.stackHuxi.push(1);
					return true;
				}
			}

			if (card % 100 == 10)
			{
				if (CardUtil.cardNum(card - 8, this.cardList) >= 1) {
					CardUtil.removeCard(this.cardList, card, 1);
					CardUtil.removeCard(this.cardList, card - 8, 1);
					List<Integer> cardGroup = new ArrayList<Integer>();
					cardGroup.add(card);
					cardGroup.add(card - 8);
					this.push(cardGroup);
					this.pair_count = 1;
					player.huXi += 1;
					this.stackHuxi.push(1);
					return true;
				}

				if (CardUtil.cardNum(card - 3, this.cardList) >= 1) {
					CardUtil.removeCard(this.cardList, card, 1);
					CardUtil.removeCard(this.cardList, card - 3, 1);
					List<Integer> cardGroup = new ArrayList<Integer>();
					cardGroup.add(card);
					cardGroup.add(card - 3);
					this.push(cardGroup);
					this.pair_count = 1;
					player.huXi += 1;
					this.stackHuxi.push(1);
					return true;
				}
			}
		}
		return false;
	}

	public boolean tryWin(EXPlayer player) {
		if (this.cardList.size() == 0) {
			if (player.huXi < 8)
			{
				return false;
			}
			if (this.pair_count == 1)
			{
				return true;
			}
			else if (this.pair_count == 2 && this.stack.size() == 2)
			{
			    List<Integer> list = new ArrayList<Integer>();
				for (int i = 0; i < this.stack.size(); i++) {
					int card1 = this.stack.get(i).get(0);
					int card2 = this.stack.get(i).get(1);

					list.add(card1 % 100);
					list.add(card2 % 100);
				}

				if (list.size() != 4)
				{
					return false;
				}

				Collections.sort(list);

				if (list.get(0) == list.get(1)+1 && list.get(1) == list.get(2)+1 && list.get(2) == list.get(3)+1)
				{
					return true;
				}
			}
			return false;
		}
		int activeCard = 0;
		for (int card : this.cardList) {
			if (card == 201 || card == 202) {
				activeCard = card;
				break;
			}
		}
		if (activeCard == 0) {
			activeCard = this.cardList.get(0);
		}
		if (activeCard % 100 == 1) {
			if (tryShunzi1(activeCard, player)) {
				if (tryWin(player)) {
					return true;
				}
				this.rollBack();
				int huXi = this.stackHuxi.pop();
				if (huXi > 0) {
					player.huXi -= huXi;
				}
			}
			if (tryKezi(activeCard, player)) {
				if (tryWin(player)) {
					return true;
				}
				this.rollBack();
				int huXi = this.stackHuxi.pop();
				if (huXi > 0) {
					player.huXi -= huXi;
				}
			}
			if (tryPair(activeCard, player)) {
				if (tryWin(player)) {
					return true;
				}
				this.pair_count = 0;
				this.rollBack();
				int huXi = this.stackHuxi.pop();
				if (huXi > 0) {
					player.huXi -= huXi;
				}
			}
			if (tryPair2(activeCard, player)) {
				if (tryWin(player)) {
					return true;
				}
				this.pair_count = 0;
				this.rollBack();
				int huXi = this.stackHuxi.pop();
				if (huXi > 0) {
					player.huXi -= huXi;
				}
			}
		} else if (activeCard % 100 == 2) {
			if (tryShunzi3(activeCard, player)) {
				if (tryWin(player)) {
					return true;
				}
				this.rollBack();
				int huXi = this.stackHuxi.pop();
				if (huXi > 0) {
					player.huXi -= huXi;
				}
			}
			if (tryKezi(activeCard, player)) {
				if (tryWin(player)) {
					return true;
				}
				this.rollBack();
				int huXi = this.stackHuxi.pop();
				if (huXi > 0) {
					player.huXi -= huXi;
				}
			}
			if (tryPair(activeCard, player)) {
				if (tryWin(player)) {
					return true;
				}
				this.pair_count = 0;
				this.rollBack();
				int huXi = this.stackHuxi.pop();
				if (huXi > 0) {
					player.huXi -= huXi;
				}
			}
			if (tryPair2(activeCard, player)) {
				if (tryWin(player)) {
					return true;
				}
				this.pair_count = 0;
				this.rollBack();
				int huXi = this.stackHuxi.pop();
				if (huXi > 0) {
					player.huXi -= huXi;
				}
			}
			if (tryShunzi1(activeCard, player)) {
				if (tryWin(player)) {
					return true;
				}
				this.rollBack();
				int huXi = this.stackHuxi.pop();
				if (huXi > 0) {
					player.huXi -= huXi;
				}
			}
			/*if (tryShunzi2(activeCard)) {
				if (tryWin(player)) {
					return true;
				}
				this.rollBack();
				this.stackHuxi.pop();
			}
			 */
		} else {
			if (tryKezi(activeCard, player)) {
				if (tryWin(player)) {
					return true;
				}
				this.rollBack();
				int huXi = this.stackHuxi.pop();
				if (huXi > 0) {
					player.huXi -= huXi;
				}
			}
			if (tryPair(activeCard, player)) {
				if (tryWin(player)) {
					return true;
				}
				this.pair_count = 0;
				this.rollBack();
				int huXi = this.stackHuxi.pop();
				if (huXi > 0) {
					player.huXi -= huXi;
				}
			}
			if (tryPair2(activeCard, player)) {
				if (tryWin(player)) {
					return true;
				}
				this.pair_count = 0;
				this.rollBack();
				int huXi = this.stackHuxi.pop();
				if (huXi > 0) {
					player.huXi -= huXi;
				}
			}
			if (tryShunzi1(activeCard, player)) {
				if (tryWin(player)) {
					return true;
				}
				this.rollBack();
				int huXi = this.stackHuxi.pop();
				if (huXi > 0) {
					player.huXi -= huXi;
				}
			}
			/*
			if (tryShunzi2(activeCard)) {
				if (tryWin(player)) {
					return true;
				}
				this.rollBack();
				this.stackHuxi.pop();
			}
			 */
		}

		return false;
	}

	public WinCard(EXPlayer player, List<Integer> cardInhand, int addCard) {
		this.stack = new Stack<List<Integer>>();
		this.stackHuxi = new Stack<Integer>();
		this.cardList = new ArrayList<Integer>();
		this.cardList.addAll(cardInhand);
		for (int i = 0; i < player.tiGroup.size(); i++) {
			int card = player.tiGroup.get(i)[0];
			this.cardList.add(card);
			this.cardList.add(card);
			this.cardList.add(card);
			this.cardList.add(card);
		}
		if (addCard > 0) {
			this.cardList.add(addCard);
		}
		this.drawCard = addCard;
		Collections.sort(this.cardList);
	}
}
