package com.backfire.room.data;

import java.util.ArrayList;
import java.util.List;

import com.backfire.arithmetic.Card;
import com.backfire.socket.socketProto.Doudizhu.CardInfo;

public class RoomInfo {

	public static enum Megagame {
		OTHER, BIG_PRIZE
	}

	public static enum GameType {
		HAPPY, LAIZI, SUPER_LAIZI, PERSONAL, MEGAGAME
	}

	// 全局的单例对象
	private static RoomInfo roominfo = null;
	private Player[] players = null; // 三个座位上的用户,数值下表代表用户座位号

	// private int roomId = 0; // 房间ID
	// private int roomType = 0; // 房间类型
	private int gameNum = 0; // 房间内第N局牌次
	private int basepoint = 0; // 底注
	private int ratio = 1; // 当前倍率
	private int currRatio = 1; // 用户出发倍率

	private int accessMoney = 0; // 准入

	private int readytimeout = 0; // 准备超时
	private int qiangDiZhuTimeout = 0; // 抢地主超时，抢庄
	private int operatetimeout = 0; // 操作超时，抢庄、出牌

	// 请求状态
	private boolean isSendReqing = false;

	private int state = -1; // －1代表加载，0代表还未做任何操作阶段，1代表准备阶段，2代表抢庄阶段，3代表玩牌阶段，4代表结算阶段,5再战阶段

	private Card[] commcard = null; // 三张底牌
	private Card[] laizi = null; // 一副牌里面最多3个癞子牌

	private int seatId = 0; // 自己的座位号
	private int dizhuId = 0; // 底注座位号
	private int callCount = 0; // 抢地主的次数

	private ArrayList<Card> myCards = null; // 自己的手里牌
	// private List<Card> selectCardList =null; //选中的牌

	private int currentActionSeatId = 0; // 当前操作的seatId

	private int lastOutCardSeatId = 0; // 上一个出牌玩家的座位号
	private int curSeatId = 0; // 当前出牌玩家的座位号
	private ArrayList<Card> lastOutCards = null; // 上一个出牌玩家出的牌
	private int lastOutCardType = 0; // 上一个出牌玩家的牌型
	private int lastOutHighcard = 0; // 上一个出牌玩家的主牌型的最大牌

	private boolean isResetDataFinish = true; // 重置游戏是否完成

	private boolean isLastLaiziSeaCardDisplay = false;
	private boolean isRefight = false;

	private int awardRoom = 0; // 大奖赛场 1是大奖赛，0为其他
	private int laiziFlag = 0; // 是否癞子场，0是普通场，1是普通癞子，2是超级癞子

	/** 是否重连过程中 */
	private boolean isRebinding = false;

	private String roomName = null;

	public boolean isResetDataFinish() {
		return isResetDataFinish;
	}

	public void setResetDataFinish(boolean isResetDataFinish) {
		this.isResetDataFinish = isResetDataFinish;
	}

	private RoomInfo() {
		if (null == players)
			players = new Player[3];
		if (null == commcard)
			commcard = new Card[3];
		if (null == laizi)
			laizi = new Card[3];
		if (null == myCards)
			myCards = new ArrayList<Card>();
		if (null == lastOutCards)
			lastOutCards = new ArrayList<Card>();
	}

	public static RoomInfo getInstance() {
		if (roominfo == null) {
			roominfo = new RoomInfo();
		}
		return roominfo;
	}

	public void clearAll() {
		removeAllPlayer();

		// roomId = 0;
		// roomType = 0;
		gameNum = 0;
		basepoint = 0;
		ratio = 1;
		currRatio = 1;
		accessMoney = 0;
		readytimeout = 0;
		qiangDiZhuTimeout = 0;
		operatetimeout = 0;
		state = -1;

		removeAllCommonCard();
		removeAllLaizi();

		seatId = 0;
		dizhuId = 0;
		callCount = 0;

		removeAllHandCard();

		lastOutCardSeatId = 0;
		curSeatId = 0;

		lastOutCards.clear();

		lastOutCardType = 0;
		lastOutHighcard = 0;

		isLastLaiziSeaCardDisplay = false;
		isRefight = false;

		isRebinding = false;
		roomName = null;
	}

