package extend.mj;

import com.game.Global;
import com.game.Util;
import com.game.data.Player;
import com.game.data.Room;
import com.game.player.state.PlayerWaitState;
import com.taurus.core.entity.ITObject;
import extend.mj.player.state.EXPlayerDisCardTipState;
import extend.mj.tip.Action;
import extend.mj.tip.TipManager;
import extend.mj.uitl.WinCard;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

public class EXRoom extends Room {

	//
	public Map<Integer, TipManager>	tipMap;
	public List<Action>				actionList;

	public RoomCard					card;

	public int						activeCard;
	public int						currenDiscardSeat;
	public int						lastDiscardSeat;
	public int						winCount	= 0;
	public boolean					liuju		= false;
	public boolean					last_liuju	= false;

	public boolean					activeHaidi			= false;
	public int						haidiCard;

	public OpenKong					activeKong			= null;

	public int                      adminSeat  = 0;
	public int  					lastWinPlayerId = 0;
	public boolean 					isGengZhuang = false;
	public int						first_zhuang_card = 0;
	public int						geng_zhuan_num = 0;
	public int						gent_zhuan_nextSeat = 0;

	public int                      gangnum = 0;
	public int                      gangzi1 = 0;
	public int                      gangzi2 = 0;
	/*
	 * 上一次庄家座位号
	 */
	public int 						lastBankerSeat = 0;

