package extend.zp;

import java.util.Collections;
import java.util.Map.Entry;

import com.game.GameController;
import com.game.Global;
import com.game.Util;
import com.game.data.Player;
import com.game.player.state.PlayerWaitState;
import com.taurus.core.entity.ITArray;
import com.taurus.core.entity.ITObject;
import com.taurus.core.entity.TArray;
import com.taurus.core.entity.TObject;
import com.taurus.core.routes.ActionKey;
import com.taurus.core.util.Logger;
import com.taurus.core.util.Utils;
import com.taurus.permanent.data.Session;

import extend.zp.uitl.CardUtil;


public class EXGameController extends GameController {
	Logger logger = Logger.getLogger(getClass());
	public EXGameController() {
		super();
	}


	@ActionKey(Config.GAME_ACTION)
	public void RouterAction(Session sender,ITObject params,int gid,Player owner) {
		logger.info("step:1" );
		owner.stateMachine.execute(EXActionEvent.EVENT_ACTION, 0, params);
	}

	@ActionKey(Config.GAME_DIS_CARD)
	public void RouterDisCard(Session sender,ITObject params,int gid,Player owner) {
		owner.stateMachine.execute(EXActionEvent.EVENT_DISCARD, 0, params);
	}
	
	@ActionKey(Config.GAME_CHANGE_PAIXING)
	public void RouterChangePaixing(Session sender,ITObject params,int gid,Player owner) {
		EXPlayer player = (EXPlayer) owner;
		player.getRoom().changePaiXing(player, params);
	}
	
	@ActionKey(Config.GAME_CHANGE_TYPEFACE)
	public void RouterChangeTypeFace(Session sender,ITObject params,int gid,Player owner) {
		EXPlayer player = (EXPlayer) owner;
		int typeface = params.getInt("typeface");
		player.getRoom().typeface = typeface;
	}

	@ActionKey(Config.GAME_PIAO)
	public void RouterPiao(Session sender,ITObject params,int gid,Player owner) {
		owner.stateMachine.execute(EXActionEvent.EVENT_PIAO, 0, params);
	}

	public void changeActiveSeat(EXRoom owner, int activeSeat) {
		owner.activeSeat = activeSeat;
		ITObject param = new TObject();
		param.putInt("seat", activeSeat);
		owner.broadCastToClient(0, Config.GAME_EVT_CHANGE_ACTIVE_PLAYER, param);
	}
	
	/**
	 * 玩家摸牌
	 * @param player
	 * @param leftCount
	 */
	public void getCard(EXPlayer player, int leftCount) {
		ITObject param = new TObject();
		param.putInt("card", player.drawCard);
		param.putInt("seat", player.room.activeSeat);
		param.putInt("left_count", leftCount);
		player.sendEvent(Config.GAME_EVT_DRAW, param);

		player.getRoom().getPlayBack().addGetCardCommand(player.room.activeSeat, player.drawCard, leftCount);
	}

	public void outCard(EXPlayer player, int discard) {
		
		ITObject response = new TObject();
		response.putInt("seat", player.seat);
		response.putInt("card", discard);
		player.room.broadCastToClient(0, Config.GAME_EVT_DISCARD, response);
		
		EXRoom room = player.getRoom();
		room.getPlayBack().addOutCardCommand(player.seat, discard);

		room.activeCard = discard;
		room.lastDiscardSeat = player.seat;
		room.currenDiscardSeat = 0;

		if (!Util.checkCard(discard, player.cardInhand)) {
			for (int i = 0; i < player.kanGroup.size(); i++) {
				if (discard == player.kanGroup.get(i)[0]) {
					player.kanGroup.remove(i);
					CardUtil.removeOpcard(player.opCardList, new OpCard(RuleWeight.TYPE_KAN, discard, discard, discard, 0));
					player.cardInhand.add(discard);
					player.cardInhand.add(discard);
					break;
				}
			}
			for (int i = 0; i < player.tiGroup.size(); i++) {
				if (discard == player.tiGroup.get(i)[0]) {
					player.tiGroup.remove(i);
					CardUtil.removeOpcard(player.opCardList, new OpCard(RuleWeight.TYPE_TI, discard, discard, discard, 0));
					player.cardInhand.add(discard);
					player.cardInhand.add(discard);
					player.cardInhand.add(discard);
					break;
				}
			}
		}
		else {
			CardUtil.removeCard(player.cardInhand, discard, 1);
		}

		room.broadCastToServer(player.playerid, EXActionEvent.EVENT_OTHER_DISCARD, discard);
	}

	public void actionCard(EXPlayer player, int active_card, int card, int type, int from_seat) {
		actionCard(player, active_card, card, type, from_seat, null);
	}
	