	public int getAccessMoney() {
		return accessMoney;
	}

	public void setAccessMoney(int accessMoney) {
		this.accessMoney = accessMoney;
	}

	// 清除自己的信息
	public void clear() {
		removeOtherPlayer();

		// roomId = 0;
		basepoint = 0;
		ratio = 1;
		currRatio = 1;
		readytimeout = 0;
		qiangDiZhuTimeout = 0;
		operatetimeout = 0;
		isSendReqing = false;
		state = 0;

		removeAllCommonCard();
		removeAllLaizi();

		seatId = 0;
		dizhuId = 0;
		callCount = 0;

		removeAllHandCard();

		currentActionSeatId = 0;

		lastOutCardSeatId = 0;
		curSeatId = 0;

		removeAllLastOutCard();

		lastOutCardType = 0;
		lastOutHighcard = 0;

		isLastLaiziSeaCardDisplay = false;
		isRebinding = false;
		roomName = null;
	}

	private void removeOtherPlayer() {
		if (players == null)
			return;
		synchronized (players) {
			for (int i = 0; i < players.length; i++) {
				Player player = players[i];
				if (player != null) {
					synchronized (player) {
						if (player.getSeatId() == seatId) {
							players[i].clear();
						} else {
							players[i].clearAll();
							players[i] = null;
						}
					}
				}
			}
		}
	}

	private void removeAllHandCard() {
		if (null == myCards)
			return;
		synchronized (myCards) {
			myCards.clear();
		}
	}

	private void removeAllLastOutCard() {
		if (null == lastOutCards)
			return;
		synchronized (lastOutCards) {
			lastOutCards.clear();
		}
	}

	private void removeAllLaizi() {
		if (laizi == null)
			return;
		synchronized (laizi) {
			for (int i = 0; i < laizi.length; i++) {
				Card card = laizi[i];
				if (card != null) {
					laizi[i] = null;
				}
			}
		}
	}

	public void removeAllPlayer() {
		if (players == null)
			return;
		synchronized (players) {
			for (int i = 0; i < players.length; i++) {
				Player player = players[i];
				if (player != null) {
					synchronized (player) {
						players[i].clearAll();
						players[i] = null;
					}
				}
			}
		}
	}

	public void removeAllCommonCard() {
		if (commcard == null)
			return;
		synchronized (commcard) {
			for (int i = 0; i < commcard.length; i++) {
				Card card = commcard[i];
				if (card != null) {
					commcard[i] = null;
				}
			}
		}
	}

	// 移除用户
	public void removePlayer(int seatId) {
		if (seatId < 3 && seatId >= 0) {
			synchronized (players) {
				Player player = players[seatId - 1];
				if (player != null) {
					synchronized (player) {
						player.clearAll();
					}
					player = null;
				}
				players[seatId - 1] = null;
			}
		}
	}

	// 添加用户
	public void addPlayer(int seatId, Player player) {
		removePlayer(seatId);
		if (seatId <= 3 && seatId > 0) {
			synchronized (players) {
				players[seatId - 1] = player;
			}
		}
	}

	public int getSeatIdx(int seatId) {
		int result = seatId - 1 + rotatePosition();
		return result % 3;
	}

	public Player getPlayer(int seatId) {
		if (seatId <= 3 && seatId > 0) {
			synchronized (players) {
				return players[seatId - 1];
			}
		}
		return null;
	}

	public int getPlayerCnt() {
		if (null == players)
			return 0;
		int result = 0;
		synchronized (players) {
			for (Player player : players) {
				if (null != player) {
					result++;
				}
			}
		}
		return result;
	}