	public EXRoom(String roomid, Map<String, String> redis_room_map) {
		super(roomid, redis_room_map);
		card = new RoomCard(this);

		this.tipMap = new HashMap<Integer, TipManager>();
		this.actionList = new ArrayList<Action>();

		if (!this.config.containsKey(Config.ROOM_CONFIG_DIANPAO))
		{
			this.config.putBoolean(Config.ROOM_CONFIG_DIANPAO, false);
		}
		if (!this.config.containsKey(Config.ROOM_CONFIG_HUNYISE))
		{
			this.config.putBoolean(Config.ROOM_CONFIG_HUNYISE, false);
		}

		if (!this.config.containsKey(Config.ROOM_CONFIG_QINGYISE))
		{
			this.config.putBoolean(Config.ROOM_CONFIG_QINGYISE, false);
		}
		if (!this.config.containsKey(Config.ROOM_CONFIG_PENGPENGHU))
		{
			this.config.putBoolean(Config.ROOM_CONFIG_PENGPENGHU, false);
		}
		if (!this.config.containsKey(Config.ROOM_CONFIG_QIDUI))
		{
			this.config.putBoolean(Config.ROOM_CONFIG_QIDUI, false);
		}
		if (!this.config.containsKey(Config.ROOM_CONFIG_HAOHUA_QIDUI))
		{
			this.config.putBoolean(Config.ROOM_CONFIG_HAOHUA_QIDUI, false);
		}
		if (!this.config.containsKey(Config.ROOM_CONFIG_HAOHUA2_QIDUI))
		{
			this.config.putBoolean(Config.ROOM_CONFIG_HAOHUA2_QIDUI, false);
		}
		if (!this.config.containsKey(Config.ROOM_CONFIG_HAOHUA3_QIDUI))
		{
			this.config.putBoolean(Config.ROOM_CONFIG_HAOHUA3_QIDUI, false);
		}
		if (!this.config.containsKey(Config.ROOM_CONFIG_GANGSHANGKAIHUA_2bei))
		{
			this.config.putBoolean(Config.ROOM_CONFIG_GANGSHANGKAIHUA_2bei, false);
		}
		if (!this.config.containsKey(Config.ROOM_CONFIG_SHISHANGYAO))
		{
			this.config.putBoolean(Config.ROOM_CONFIG_SHISHANGYAO, false);
		}
		if (!this.config.containsKey(Config.ROOM_CONFIG_TIANDIHU))
		{
			this.config.putBoolean(Config.ROOM_CONFIG_TIANDIHU, false);
		}
		if (!this.config.containsKey(Config.ROOM_CONFIG_SHIBALUOHAN))
		{
			this.config.putBoolean(Config.ROOM_CONFIG_SHIBALUOHAN, false);
		}
		if (!this.config.containsKey(Config.ROOM_CONFIG_XIAOSHANYUAN))
		{
			this.config.putBoolean(Config.ROOM_CONFIG_XIAOSHANYUAN, false);
		}
		if (!this.config.containsKey(Config.ROOM_CONFIG_DASHANYUAN))
		{
			this.config.putBoolean(Config.ROOM_CONFIG_DASHANYUAN, false);
		}
		if (!this.config.containsKey(Config.ROOM_CONFIG_DASIXI))
		{
			this.config.putBoolean(Config.ROOM_CONFIG_DASIXI, false);
		}
		if (!this.config.containsKey(Config.ROOM_CONFIG_XIAOSIXI))
		{
			this.config.putBoolean(Config.ROOM_CONFIG_XIAOSIXI, false);
		}
		if (!this.config.containsKey(Config.ROOM_CONFIG_LOUHU))
		{
			this.config.putBoolean(Config.ROOM_CONFIG_LOUHU, false);
		}

		this.config.putBoolean(Config.ROOM_CONFIG_ZHUANGXIAN, false);

		this.config.putBoolean(Config.ROOM_CONFIG_HZ_HU, false);

		if (!this.config.containsKey(Config.ROOM_CONFIG_GENGZHUAN))
		{
			this.config.putBoolean(Config.ROOM_CONFIG_GENGZHUAN, false);
		}


		if (!this.config.containsKey(Config.ROOM_CONFIG_LIAN_ZHUANG)) {
			this.config.putBoolean(Config.ROOM_CONFIG_LIAN_ZHUANG, false);
		}


		if (!this.config.containsKey(Config.ROOM_CONFIG_QIDUI_JIA_FAN))
		{
			this.config.putBoolean(Config.ROOM_CONFIG_QIDUI_JIA_FAN, false);
		}


		////幺九
		if (!this.config.containsKey(Config.ROOM_CONFIG_YAO_JIU))
		{
			this.config.putBoolean(Config.ROOM_CONFIG_YAO_JIU, false);
		}

		//清幺九
		if (!this.config.containsKey(Config.ROOM_CONFIG_QING_YAO_JIU))
		{
			this.config.putBoolean(Config.ROOM_CONFIG_QING_YAO_JIU, false);
		}


		//全风
		if (!this.config.containsKey(Config.ROOM_CONFIG_QUAN_FENG))
		{
			this.config.putBoolean(Config.ROOM_CONFIG_QUAN_FENG, false);
		}



		//全求人
		if (!this.config.containsKey(Config.ROOM_CONFIG_QUAN_FENG_SCORE))
		{
			this.config.putBoolean(Config.ROOM_CONFIG_QUAN_FENG_SCORE, false);
		}


		if (!this.config.containsKey(Config.ROOM_CONFIG_ZIYISE))
		{
			this.config.putBoolean(Config.ROOM_CONFIG_ZIYISE, false);
		}

		//封顶十倍
		if (!this.config.containsKey(Config.ROOM_CONFIG_10_BEI_FENGDING))
		{
			this.config.putBoolean(Config.ROOM_CONFIG_10_BEI_FENGDING, false);
		}

		//海底捞月
		//自动胡
		if (!this.config.containsKey(Config.ROOM_CONFIG_HAI_DI_NAO_YUE))
		{
			this.config.putBoolean(Config.ROOM_CONFIG_HAI_DI_NAO_YUE, false);
		}

		//门清
		if (!this.config.containsKey(Config.ROOM_CONFIG_MENG_QING))
		{
			this.config.putBoolean(Config.ROOM_CONFIG_MENG_QING, false);
		}

		//杠上炮2倍
		if (!this.config.containsKey(Config.ROOM_CONFIG_GANGSHANGPAO_2bei))
		{
			this.config.putBoolean(Config.ROOM_CONFIG_GANGSHANGPAO_2bei, false);
		}

		this.isEntrust=true;
		this.adminSeat = 0;
		this.lastWinPlayerId =0;

		this.first_zhuang_card = 0;
		this.geng_zhuan_num = 0;
		this.gent_zhuan_nextSeat = 0;

		if (this.config.getBoolean(Config.ROOM_CONFIG_GENGZHUAN))
		{
			this.isGengZhuang = true;
		}

		this.lastBankerSeat = 0;
		this.last_liuju = false;

		//初始化房间的特殊参数
		WinCardType.InitRoomSpecialConfig(this);
	}

	public boolean isLiuJu()
	{

		if (card.cardList.size() == 0)
		{
			return true;
		}


		return false;
	}

	public void endGameByLiuJu()
	{
		liuju = true;
		clear_repeatwin();

		endGame();
	}

	public void endGame()
	{
		last_liuju = liuju;
		for (Entry<Integer, Player> entry : this.playerMapById.entrySet()) {
			EXPlayer player = (EXPlayer) entry.getValue();
			if (player.winer != 1)
			{
				player.last_winer = 0;
				player.repeat_win = -1;
			}
			else
			{
				player.last_winer = 1;
			}
		}
		super.endGame();
	}