	/**
	 * 玩家对牌操作
	 * @param player
	 * @param active_card
	 * @param card
	 * @param type
	 * @param from_seat
	 * @param opcardArray
	 */
	public void actionCard(EXPlayer player, int active_card, int card, int type, int from_seat, ITArray opcardArray) {
		
		ITObject paramBroadCast = new TObject();
		paramBroadCast.putInt("playerid", player.playerid);
		paramBroadCast.putInt("active_card", active_card);
		paramBroadCast.putInt("card", card);
		paramBroadCast.putInt("type", type);
		paramBroadCast.putInt("from_seat", from_seat);
		int huxi = player.getShowHuXi(true);
		paramBroadCast.putInt("hu_xi", huxi);
		if (opcardArray != null) {
			paramBroadCast.putTArray("opcard", opcardArray);
		}
		EXRoom room = player.getRoom();

		room.getPlayBack().addActionCommand(player.seat, type, active_card, card, from_seat, huxi, opcardArray);

		ITObject otherBroadCast = new TObject();
		Utils.objectCopyDeep(paramBroadCast, otherBroadCast);
		otherBroadCast.putInt("hu_xi", player.getShowHuXi(false));
		room.broadCastToClient(player.playerid, Config.GAME_EVT_ACTION, otherBroadCast);

		ITArray notPutArray = TArray.newInstance();
		for (Integer notPutCard : player.notPutSet) {
			notPutArray.addInt(notPutCard);
		}
		paramBroadCast.putTArray("notput", notPutArray);

		player.sendEvent(Config.GAME_EVT_ACTION, paramBroadCast);
	}
	
	/**
	 * 发牌
	 * @param owner
	 */
	public void dealCard(EXRoom owner) {

		for (Entry<Integer, Player> entry : owner.playerMapById.entrySet()) {
			
			EXPlayer player = (EXPlayer) entry.getValue();
			if (player.room.bankerSeat==player.seat){
				player.cardInhand = owner.card.deal2();
			}else{
				player.cardInhand = owner.card.deal();
			}

			//player.cardInhand = owner.card.deal();


			Collections.sort(player.cardInhand);

			ITObject param = new TObject();
			ITArray handCard = Util.toTArray(player.cardInhand);
			param.putTArray("card_list", handCard);
			param.putInt("bank_seat", player.room.bankerSeat);
			player.sendEvent(Config.GAME_EVT_PLAYER_DEAL, param);

			player.stateMachine.changeState(Global.getState(PlayerWaitState.class));
			
			logger.info("roomId:" + owner.roomid + ",round:" + owner.round + ",player:" + player + ",cardInhand:" + player.cardInhand);
		}

		logger.info("roomId:" + owner.roomid + ",round:" + owner.round + ",cardList:" + owner.card.cardList);
	}

	public void tipEvent(EXPlayer owner) {
		ITObject param = owner.tipMgr.toMP();
		if (!owner.tipMgr.tipMap.isEmpty()) {
			owner.sendEvent(Config.GAME_EVT_FZTIPS, param);
		}
	}

	public void discardTipEvent(EXPlayer owner) {
		owner.getRoom().currenDiscardSeat = owner.seat;
		owner.sendEvent(Config.GAME_EVT_DISCARD_TIP, null);
	}

	public void winEvent(EXPlayer owner, int from_seat) {
		ITArray cardInHand = TArray.newInstance();
		for (int card1 : owner.cardInhand) {
			cardInHand.addInt(card1);
		}
		ITObject param = new TObject();
		param.putTArray("card", cardInHand);
		param.putInt("seat", owner.seat);
		param.putInt("from_seat", from_seat);

		EXRoom room = owner.getRoom();
		room.broadCastToClient(0, Config.GAME_EVT_HU, param);
		room.getPlayBack().addWinCardCommand(owner.seat, false);
	}