	public synchronized int getLastOutCardType() {
		return lastOutCardType;
	}

	public synchronized void setLastOutCardType(int lastOutCardType) {
		this.lastOutCardType = lastOutCardType;
	}

	public synchronized int getLastOutCardSeatId() {
		return lastOutCardSeatId;
	}

	public synchronized void setLastOutCardSeatId(int lastOutCardSeatId) {
		this.lastOutCardSeatId = lastOutCardSeatId;
	}

	public Player getSelfPlayer() {
		if (null == players)
			return null;
		synchronized (players) {
			return players[Math.abs(seatId - 1) % 3];
		}
	}

	public boolean getSelfIsDeposit() {
		int seatIdx = Math.abs(seatId - 1) % 3;

		if (null == players || seatIdx >= players.length
				|| null == players[seatIdx])
			return false;
		synchronized (players) {
			return players[seatIdx].isDeposit();
		}
	}

	public int getPlayerLength() {
		synchronized (players) {
			return players.length;
		}
	}

	public void setPlayers(Player[] players) {
		this.players = players;
	}

	// public int getRoomId() {
	// return roomId;
	// }
	//
	// public void setRoomId(int roomId) {
	// this.roomId = roomId;
	// }
	//
	// public int getRoomType() {
	// return roomType;
	// }
	//
	// public void setRoomType(int roomType) {
	// this.roomType = roomType;
	// }

	public int getGameNum() {
		return gameNum;
	}

	public void setGameNum(int gameNum) {
		this.gameNum = gameNum;
	}

	public int getBasepoint() {
		return basepoint;
	}

	public void setBasepoint(int basepoint) {
		this.basepoint = basepoint;
	}

	public int getRatio() {
		return ratio;
	}

	public void setRatio(int ratio) {
		this.ratio = ratio;
	}

	public int getReadytimeout() {
		return readytimeout;
	}

	public void setReadytimeout(int readytimeout) {
		this.readytimeout = readytimeout;
	}

	public int getOperatetimeout() {
		return operatetimeout;
	}

	public void setOperatetimeout(int operatetimeout) {
		this.operatetimeout = operatetimeout;
	}

	public int getState() {
		return state;
	}

	public void setState(int state) {
		this.state = state;
	}

	public int getSelfPlayerState() {
		int result = -1;
		if (null == players)
			return result;

		synchronized (players) {
			Player player = players[Math.abs(seatId - 1) % 3];
			if (null != player) {
				synchronized (player) {
					result = player.getState();
				}
			}
		}
		return result;
	}

	public Card[] getCommcard() {
		return commcard;
	}

	public void setCommcard(Card[] commcard) {
		this.commcard = commcard;
	}

	public Card[] getLaizi() {
		return laizi;
	}

	public Card getLaizi(int index) {
		if (index >= 0 && index < laizi.length) {
			return laizi[index];
		} else {
			return null;
		}
	}

	public static int getLastLaiziIndex(Card[] cards) {
		int index = 0;
		if (cards != null) {
			for (int i = 0; i < cards.length; i++) {
				if (cards[i] != null) {
					index = i;
				}
			}
		}
		return index;
	}

	public void addLaizi(Card card) {
		if (laizi != null) {
			synchronized (laizi) {
				for (int i = 0; i < laizi.length; i++) {
					if (laizi[i] == null) {
						laizi[i] = card;
						break;
					}
				}
			}
		}
	}

	public int getLaiziCnt() {
		int result = 0;
		if (null == laizi)
			return result;
		synchronized (laizi) {
			for (int i = 0; i < laizi.length; i++) {
				if (null == laizi[i]) {
					continue;
				}
				result++;
			}
		}
		return result;
	}

	public int getSeatId() {
		return seatId;
	}

	public void setSeatId(int seatId) {
		this.seatId = seatId;
	}