	public void addAction(Action action) {
		if (this.actionList.size() == 0) {
			this.actionList.add(action);
		} else if (action.tip.weight > this.actionList.get(0).tip.weight) {
			this.actionList.clear();
			this.actionList.add(action);
		} else if (action.tip.weight == this.actionList.get(0).tip.weight) {
			this.actionList.add(action);
		}

		checkAction();
	}

	public boolean isLaizi(int card) {
		return this.card.isLaizi(card);
	}

	public boolean isFanPai(int card) {
		return this.card.isFanPai(card);
	}

	public void checkAction() {
		boolean isWeightest = this.isWeightestAction();
		if (!isWeightest) {
			return;
		}
		if (this.isAllPass()) {
			Player activePlayer = this.playerMapBySeat.get(this.activeSeat);
			activePlayer.stateMachine.toNextState();
		} else {

			for (Action action : this.actionList) {
				action.run();
			}
			this.actionList.clear();
		}
	}

	public boolean isAllPass() {
		return this.actionList.size() == 0 && this.tipMap.size() == 0;
	}

	public boolean isWeightestAction() {

		if (this.isAllPass()) {
			return true;
		}
		if (this.actionList.size() == 0) {
			return false;
		}

		Action curaction = this.actionList.get(0);
		for (Entry<Integer, TipManager> entry : this.tipMap.entrySet()) {
			TipManager tip = entry.getValue();
			if (curaction.tip.weight <= tip.getWeightest()) {
				return false;
			}
		}

		for (Entry<Integer, Player> entry : this.playerMapById.entrySet()) {
			EXPlayer player = (EXPlayer) entry.getValue();
			if (player.stateMachine.curState instanceof EXPlayerDisCardTipState) {
				player.stateMachine.changeState(Global.getState(PlayerWaitState.class));
			}
		}
		return true;

	}

	/**
	 * 获取房间信息
	 *
	 * @return
	 */
	public ITObject getRoomInfo() {
		ITObject data = super.getRoomInfo();
		if (data != null)
		{
			data.putInt("laiziCard", this.card.laiziCard);
			data.putInt("laiziCard2", this.card.laiziCard2);
			data.putInt("laiziCardBefore", this.card.laiziCardBefore);
			data.putInt("laiziCard2Before", this.card.laiziCard2Before);
		}

		return data;
	}

	public ITObject getReloadInfo(Player player) {
		ITObject data = super.getReloadInfo(player);
		EXPlayer p = (EXPlayer) player;
		data.putTArray("hand_card", Util.toTArray(p.cardInhand));
		data.putInt("left_card", card.getCount());
		data.putInt("curren_outcard_seat", currenDiscardSeat);
		data.putInt("last_outcard_seat", lastDiscardSeat);
		return data;
	}

	public void addScore(EXPlayer destPlayer, EXPlayer fromPlayer, int score, int type) {
		boolean zhuangxian = this.config.getBoolean(Config.ROOM_CONFIG_ZHUANGXIAN);
		if(type == EXScore.WIN) {
			if (zhuangxian) {
				if (destPlayer.seat == this.bankerSeat || fromPlayer.seat == this.bankerSeat) {
					score += 1;
				}
			}
		}

		Global.logger.info("destPlayer:"+destPlayer+"type:"+destPlayer.score.round_log.get(type)+"|"+score);
		destPlayer.score.round_log.put(type, destPlayer.score.round_log.get(type) + score);
		fromPlayer.score.round_log.put(type, fromPlayer.score.round_log.get(type) - score);

		destPlayer.score.round_score += score;
		destPlayer.score.total_score += score;

		fromPlayer.score.round_score -= score;
		fromPlayer.score.total_score -= score;

	}

	public void addMaGengGongScore(EXPlayer destPlayer, EXPlayer fromPlayer, int score) {
		this.addScore(destPlayer, fromPlayer, score, EXScore.MA_GENG_GONG);
	}

	public void addAllMaGengGongScore(EXPlayer destPlayer, int score) {
		for (Entry<Integer, Player> entry : this.playerMapById.entrySet()) {
			if (entry.getKey().equals(destPlayer.playerid)) {
				continue;
			}
			EXPlayer fromPlayer = (EXPlayer) entry.getValue();
			addMaGengGongScore(destPlayer, fromPlayer, score);
		}
	}

	public int GetGongScore(EXPlayer destPlayer)
	{
		return destPlayer.score.round_log.get(EXScore.KONG);
	}