	public ITObject getRoomResultData(EXRoom owner) {
		ITObject mp = TObject.newInstance();
		mp.putBoolean("liuju", owner.liuju);
		mp.putInt("active_player", owner.playerMapBySeat.get(owner.activeSeat).playerid);
		mp.putTArray("left_card", Util.toTArray(owner.card.cardList));
		mp.putTArray("throw_card", Util.toTArray(owner.throwCardsList));
		mp.putInt("xipai_score", owner.xi_pai_score);
		long time = System.currentTimeMillis();
		long t = time / 1000;
		mp.putLong("time", t);
		ITArray infoList = new TArray();
		for (Entry<Integer, Player> entry : owner.playerMapById.entrySet()) {
			EXPlayer player = (EXPlayer) entry.getValue();
			ITObject param = new TObject();
			param.putInt("seat", player.seat);
			param.putInt("win_card", player.winCard);
			param.putBoolean("is_win", player.winer == 1);
			param.putInt("hu_xi", player.huXi);
			param.putInt("tun", player.winScore);
			param.putInt("piao", player.piao);
			player.hp_info(param);
			if (owner.maxPlayers == 2) {
				param.putInt("total_tun", player.score.round_score);
			} else {
				param.putInt("total_tun", player.score.round_score / 2);
			}

			param.putInt("round_score", player.score.round_score);
			param.putInt("total_score", player.score.total_score);

			ITArray mtList = TArray.newInstance();
			for (MingTang mingTang : player.mingtangList) {
				ITObject obj = TObject.newInstance();
				obj.putInt("mingtang", mingTang.mingTang);
				obj.putInt("type", mingTang.type);
				obj.putInt("score", mingTang.score);

				mtList.addTObject(obj);
			}
			param.putTArray("mingtang", mtList);

			ITArray haoList = TArray.newInstance();
			if (player.winer == 1) {
				ITArray handCard = Util.toTArray(player.handCardEx);
				param.putTArray("hand_card", handCard);

				ITArray cardList = TArray.newInstance();
				for (int i = 0; i < player.tiGroup.size(); i++) {
					int ti_card = player.tiGroup.get(i)[0];
					ITObject hao = TObject.newInstance();
					hao.putInt("hao", RuleWeight.HAO_QING);
					hao.putInt("hao_card", ti_card);
					haoList.addTObject(hao);
				}

				for (OpCard opCard : player.handCard) {
					boolean flag = true;
					if (opCard.card1 == opCard.card2 && opCard.card1 == opCard.card3 && opCard.card1 != 0) {
						for (int i = 0; i < player.tiGroup.size(); i++) {
							int ti_card = player.tiGroup.get(i)[0];
							if (ti_card == opCard.card1)
							{
								flag = false;
							}
						}
					}
					if (flag)
					{
						ITObject obj = TObject.newInstance();
						obj.putInt("type", opCard.type);
						obj.putInt("hu_xi", opCard.huXi);
						obj.putInt("card1", opCard.card1);
						obj.putInt("card2", opCard.card2);
						obj.putInt("card3", opCard.card3);

						if (opCard.hao != RuleWeight.HAO_NONE)
						{
							ITObject hao = TObject.newInstance();
							hao.putInt("hao", opCard.hao);
							hao.putInt("hao_card", opCard.haoCard);
							haoList.addTObject(hao);
						}

						cardList.addTObject(obj);
					}
				}
				param.putTArray("cardList", cardList);
			} else {
				ITArray handCard = Util.toTArray(player.cardInhand);
				param.putTArray("hand_card", handCard);
			}

			ITArray opCardList = TArray.newInstance();

			for (OpCard opCard : player.opCardList) {
				ITObject obj = TObject.newInstance();
				obj.putInt("type", opCard.type);
				obj.putInt("hu_xi", opCard.huXi);
				obj.putInt("card1", opCard.card1);
				obj.putInt("card2", opCard.card2);
				obj.putInt("card3", opCard.card3);

				opCardList.addTObject(obj);

				if (opCard.hao != RuleWeight.HAO_NONE)
				{
					ITObject hao = TObject.newInstance();
					hao.putInt("hao", opCard.hao);
					hao.putInt("hao_card", opCard.haoCard);
					haoList.addTObject(hao);
				}
			}
			param.putTArray("opCardList", opCardList);
			param.putTArray("haoList", haoList);

			infoList.addTObject(param);
		}
		mp.putTArray("info_list", infoList);
		return mp;
	}

	public void roomResult(EXRoom owner) {
		ITObject mp = TObject.newInstance();
		mp.putInt("type", 0);
		ITObject result = getRoomResultData(owner);
		mp.putTObject("result", result);
		owner.broadCastToClient(0, Config.GAME_EVT_RESULT1, mp);
	}

	public void roomTotalResult(EXRoom owner, boolean dissmiss) {
		ITObject data = TObject.newInstance();
		long t = System.currentTimeMillis() / 1000;
		data.putLong("time", t);
		ITArray infoList = new TArray();
		for (Entry<Integer, Player> entry : owner.playerMapById.entrySet()) {
			EXPlayer player = (EXPlayer) entry.getValue();
			ITObject param = new TObject();
			param.putInt("seat", player.seat);
			param.putInt("total_huxi", player.total_huxi);
			param.putInt("win_count", player.winCount);
			param.putInt("total_score", player.score.total_score);
			player.hp_info(param);
			infoList.addTObject(param);
		}
		data.putTArray("info_list", infoList);

		ITObject mp = TObject.newInstance();
		mp.putInt("type", dissmiss ? 2 : 1);
		if (!dissmiss) {
			ITObject result = getRoomResultData(owner);
			mp.putTObject("result", result);
		}
		mp.putTObject("total_result", data);

		owner.broadCastToClient(0, Config.GAME_EVT_RESULT1, mp);
	}

	/**
	 * 票鸟提示
	 * @param owner
	 */
	public void piaoTipEvent(EXPlayer owner,int reload) {

		ITObject response = new TObject();
		response.putInt("piao", owner.room.config.getInt(Config.ROOM_CONFIG_PIAO));
		response.putInt("reload", reload);
		System.out.println("piao");
		owner.sendEvent(Config.GAME_EVT_PIAO_TIP, response);
	}

	/**
	 * 票鸟事件
	 * @param owner
	 */
	public void piaoEvent(EXPlayer owner) {
		if(owner.piao==-1)return;

		ITObject param = new TObject();
		param.putInt("seat", owner.seat);
		param.putInt("piao", owner.piao);
		owner.room.broadCastToClient(0, Config.GAME_EVT_PIAO, param);
	}
}