	public int getSeatId(int seatIdx) {
		int result = 0;
		if (null == players)
			return result;

		synchronized (players) {
			for (int i = 0; i < players.length; i++) {
				Player player = players[i];
				if (null == player)
					continue;

				synchronized (player) {
					int tmpSeatId = player.getSeatId();
					int tmpSeatIdx = getSeatIdx(seatId);// getSeatId和seatIdx同时加this锁就完蛋了
					if (seatIdx == tmpSeatIdx) {
						result = tmpSeatId;
						break;
					}
				}
			}
		}
		return result;
	}

	public ArrayList<Card> getMyCards() {
		return myCards;
	}

	public void setMyCards(ArrayList<Card> myCards) {
		this.myCards = myCards;
	}

	public int getCurSeatId() {
		return curSeatId;
	}

	public void setCurSeatId(int curSeatId) {
		this.curSeatId = curSeatId;
	}

	public int getPreSeatId() {
		int preSeatId = 0;
		if (0 != currentActionSeatId) {
			if (currentActionSeatId > 1) {
				preSeatId = currentActionSeatId - 1;
			} else {
				preSeatId = 3;
			}
		}
		return preSeatId;
	}

	public int getPreSeatId(int seatId) {
		int preSeatId = 1;
		if (seatId > 1) {
			preSeatId = seatId - 1;
		} else {
			preSeatId = 3 - seatId + 1;
		}
		return Math.abs(preSeatId % 4);
	}

	public int getNextSeatId(int seatId) {
		int nextSeatId = 1;
		if (seatId < 3) {
			nextSeatId = seatId + 1;
		} else {
			nextSeatId = seatId - 3 + 1;
		}
		return Math.abs(nextSeatId % 4);
	}

	public ArrayList<Card> getLastOutCards() {
		return lastOutCards;
	}

	public void setLastOutCards(ArrayList<Card> lastOutCards) {
		this.lastOutCards = lastOutCards;
	}

	public int getLastOutHighcard() {
		return lastOutHighcard;
	}

	public void setLastOutHighcard(int lastOutHighcard) {
		this.lastOutHighcard = lastOutHighcard;
	}

	public int getQiangDiZhuTimeout() {
		return qiangDiZhuTimeout;
	}

	public void setQiangDiZhuTimeout(int qiangDiZhuTimeout) {
		this.qiangDiZhuTimeout = qiangDiZhuTimeout;
	}

	public int getDizhuId() {
		return dizhuId;
	}

	public void setDizhuId(int dizhuId) {
		this.dizhuId = dizhuId;
	}

	public int getCallCount() {
		return callCount;
	}

	public void setCallCount(int callCount) {
		this.callCount = callCount;
	}

	public boolean isSendReqing() {
		return isSendReqing;
	}

	public void setSendReqing(boolean isSendReqing) {
		this.isSendReqing = isSendReqing;
	}

	public int getCurrentActionSeatId() {
		return currentActionSeatId;
	}

	public void setCurrentActionSeatId(int currentActionSeatId) {
		this.currentActionSeatId = currentActionSeatId;
	}

	/**
	 * 重置农民的之前的操作状态
	 */
	public void resetPeasentSeatIdOperatAction() {
		if (null == players)
			return;
		synchronized (players) {
			for (Player player : players) {
				if (null == player)
					return;
				synchronized (player) {
					if (player.getSeatId() != dizhuId) {
						player.setOperateAction(0);
					}
				}
			}
		}
	}

	public int rotatePosition() {
		int offsetPos = 0;
		if (seatId >= 1 && seatId <= 3) {
			// 自己的seatIdx!=0，不再第1个位置,就旋转
			if (seatId != 3) {
				offsetPos = 3 - seatId;
			}
		}
		return offsetPos;
	}