	public void addAllScore(EXPlayer destPlayer, int socre, int type) {
		Global.logger.info("add score:"+socre+"type:"+type);
		for (Entry<Integer, Player> entry : this.playerMapById.entrySet()) {
			if (entry.getKey().equals(destPlayer.playerid)) {
				continue;
			}
			EXPlayer fromPlayer = (EXPlayer) entry.getValue();
			this.addScore(destPlayer, fromPlayer, socre, type);
		}
	}



	public void handle_repeatwin(EXPlayer owner)
	{
		if (owner.last_winer == 1)
		{
			owner.repeat_win += 1;
		}
		else
		{
			owner.repeat_win += 1;
		}
	}

	public void clear_repeatwin()
	{
		for (Entry<Integer, Player> entry : this.playerMapById.entrySet()) {
			EXPlayer player = (EXPlayer) entry.getValue();
			player.repeat_win = -1;
			player.last_winer = 0;
		}
	}





	public void winCallback(EXPlayer owner, int card) {
		if (this.winCount >= this.actionList.size()) {
			if (actionList.size() > 1) {
				this.bankerSeat = this.activeSeat;
			} else {
			}

			this.endGame();
		}
	}

	public void winCallback_qiangkong(EXPlayer owner, int card) {

		if (this.winCount >= this.actionList.size()) {
			if (actionList.size() > 1) {
				this.bankerSeat = this.activeSeat;
			} else {
			}

			this.endGame();
		}
	}

	@Override
	public void saveMilitaryTotal(boolean dissmiss) {
		super.saveMilitaryTotal(dissmiss);
		EXMainServer.gameCtr.roomTotalResult(this, dissmiss);
	}
	@Override
	protected void roomResult() {
		EXMainServer.gameCtr.roomResult(this);
	}

	@Override
	public void clear() {
		super.clear();

		this.liuju = false;
		this.activeSeat = this.lastDiscardSeat = this.currenDiscardSeat = 0;

		this.isGengZhuang = false;
		this.first_zhuang_card = 0;
		this.geng_zhuan_num = 0;
		this.gent_zhuan_nextSeat = 0;
		if (this.config.getBoolean(Config.ROOM_CONFIG_GENGZHUAN))
		{
			this.isGengZhuang = true;
		}
		this.lastBankerSeat = 0;
	}

	public void handle10BeiBuJiFen(EXPlayer winner)
	{
		for (Entry<Integer, Player> entry : this.playerMapById.entrySet()) {
			EXPlayer player = (EXPlayer) entry.getValue();
			if (winner.playerid != player.playerid)
			{
				if (IsTingHu10Bei(player))
				{
					player.tinghu10bei = true;
				}
			}
		}
	}

	public boolean IsTingHu10Bei(EXPlayer player)
	{
		List<Integer> tempList = new ArrayList<Integer>();

			for (int index = 1; index <= 9; index++) {
				tempList.add(100 + index);
				tempList.add(200 + index);
				tempList.add(300 + index);
			}


		//400 东风 403南风 406西风 409北风 412红中 415发财 418白板
			tempList.add(Config.DONGFENG);
			tempList.add(Config.NANFENG);
			tempList.add(Config.XIFENG);
			tempList.add(Config.BEIFENG);
			tempList.add(Config.HONGZHONG);
			tempList.add(Config.FACAI);
			tempList.add(Config.BAIBAN);


		for(int i = 0; i < tempList.size(); i++)
		{
			int card = tempList.get(i);

			HashMap<Integer, WinCardType> map = new HashMap<Integer, WinCardType>();
			WinCard win = new WinCard(player.cardInhand, card, this.card.laiziCard, this.card.laiziCard2, false, false);
			if (win.checkWin(map, player, this, true)) {
				int dahu_score = 0;
				int cheng_score = 1;
				for (Entry<Integer, WinCardType> entry : map.entrySet()) {
					WinCardType cardType = entry.getValue();

						if (cardType.IsDaHu())
						{
							dahu_score += cardType.score*WinCardType.DA_HU_BEI_SCORE;
						}
						else
						{
							cheng_score *=  cardType.score;
						}
					}

			}
		}

		return false;
	}

	public EXPlayer get12ZhangLuoDi(EXPlayer owner)
	{
		if (owner.opCardList.size() >= 4)
		{
			OpCard opCard = owner.opCardList.get(owner.opCardList.size() - 1);
			if (opCard.type == RuleWeight.TYPE_PONG || opCard.type == RuleWeight.KONG)
			{
				if (opCard.card_seat > 0)
				{
					EXPlayer badPlayer = (EXPlayer)this.playerMapBySeat.get(opCard.card_seat);
					if (badPlayer != null)
					{
						return badPlayer;
					}
				}
			}
		}
		return null;
	}
}
