package extend.mj.uitl;

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

import com.game.Util;
import extend.mj.Config;
import extend.mj.EXRoom;

public class WinCard {
	
	public int					pair_count;
	public Stack<List<Integer>>	stack;
	public List<Integer>		cardList;
	public int					zhong_count;
	public int					zhongid	= 0;
	public boolean				qidui;
	public static int 			zhongWinNum = 4;		

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

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

	private boolean tryShunzi(int card) {
		if (card < 400 && card % 100 > 7) {
			return false;
		}
		if (Util.checkCard(card + 1, this.cardList) && Util.checkCard(card + 2, this.cardList)) {
			Util.removeCard(this.cardList, card, 1);
			Util.removeCard(this.cardList, card + 1, 1);
			Util.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);
			return true;
		}
		return false;
	}

	private boolean tryKezi(int card) {

		if (Util.checkCardAndRomve(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);
			return true;
		}
		return false;

	}

	private boolean tryPair(int card) {
		if (this.pair_count > 0) {
			return false;
		}

		if (Util.checkCardAndRomve(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;
			return true;
		}
		return false;

	}

	private boolean tryKezi1Zhong(int card) {

		if (this.zhong_count >= 1 && Util.checkCardAndRomve(card, this.cardList,2)) {
//			CardUtil.removeCard(this.cardList, card, 2);
			List<Integer> cardGroup = new ArrayList<Integer>();
			cardGroup.add(card);
			cardGroup.add(card);
			cardGroup.add(this.zhongid);
			this.zhong_count -= 1;
			this.push(cardGroup);
			return true;
		}
		return false;

	}

	private boolean tryKezi2Zhong(int card) {

		if (this.zhong_count >= 2 && Util.checkCardAndRomve(card, this.cardList,1)) {
//			CardUtil.removeCard(this.cardList, card, 1);
			List<Integer> cardGroup = new ArrayList<Integer>();
			cardGroup.add(card);
			cardGroup.add(this.zhongid);
			cardGroup.add(this.zhongid);
			this.zhong_count -= 2;
			this.push(cardGroup);
			return true;
		}
		return false;

	}

	private boolean tryShunzi1Zhong(int card) {
		if (card % 100 > 8) {
			return false;
		}

		if (this.zhong_count < 1) {
			return false;
		}

		if (Util.checkCard(card + 1, this.cardList)) {
			Util.removeCard(cardList, card, 1);
			Util.removeCard(cardList, card + 1, 1);
			this.zhong_count -= 1;
			List<Integer> cardGroup = new ArrayList<Integer>();
			cardGroup.add(card);
			cardGroup.add(card + 1);
			cardGroup.add(this.zhongid);
			this.push(cardGroup);
			return true;
		}

		if (Util.checkCard(card + 2, this.cardList) && ((card + 1) % 100 != 0)) {
			Util.removeCard(cardList, card, 1);
			Util.removeCard(cardList, card + 2, 1);
			this.zhong_count -= 1;
			List<Integer> cardGroup = new ArrayList<Integer>();
			cardGroup.add(card);
			cardGroup.add(this.zhongid);
			cardGroup.add(card + 2);
			this.push(cardGroup);
			return true;
		}

		return false;

	}

	private boolean tryPair1Zhong(int card) {

		if (this.pair_count > 0) {
			return false;
		}
		if (this.zhong_count < 1) {
			return false;
		}
		Util.removeCard(cardList, card, 1);
		List<Integer> cardGroup = new ArrayList<Integer>();
		cardGroup.add(card);
		cardGroup.add(this.zhongid);
		this.push(cardGroup);
		this.zhong_count -= 1;
		this.pair_count = 1;
		return true;

	}

	private boolean tryPair2Zhong() {

		if (this.pair_count > 0) {
			return false;
		}
		if (this.zhong_count < 2) {
			return false;
		}
		List<Integer> cardGroup = new ArrayList<Integer>();
		cardGroup.add(this.zhongid);
		cardGroup.add(this.zhongid);
		this.push(cardGroup);
		this.pair_count = 1;
		this.zhong_count -= 2;
		return true;
	}

	public boolean tryWin(EXRoom room) {
		if (room.config.getBoolean(Config.ROOM_CONFIG_LAIZI4_HU))
		{
			if (this.zhong_count == zhongWinNum) {
				return true;
			}
		}

		if (this.cardList.size() == 0 && this.pair_count == 1) {
			return true;
		}
		if (this.cardList.size() == 0 && this.pair_count == 0) {
			return tryPair2Zhong();
		}

		if (this.cardList.size() == 0) {
			return false;
		}
		int activeCard = this.cardList.get(0);

		if (tryPair(activeCard)) {
			if (tryWin(room)) {
				return true;
			}
			this.pair_count = 0;
			this.rollBack();

		}

		if (tryKezi(activeCard)) {
			if (tryWin(room)) {
				return true;
			}
			this.rollBack();

		}
		if (tryShunzi(activeCard)) {
			if (tryWin(room)) {
				return true;
			}
			this.rollBack();

		}

		if (tryKezi1Zhong(activeCard)) {
			if (tryWin(room)) {
				return true;
			}
			this.rollBack();

		}
		if (tryKezi2Zhong(activeCard)) {
			if (tryWin(room)) {
				return true;
			}
			this.rollBack();

		}
		if (tryShunzi1Zhong(activeCard)) {
			if (tryWin(room)) {
				return true;
			}
			this.rollBack();

		}
		if (tryPair1Zhong(activeCard)) {
			if (tryWin(room)) {
				return true;
			}
			this.pair_count = 0;
			this.rollBack();
		}
		return false;
	}

	public WinCard(List<Integer> cardInhand, int addCard, int zhongid, boolean isZhong, boolean qidui) {
		this.stack = new Stack<List<Integer>>();
		this.cardList = new ArrayList<Integer>();
		this.cardList.addAll(cardInhand);
		this.qidui = qidui;
		this.cardList.add(addCard);
		if (isZhong) {
			this.zhongid = zhongid;
			this.zhong_count = Util.cardNum(zhongid, this.cardList);
			Util.removeCard(this.cardList, zhongid, this.zhong_count);
		}
		Collections.sort(this.cardList);
	}

	public WinCard(List<Integer> cardInhand, int zhongid, boolean isZhong, boolean qidui) {
		this.stack = new Stack<List<Integer>>();
		this.cardList = new ArrayList<Integer>();
		this.qidui = qidui;
		this.cardList.addAll(cardInhand);
		if (isZhong) {
			this.zhongid = zhongid;
			this.zhong_count = Util.cardNum(zhongid, this.cardList);
			Util.removeCard(this.cardList, zhongid, this.zhong_count);
		}
		Collections.sort(this.cardList);

	}

	public boolean checkQidui() {
		if (!this.qidui)
			return false;
		if ((this.cardList.size() + zhong_count) != 14)
			return false;
		List<Integer> cardlist = new ArrayList<>();
		cardlist.addAll(this.cardList);
		hongzhong_count = this.zhong_count;
		return isQdPari(cardlist);
	}

	private int hongzhong_count = 0;
	private int qidui_pari_count = 0;
	boolean isQdPari(List<Integer> cardlist) {
		if(qidui_pari_count == 7)return true;
		if (cardlist.size() == 0)return true;
		int card = cardlist.get(0);
		if (Util.cardNum(card, cardlist) >= 2) {
			Util.removeCard(cardlist, card, 2);
			qidui_pari_count++;
			if (isQdPari(cardlist)) {
				return true;
			}
		}

		if (this.hongzhong_count > 0) {
			Util.removeCard(cardlist, card, 1);
			this.hongzhong_count--;
			qidui_pari_count++;
			if (isQdPari(cardlist)) {
				return true;
			}
		}
		return false;

	}

	 public static void main(String[] args) {
	
	
		 long time = System.currentTimeMillis();
//		 for(int i=0;i<1000000;++i) {
		 ArrayList<Integer> cardInhand = new ArrayList<Integer>();
		 cardInhand.add(101);
		 cardInhand.add(102);
		 cardInhand.add(103);
		 cardInhand.add(104);
		 cardInhand.add(105);
		 cardInhand.add(106);
		 
		 cardInhand.add(204);
		 cardInhand.add(205);
		 cardInhand.add(206);
		 cardInhand.add(201);
		 cardInhand.add(202);
		 cardInhand.add(203);
		 
		 cardInhand.add(301);
		 cardInhand.add(301);
		 cardInhand.add(301);
		 cardInhand.add(108);
		 WinCard win = new WinCard(cardInhand,45,45,true,false);
//		 }
		 System.out.println( System.currentTimeMillis() - time);
	 }

}