	public void removeCard(Card other) {
		if (myCards == null || other == null)
			return;
		synchronized (myCards) {
			for (int i = 0; i < myCards.size(); i++) {
				Card card = myCards.get(i);
				if (0 == card.comparePoint(other)) {
					myCards.remove(card);
				}
			}
		}
	}

	public void setLaiZiCard(Card card) {
		// 遍历设置自己的手牌癞子
		if (null != myCards) {
			synchronized (myCards) {
				for (Card ci : myCards) {
					if (card.isEqualTo(ci)) {
						ci.setIsLaiZi(true);
						ci.setSmallLaizi(true);
						break;
					}
				}
			}
		}
	}

	public void updateLaiziCard(Card card) {
		// 遍历设置自己的手牌癞子
		if (null != myCards) {
			synchronized (myCards) {
				for (Card ci : myCards) {
					if (ci.getPoint() == card.getPoint()) {
						ci.setIsLaiZi(true);
					}
				}
			}
		}
	}

	public int getCurrRatio() {
		return currRatio;
	}

	public void setCurrRatio(int currRatio) {
		this.currRatio = currRatio;
	}

	public List<CardInfo> getSelectCardInfoList(List<Card> selectCardList) {
		List<CardInfo> cardInfos = new ArrayList<CardInfo>();
		if (null != myCards && null != selectCardList) {
			synchronized (selectCardList) {
				for (Card card : selectCardList) {
					CardInfo.Builder builder = CardInfo.newBuilder();
					builder.setCardSuit(card.getColor());
					builder.setCardFace(card.getPoint());
					builder.setLaiziFace(card.isLaiZi() ? card.getPoint() : 0);
					CardInfo cardInfo = builder.build();
					cardInfos.add(cardInfo);
				}
			}
		}
		return cardInfos;
	}

	public void updateSendReq(int rpySeatId) {
		if (this.seatId == rpySeatId) {
			isSendReqing = false;
		}
	}

	public boolean isLastLaiziSeaCardDisplay() {
		return isLastLaiziSeaCardDisplay;
	}

	public void setLastLaiziSeaCardDisplay(boolean isLastLaiziSeaCardDisplay) {
		this.isLastLaiziSeaCardDisplay = isLastLaiziSeaCardDisplay;
	}

	public boolean isRefight() {
		return isRefight;
	}

	public void setRefight(boolean isRefight) {
		this.isRefight = isRefight;
	}

	public int getAwardRoom() {
		return awardRoom;
	}

	public int getLaiziFlag() {
		return laiziFlag;
	}

	public void setAwardRoom(int awardRoom) {
		this.awardRoom = awardRoom;
	}

	public void setLaiziFlag(int laiziFlag) {
		this.laiziFlag = laiziFlag;
	}

	public Megagame getMegagame() {
		Megagame megagame = Megagame.OTHER;
		if (Megagame.BIG_PRIZE.ordinal() == awardRoom) {
			megagame = Megagame.BIG_PRIZE;
		}
		return megagame;
	}

	public boolean isLaiziType() {
		boolean result = false;
		if (GameType.LAIZI.ordinal() == laiziFlag
				|| GameType.SUPER_LAIZI.ordinal() == laiziFlag) {
			result = true;
		}
		return result;
	}

	public GameType getGameType() {
		GameType gameType = GameType.HAPPY;
		if (GameType.HAPPY.ordinal() == laiziFlag) {
			gameType = GameType.HAPPY;
		} else if (GameType.LAIZI.ordinal() == laiziFlag) {
			gameType = GameType.LAIZI;
		} else if (GameType.SUPER_LAIZI.ordinal() == laiziFlag) {
			gameType = GameType.SUPER_LAIZI;
		}
		return gameType;
	}

	public boolean isRebinding() {
		return isRebinding;
	}

	public void setRebinding(boolean isRebinding) {
		this.isRebinding = isRebinding;
	}

	public String getRoomName() {
		return roomName;
	}

	public void setRoomName(String roomName) {
		this.roomName = roomName;
	}
}
