package com.backfire.room.receiveDataManager;

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

import net.yeeyo.doudizhu.feiyu.R;
import android.graphics.Point;

import com.backfire.Animation.Animation;
import com.backfire.Animation.AnimationAirplane;
import com.backfire.Animation.AnimationBomb;
import com.backfire.Animation.AnimationBurstLaizi;
import com.backfire.Animation.AnimationChain;
import com.backfire.Animation.AnimationChainPair;
import com.backfire.Animation.AnimationManager;
import com.backfire.Animation.AnimationRocket;
import com.backfire.Animation.AnimationSelectLaizi;
import com.backfire.Animation.AnimationToast;
import com.backfire.Animation.AnimationTurnMoveLaizi;
import com.backfire.arithmetic.Card;
import com.backfire.arithmetic.CardAssist;
import com.backfire.arithmetic.CardJudge.CardType;
import com.backfire.arithmetic.CardJudge3_Laizi;
import com.backfire.arithmetic.CardReturn;
import com.backfire.arithmetic.CardReturn_Laizi;
import com.backfire.doudizhu.common.AudioConfig;
import com.backfire.doudizhu.common.DdzApplication;
import com.backfire.doudizhu.userinfo.UserInfo;
import com.backfire.doudizhu.userinfo.UserMessageCenter;
import com.backfire.room.RoomActivity;
import com.backfire.room.data.ConfigCenter;
import com.backfire.room.data.HandlerMsg;
import com.backfire.room.data.Player;
import com.backfire.room.data.ResCenter;
import com.backfire.room.data.RoomInfo;
import com.backfire.room.data.State.CardNum;
import com.backfire.room.data.State.GameState;
import com.backfire.room.data.State.Identity;
import com.backfire.room.data.State.Sex;
import com.backfire.room.data.State.UserAction;
import com.backfire.room.data.State.UserState;
import com.backfire.socket.socketProto.Doudizhu.BroadcastChat;
import com.backfire.socket.socketProto.Doudizhu.BroadcastLaiziCard;
import com.backfire.socket.socketProto.Doudizhu.BroadcastPlayerAction;
import com.backfire.socket.socketProto.Doudizhu.BroadcastPlayerInfo;
import com.backfire.socket.socketProto.Doudizhu.CardInfo;
import com.backfire.socket.socketProto.Doudizhu.GameOver;
import com.backfire.socket.socketProto.Doudizhu.GameResult;
import com.backfire.socket.socketProto.Doudizhu.GameStart;
import com.backfire.socket.socketProto.Doudizhu.HandCard;
import com.backfire.socket.socketProto.Doudizhu.PlayerDepositRpy;
import com.backfire.socket.socketProto.Doudizhu.PlayerInfo;
import com.backfire.socket.socketProto.Doudizhu.QiangdizhuRpy;
import com.backfire.socket.socketProto.Doudizhu.ReadyReply;
import com.backfire.socket.socketProto.Doudizhu.SeatRpy;
import com.backfire.utils.Log;
import com.google.protobuf.InvalidProtocolBufferException;

public class BroadcastProtoManager {
	RoomActivity mContext;

	public BroadcastProtoManager(RoomActivity mContext) {
		this.mContext = mContext;
	}

	/**
	 * 准备回应广播 optional uint32 ret = 1; // optional uint32 retcode = 2; //
	 * optional string retmsg = 3; // repeated uint32 seats = 4;
	 * //哪些位置已经准备,这个的做法再商量
	 */
	public void readyRpy(byte[] data) {
		ReadyReply rpy = null;
		try {
			rpy = ReadyReply.parseFrom(data);
		} catch (InvalidProtocolBufferException e) {
			e.printStackTrace();
		}

		if (null != rpy) {
			int ret = 2;
			if (rpy.hasRet()) {
				ret = rpy.getRet();
			}
			int retcode = 0;
			if (rpy.hasRetcode()) {
				retcode = rpy.getRetcode();
			}
			String retmsg = "";
			if (rpy.hasRetmsg()) {
				retmsg = rpy.getRetmsg();
			}
			Log.i(this, "ret:" + ret + "-->retcode:" + retcode + "---->retmsg:"
					+ retmsg);
			if (rpy.getSeatsCount() > 0) {
				List<Integer> seatlist = rpy.getSeatsList();
				int readyCnt = 0;
				for (int i = 0; i < seatlist.size(); i++) {
					int state = seatlist.get(i);
					int seatId = i + 1;
					Player player = RoomInfo.getInstance().getPlayer(seatId);
					if (null != player) { // 代表用户存在并且已经准备
						synchronized (player) {
							if (1 == state) {
								readyCnt++;
								player.setState(UserState.USER_READY);
								player.setReady(true);
							} else {
								player.setReady(false);
							}
							if (seatId == RoomInfo.getInstance().getSeatId()) {
								RoomInfo.getInstance().setSendReqing(false);
								RoomInfo.getInstance().setRefight(false);
							}
						}
						Log.i(this, "seatId" + seatId + "-->state:" + state
								+ "---->用户准备");
					}
				}
				mContext.removeClockAnimation();
				if (3 == RoomInfo.getInstance().getPlayerCnt()) {
					int timeOut = RoomInfo.getInstance().getReadytimeout();
					int posX = (DdzApplication.getApplication().screenWidth - ConfigCenter.clock_bg_W) / 2;
					int posY = ConfigCenter.click_center_Y;
					if (3 != readyCnt) {
						mContext.addClockAnimation(posX, posY, timeOut);
					}
				}
			}
			Log.i(this, "--------------------------------");
		}
	}

	/**
	 * 坐下回应 optional uint32 ret = 1; //返回值，1成功，2失败 optional uint32 retCode = 2;
	 * //错误码 optional string retMsg = 3; //用户提示信息 optional uint32 seatid = 4;
	 * //玩家的座位 optional uint32 action = 5; //玩家的动作 optional uint32 basepoint =
	 * 6; //底分 optional uint32 readytimeout= 7; //准备超时 实现功能： 1.成功 2.失败
	 */
	public void sitRpy(byte[] data) {
		SeatRpy rpy = null;
		try {
			rpy = SeatRpy.parseFrom(data);
		} catch (InvalidProtocolBufferException e) {
			e.printStackTrace();
		}

		if (null != rpy) {
			int ret = 2;
			if (rpy.hasRet()) {
				ret = rpy.getRet();
			}
			int retCode = 0;
			if (rpy.hasRetCode()) {
				retCode = rpy.getRetCode();
			}
			String retmsg = "";
			if (rpy.hasRetMsg()) {
				retmsg = rpy.getRetMsg();
			}
			int seatId = 0;
			if (rpy.hasSeatid()) {
				seatId = rpy.getSeatid();
			}
			int action = 0;
			if (rpy.hasAction()) {
				action = rpy.getAction();
			}

			int basepoint = 0;
			if (rpy.hasBasepoint()) {
				basepoint = rpy.getBasepoint();
			}

			int readytimeout = 0;
			if (rpy.hasReadytimeout()) {
				readytimeout = rpy.getReadytimeout();
			}
			int awardRoom = 0;
			if (rpy.hasAwardRoom()) {
				awardRoom = rpy.getAwardRoom();
			}
			int laiziFlag = 0;
			if (rpy.hasLaiziFlag()) {
				laiziFlag = rpy.getLaiziFlag();
			}
			String roomName = "";
			if(rpy.hasRoomName()){
				roomName = rpy.getRoomName();
			}
			RoomInfo roomInfo = RoomInfo.getInstance();
			Log.i(this, "ret:" + ret + "-->retcode:" + retCode + "---->retmsg:"
					+ retmsg + "---->seatId:" + seatId + "---->action:"
					+ action + "---->basepoint:" + basepoint
					+ "---->readytimeout:" + readytimeout + ",awardRoom="
					+ awardRoom + ",laiziFlag=" + laiziFlag+ ",roomName=" + roomName);
			Log.i(this, "--------------------------------");
			if (ret == 1) { // 请求命令成功
				if (action == UserAction.SIT) {
					roomInfo = RoomInfo.getInstance();
					roomInfo.setSeatId(seatId);
					roomInfo.setBasepoint(basepoint);
					roomInfo.setReadytimeout(readytimeout);
					roomInfo.setAwardRoom(awardRoom);
					roomInfo.setLaiziFlag(laiziFlag);
					roomInfo.setRoomName(roomName+ResCenter.getFormSuffix(laiziFlag));

					Player player = new Player();
					player.setUid(UserMessageCenter.getInstance().getUserInfo()
							.getUid());
					player.setSeatId(seatId);
					player.setState(UserState.USER_READY_NEED); // 代表用户需要准备了

					UserInfo userinfo = UserMessageCenter.getInstance()
							.getUserInfo();
					player.setIcon(ResCenter.getUserIcon(userinfo.getIcon()));
					player.setMoney(userinfo.getMoney());
					player.setLevel(userinfo.getLevel());
					player.setSex(userinfo.getSex());
					player.setNick(userinfo.getNick());
					// player.setItems(items);
					player.setGameCount(userinfo.getGameCnt());
					player.setWinCount(userinfo.getWinCnt());
					player.setDropCount(userinfo.getDropCnt());
					player.setRunCount(userinfo.getRunCnt());
					player.setSign(userinfo.getSignature());
					player.setLottery(userinfo.getLottery());

					roomInfo.addPlayer(seatId, player);
					// mContext.getRoom().getUserSurFace().updateSeatButton();
					roomInfo.setState(GameState.GAME_READY); // 代表游戏开始进入准备阶段
					DdzApplication.getApplication().getPlayMedia()
							.startBgMusic();// 成功坐下播放背景音乐
				} else if (action == UserAction.STAND) {
					// 判断是不是主动退的
					if (roomInfo.getState() != GameState.GAME_OVER) {
						if (seatId == RoomInfo.getInstance().getSeatId()) {
							RoomInfo.getInstance().clearAll();
							mContext.getRoom().getSocketSender().logoutReq();
						} else {
							RoomInfo.getInstance().removePlayer(seatId);
						}
					} else {
						mContext.removeClockAnimation();
					}
				}
			} else {
				Log.e(rpy, "ret=" + ret + ",retCode=" + retCode + ",retmsg="
						+ retmsg);
				//String msg = mContext.getString(R.string.network_error);
				mContext.showMessage(retmsg);
				mContext.toLobby();
			}
		} else {
			// 返回大厅：提示认证失败
			mContext.getRoom().getSocketSender().logoutReq();
		}
	}

	public void playerInfoRpy(byte[] data) {
		BroadcastPlayerInfo rpy = null;
		try {
			rpy = BroadcastPlayerInfo.parseFrom(data);
		} catch (InvalidProtocolBufferException e) {
			e.printStackTrace();
		}

		if (null != rpy) {
			List<PlayerInfo> playerInfo = rpy.getSeatListList();
			if (playerInfo.size() > 0) { // 其他用户登陆
				for (PlayerInfo info : playerInfo) {
					initPlayer(info);
				}
			}
			Log.i(this, "--------------------------------");
		} else {
			// 返回大厅：提示认证失败
			mContext.toLobby();
		}
	}

	/*
	 * optional uint32 seatId = 1; //座位ID optional uint64 uid = 2; //用户ID
	 * ooptional string uName = 3; //用户名称 ooptional string icon = 4; //用户头像
	 * ooptional uint32 money = 5; //用户金币数 ooptional uint32 level = 6; //用户等级
	 * ooptional uint32 sex = 7; //用户性别 orepeated uint32 items = 8; //用户道具
	 * optional uint32 gameCount = 9; //游戏场数 optional uint32 winCount = 10;
	 * //胜利场数 optional uint32 dropCount = 11; //掉线次数 optional uint32 runCount =
	 * 12; //逃跑次数
	 */
	private void initPlayer(PlayerInfo playerInfo) {
		int seatId = 0;
		if (playerInfo.hasSeatId()) {
			seatId = playerInfo.getSeatId();
		}
		long uid = 0;
		if (playerInfo.hasUid()) {
			uid = playerInfo.getUid();
		}
		String nick = "";
		if (playerInfo.hasUName()) {
			nick = playerInfo.getUName();
		}
		String icon = "";
		if (playerInfo.hasIcon()) {
			icon = playerInfo.getIcon();
		}
		long money = 0;
		if (playerInfo.hasMoney()) {
			money = playerInfo.getMoney();
		}
		int level = 0;
		if (playerInfo.hasLevel()) {
			level = playerInfo.getLevel();
		}
		int sex = 0;
		if (playerInfo.hasSex()) {
			sex = playerInfo.getSex();
			if (Sex.MALE == sex) {
				sex = Sex.MALE;
			} else {
				sex = Sex.FEMALE;
			}
		}
		List<Integer> items = new ArrayList<Integer>();
		if (playerInfo.getItemsCount() > 0) {
			items = playerInfo.getItemsList();
		}
		int gameCount = 0;
		if (playerInfo.hasGameCount()) {
			gameCount = playerInfo.getGameCount();
		}
		int winCount = 0;
		if (playerInfo.hasWinCount()) {
			winCount = playerInfo.getWinCount();
		}
		int dropCount = 0;
		if (playerInfo.hasDropCount()) {
			dropCount = playerInfo.getDropCount();
		}
		int runCount = 0;
		if (playerInfo.hasRunCount()) {
			runCount = playerInfo.getRunCount();
		}
		long lottery = 0;
		if(playerInfo.hasLottery()){
			lottery = playerInfo.getLottery();
		}
		String sign = "";
		if(playerInfo.hasSign()){
			sign = playerInfo.getSign();
		}
		Log.i(this, "seatId:" + seatId + "-->uid:" + uid + "---->uName:" + nick
				+ "---->icon:" + icon + "---->money:" + money + "---->level:"
				+ level + "---->sex:" + sex + "---->gameCount:" + gameCount
				+ "---->winCount:" + winCount + "---->dropCount:" + dropCount
				+ "---->runCount:" + runCount+ "---->lottery:" + lottery+ "---->sign:" + sign);
		Log.i(this, "--------------------------------");
		Player player = new Player();
		player.setSeatId(seatId);
		player.setUid(uid);
		player.setNick(nick);
		player.setIcon(ResCenter.getUserIcon(icon));
		player.setMoney(money);
		player.setLevel(level);
		player.setSex(sex);
		player.setItems(items);
		player.setGameCount(gameCount);
		player.setWinCount(winCount);
		player.setDropCount(dropCount);
		player.setRunCount(runCount);
		player.setLottery(lottery);
		player.setState(UserState.USER_READY_NEED); // 代表用户需要准备了
		player.setSign(sign);
		RoomInfo.getInstance().addPlayer(seatId, player);
		// mContext.getRoom().getUserSurFace().updateSeatButton();
	}

	public void handCard(byte[] data,boolean isRebinding) {
		HandCard rpy = null;
		try {
			rpy = HandCard.parseFrom(data);
		} catch (InvalidProtocolBufferException e) {
			e.printStackTrace();
		}

		if (null != rpy) {
			if (rpy.getHandCardListCount() > 0) {
				RoomInfo roomInfo = RoomInfo.getInstance();
				ArrayList<Card> cards = roomInfo.getMyCards();
				if (null != cards) {
					synchronized (cards) {
						cards.clear();
					}
				}
				for (CardInfo info : rpy.getHandCardListList()) {
					Card card = addCard(info);
					if (null != cards) {
						synchronized (cards) {
							cards.add(card);
						}
					}
				}
				if (null != cards) {
					synchronized (cards) {
						Collections.sort(cards, new CardAssist.Desc());
					}
				}
				mContext.getRoom().getCardBtnManager().updateCard(null);
				roomInfo.setState(GameState.GAME_QIANG_ZHUANG); // 代表游戏已经进入抢庄阶段
				for (int i = 0, n = roomInfo.getPlayerLength(); i < n; i++) {
					int seatId = i + 1;
					Player player = RoomInfo.getInstance().getPlayer(seatId);
					if (player != null) { // 代表用户存在并且已经准备
						synchronized (player) {
							player.setState(UserState.USER_GRAB_WAIT); // 进入抢庄阶段，所有人开始都是等待状态
							if(!isRebinding)player.setCardNum(CardNum.SEVENTEEEN); // 初始化用户的牌数，17张,重连的时候另算
						}
						Log.i(this, "seatId" + seatId + "-->state:"
								+ UserState.USER_GRAB_WAIT + "---->开始抢庄流程");
					}
				}
			}

			Log.i(this, "--------------------------------");
		}
	}

	public Card addCard(CardInfo cardInfo, boolean orgLaizi) {
		boolean isLaizi = cardInfo.getLaiziFace() > 0;
		int cardFace = isLaizi ? (orgLaizi ? cardInfo.getLaiziFace() : cardInfo
				.getCardFace()) : cardInfo.getCardFace();
		Card card = new Card(cardInfo.getCardSuit(), cardFace);
		card.setIsLaiZi(isLaizi);
		Log.i(this,
				"cardSuit:" + card.getColor() + "-->cardFace:"
						+ card.getPoint() + "---->isLaiZi:" + card.isLaiZi());
		return card;
	}

	// 说明:主动出牌用此函数
	public Card addCard(CardInfo cardInfo) {
		Card card = new Card(cardInfo.getCardSuit(), cardInfo.getCardFace());
		card.setIsLaiZi(cardInfo.getLaiziFace() != 0);
		Log.i(this,
				"cardSuit:" + card.getColor() + "-->cardFace:"
						+ card.getPoint() + "---->isLaiZi:" + card.isLaiZi());
		return card;
	}

	/**
	 * 抢地主回应 optional uint32 ret = 1; // optional uint32 retcode = 2; //
	 * optional string retmsg = 3; // optional uint32 ratio = 4; //返回当前倍率
	 * optional uint32 seatid = 5; //当前抢地主玩家位置 optional uint32 timeout = 6;
	 * //抢地主倒计时时间 optional uint32 callCount = 7; //当前是第几次抢
	 * 
	 * @param data
	 */
	public void qiangDizhuRpy(byte[] data) {
		QiangdizhuRpy rpy = null;
		try {
			rpy = QiangdizhuRpy.parseFrom(data);
		} catch (InvalidProtocolBufferException e) {
			e.printStackTrace();
		}

		if (null != rpy) {
			int ret = 2;
			if (rpy.hasRet()) {
				ret = rpy.getRet();
			}
			int retcode = 0;
			if (rpy.hasRetcode()) {
				retcode = rpy.getRetcode();
			}
			String retmsg = "";
			if (rpy.hasRetmsg()) {
				retmsg = rpy.getRetmsg();
			}
			int ratio = 0;
			if (rpy.hasRatio()) {
				ratio = rpy.getRatio();
			}
			int seatId = 0;
			if (rpy.hasSeatid()) {
				seatId = rpy.getSeatid();
			}
			int timeout = 0;
			if (rpy.hasTimeout()) {
				timeout = rpy.getTimeout();
			}
			int callCount = 0;
			if (rpy.hasCallCount()) {
				callCount = rpy.getCallCount();
			}
			Log.i(this, "ret:" + ret + "-->retcode:" + retcode + "---->retmsg:"
					+ retmsg + "---->ratio:" + ratio + "---->seatId:" + seatId
					+ "---->timeout:" + timeout + "---->callCount:" + callCount);

			RoomInfo roomInfo = RoomInfo.getInstance();
			if (seatId == roomInfo.getSeatId()) {
				RoomInfo.getInstance().setSendReqing(false);
			}
			if (timeout > 0)
				roomInfo.setQiangDiZhuTimeout(timeout);
			Player lastPlayer = roomInfo.getPlayer(roomInfo.getCurSeatId());
			if (callCount > 0) { // 代表前面已经有用户叫过庄了，这个时候，就得先将上一个玩家的状态调整过来
				if (lastPlayer != null) {
					int state = 0;
					synchronized (lastPlayer) {
						state = lastPlayer.getState();
					}
					if (state == UserState.USER_CALL_NEED) { // 代表上一个用户是叫地主
						synchronized (lastPlayer) {
							if (ratio == 1) {
								lastPlayer.setState(UserState.USER_CALL_ONE);
								lastPlayer
										.setOperateAction(UserState.USER_CALL_ONE);
							} else if (ratio == 2) {
								lastPlayer.setState(UserState.USER_CALL_TWO);
								lastPlayer
										.setOperateAction(UserState.USER_CALL_TWO);
							} else if (ratio == 3) {
								lastPlayer.setState(UserState.USER_CALL_THREE);
								lastPlayer
										.setOperateAction(UserState.USER_CALL_THREE);
							}
						}
						DdzApplication.getApplication().play(
								AudioConfig.kCall, lastPlayer.getSex());
					} else {
						// 代表上一个用户是抢地主
						int multiple = ratio / roomInfo.getRatio();
						if (multiple > 1) {
							synchronized (lastPlayer) {
								lastPlayer.setState(UserState.USER_GRAB);
								lastPlayer.setOperateAction(UserState.USER_GRAB);
							}
							DdzApplication.getApplication().play(
									AudioConfig.kGrab, lastPlayer.getSex());
						} else {
							synchronized (lastPlayer) {
								lastPlayer.setState(UserState.USER_GRAB_GIVEUP);
								lastPlayer.setOperateAction(UserState.USER_GRAB_GIVEUP);
							}
							DdzApplication.getApplication().play(
									AudioConfig.kNotGrab,
									lastPlayer.getSex());
						}
					}
				}
			}
			// seatId为0就代表着没有下一个抢庄的人了
			if (seatId > 0) {
				Player player = roomInfo.getPlayer(seatId);
				if (player != null) {
					roomInfo.setCallCount(callCount);
					roomInfo.setCurSeatId(seatId);
					roomInfo.setRatio(ratio);
					synchronized (player) {
						if (callCount == 0) {
							player.setState(UserState.USER_CALL_NEED); // 代表改用户需要选择叫地主操作，包括1分，2分，3分
						} else {
							player.setState(UserState.USER_GRAB_NEED); // 代表改用户需要选择抢庄操作，包括抢庄和不抢
						}
					}
				}
				// 添加抢地主超时闹钟
				mContext.addClockAnimation(seatId, timeout);
			} else if(lastPlayer!=null){
				int seatIdx = 0 ;
				synchronized (lastPlayer) {
					seatIdx = roomInfo.getSeatIdx(lastPlayer.getSeatId());
				}
				int multiple = ratio / roomInfo.getRatio();
				int seatW = ConfigCenter.room_seat_W;
				int seatH = ConfigCenter.room_seat_H;
				int width = 0;
				int hight = ConfigCenter.operate_tag_H;
				int resID = 0;
				if (multiple > 1) {// 抢
					width = ConfigCenter.operate_three_W;
					resID = R.drawable.grab_text;
				} else {
					width = ConfigCenter.operate_two_W;
					resID = R.drawable.no_grab_text;
				}
				int posX = ConfigCenter.room_seat_X[seatIdx % 3];
				int posY = ConfigCenter.room_seat_Y[seatIdx % 3];
				if (ConfigCenter.SeatPos1 == seatIdx) {
					posX = posX - width - ConfigCenter.operate_tag_offset_W;
				} else {
					posX = posX + seatW + ConfigCenter.operate_tag_offset_W;
				}
				posY = posY + seatH - ConfigCenter.operate_tag_offset_H;

				if (resID > 0) {
					AnimationManager.getInstance().addAnimation(
							new AnimationToast(resID, width, hight, posX, posY,
									1000));
				}
				roomInfo.setRatio(ratio);
				mContext.removeClockAnimation();
			}
			Log.i(this, "--------------------------------");
		}
	}

	/**
	 * 游戏开始广播
	 */
	public void gameStart(byte[] data,boolean isRebinding) {
		GameStart rpy = null;
		try {
			rpy = GameStart.parseFrom(data);
		} catch (InvalidProtocolBufferException e) {
			e.printStackTrace();
		}

		if (null != rpy) {
			int gameNum = 0;
			if (rpy.hasGameNum()) {
				gameNum = rpy.getGameNum();
			}
			int basePoint = 0;
			if (rpy.hasBet()) {
				basePoint = rpy.getBet();
			}
			int dizhuId = 0;
			if (rpy.hasDizhu()) {
				dizhuId = rpy.getDizhu();
			}
			int timeout = 0;
			if (rpy.hasTimeout()) {
				timeout = rpy.getTimeout();
			}

			Log.i(this, "gameNum:" + gameNum + "-->bet:" + basePoint
					+ "---->dizhuId:" + dizhuId + "---->timeout:" + timeout);
			RoomInfo roomInfo = RoomInfo.getInstance();
			if (gameNum > 0)
				roomInfo.setGameNum(gameNum);
			if (basePoint > 0)
				roomInfo.setBasepoint(basePoint);
			if (timeout > 0)
				roomInfo.setOperatetimeout(timeout);

			ArrayList<Card> myCards = RoomInfo.getInstance().getMyCards();
			if (null != myCards) {
				synchronized (myCards) {
					if (rpy.getCommcardCount() == 3) { // 3张底牌
						Card[] commcard = roomInfo.getCommcard();
						Card selectLaiziCard = roomInfo.getLaizi(0);// 第一张为抽选出来的癞子，其他为爆出来的癞子
						for (int i = 0; i < 3; i++) {
							Card card = addCard(rpy.getCommcard(i));
							if (null != selectLaiziCard && null != card
									&& card.isSamePoint(selectLaiziCard)) {
								card.setLaiZi(true);
							}

							synchronized (commcard) {
								commcard[i] = card;
							}
							if (dizhuId == roomInfo.getSeatId() && !isRebinding) {
								myCards.add(card);
							}
						}
					}
				}
			}
			if (dizhuId == roomInfo.getSeatId()) { //
				RoomInfo.getInstance().setSendReqing(false);
				if (null != myCards) {
					synchronized (myCards) {
						Collections.sort(myCards, new CardAssist.Desc());
					}
				}
				mContext.getRoom().getCardBtnManager().updateCard(null);
			}

			roomInfo.setState(GameState.GAME_PLAY); // 代表游戏已经进入玩牌阶段
			for (int i = 0, n = roomInfo.getPlayerLength(); i < n; i++) {
				int seatId = i + 1;
				Player player = RoomInfo.getInstance().getPlayer(seatId);
				if (player != null) { // 代表用户存在并且已经准备
					synchronized (player) {
						if (seatId == dizhuId) {
							player.setSide(Identity.LANDLORD);
						} else {
							player.setSide(Identity.COMMONER);
						}
						player.setState(UserState.USER_PLAY_WAIT); // 进入玩牌阶段，所有人开始都是等待状态
					}
					Log.i(this, "seatId" + seatId + "-->state:"
							+ UserState.USER_PLAY_WAIT + "---->开始抢庄玩牌");
				}
			}
			if (dizhuId > 0) {
				Player player = roomInfo.getPlayer(dizhuId);
				if (player != null) {
					roomInfo.setDizhuId(dizhuId);
					roomInfo.setCurSeatId(dizhuId);
					roomInfo.resetPeasentSeatIdOperatAction();
					synchronized (player) {
						player.setState(UserState.USER_PLAY_NEED);
						if (!isRebinding) {
							player.setCardNum(CardNum.TWENTY); // 初始化地主的牌数，20张
						}
					}
					// 添加抢地主超时闹钟
					mContext.addClockAnimation(dizhuId, timeout);
				}
			}
			Log.i(this, "--------------------------------");
		}
	}

	/**
	 * 广播其他玩家动作(出牌，pass，表情等) optional uint64 uid = 1; //用户id optional uint32
	 * seatid = 2; //出牌玩家seatid optional uint32 action = 3; //动作，1pass，2打牌，3发表情
	 * repeated CardInfo pushCardList = 4; //对手出牌内容 optional uint32 emotionId =
	 * 5; //表情ID optional uint64 nextuid = 6; //下一个出牌玩家uid optional uint32
	 * nextseatid = 7; //下一个出牌玩家seatid optional uint32 pointratio = 8; //当前倍率
	 * optional uint32 cardType = 9; //牌型 optional uint32 highcard = 10;
	 * //主牌型的最大牌 实现功能： 更新其他玩家动作对应的UI
	 * 
	 * @param body
	 */
	public void userAction(byte[] data,boolean isRebinding) {
		BroadcastPlayerAction rpy = null;
		try {
			rpy = BroadcastPlayerAction.parseFrom(data);
		} catch (InvalidProtocolBufferException e) {
			e.printStackTrace();
		}

		if (null != rpy) {
			long uid = 0;
			if (rpy.hasUid()) {
				uid = rpy.getUid();
			}
			int seatid = 0;
			if (rpy.hasSeatid()) {
				seatid = rpy.getSeatid();
			}
			int action = 0;
			if (rpy.hasAction()) {
				action = rpy.getAction();
			}
			int emotionId = 0;
			if (rpy.hasEmotionId()) {
				emotionId = rpy.getEmotionId();
			}
			long nextuid = 0;
			if (rpy.hasNextuid()) {
				nextuid = rpy.getNextuid();
			}
			int nextseatid = 0;
			if (rpy.hasNextseatid()) {
				nextseatid = rpy.getNextseatid();
			}
			int pointratio = 0;
			if (rpy.hasPointratio()) {
				pointratio = rpy.getPointratio();
			}
			int cardType = 0;
			if (rpy.hasCardType()) {
				cardType = rpy.getCardType();
			}
			int highcard = 0;
			if (rpy.hasCardType()) {
				highcard = rpy.getHighcard();
			}
			Log.i(this, "uid:" + uid + "-->seatid:" + seatid + "---->action:"
					+ action + "---->emotionId:" + emotionId + "-->nextuid:"
					+ nextuid + "---->nextseatid:" + nextseatid
					+ "---->pointratio:" + pointratio + "---->cardType:"
					+ cardType + "---->highcard:" + highcard);

			RoomInfo roomInfo = RoomInfo.getInstance();
			roomInfo.setRatio(pointratio);
			if (seatid > 0) { // 已操作用户
				Player player = roomInfo.getPlayer(seatid);
				if (player != null) {
					if (action == UserAction.PLAY) { // 用户出牌
						synchronized (player) {
							player.setOperateAction(UserState.USER_PLAY);
						}
						int lastOutCardSeatId = roomInfo.getLastOutCardSeatId();
						roomInfo.setLastOutCardSeatId(seatid);
						ArrayList<Card> tmpCards = new ArrayList<Card>();// 用来做牌移除
						ArrayList<Card> outCards = roomInfo.getLastOutCards();
						if(outCards!=null){
							synchronized (outCards) {
								outCards.clear();
							}
						}
						if (rpy.getPushCardListCount() > 0) {
							for (CardInfo info : rpy.getPushCardListList()) {
								if(outCards!=null){
									synchronized (outCards) {
										tmpCards.add(addCard(info, true));
										outCards.add(addCard(info));
									}
								}
							}
						}
						if(outCards!=null){
							synchronized (outCards) {
								Collections.sort(outCards, new CardAssist.Desc());
							}
						}
						roomInfo.setLastOutCardType(cardType);
						roomInfo.setLastOutHighcard(highcard);
						if (seatid == roomInfo.getSeatId()) {
							for (int i = 0; i < tmpCards.size(); i++) {
								Card card = tmpCards.get(i);
								roomInfo.removeCard(card);
							}
						} else {
							mContext.getRoom().getBtnManager().updatePlayPrompt();
						}
						synchronized (player) {
							// 托管时我出的牌就移除牌
							player.setState(UserState.USER_PLAY);
							if (!isRebinding) {
								player.setCardNum(player.getCardNum()
										- rpy.getPushCardListCount());
							}
						}
						if (seatid == roomInfo.getSeatId()) {// 如果出牌自己
							ArrayList<Card> myCards = RoomInfo.getInstance().getMyCards();
							if (null != myCards) {
								synchronized (myCards) {
									Collections.sort(myCards, new CardAssist.Desc());
								}
							}
							mContext.getRoom().getCardBtnManager().updateCard(null);
						}
						// 播放音效和动画
						playAnimaAndSound(tmpCards, lastOutCardSeatId, player,
								seatid);
					} else if (action == UserAction.PASS) { // 用户不出
						synchronized (player) {
							player.setState(UserState.USER_PLAY_GIVEUP);
							player.setOperateAction(UserState.USER_PLAY_GIVEUP);
						}
						DdzApplication.getApplication().play(AudioConfig.kPass,
								player.getSex());
					} else {// 用户发表情

					}
					if (action == UserAction.PLAY || action == UserAction.PASS) {
						mContext.addClockAnimation(nextseatid,
								roomInfo.getOperatetimeout());
						int selfSeatId = roomInfo.getSeatId();
						int lastOutCardSeatId = roomInfo.getLastOutCardSeatId();
						ArrayList<Card> outCards = roomInfo.getLastOutCards();
						// 上次出牌和这次出牌都是自己将lastOutCards清除
						if (nextseatid == lastOutCardSeatId
								&& nextseatid == selfSeatId
								&& !outCards.isEmpty()) {
							if(outCards!=null){
								synchronized (outCards) {
									outCards.clear();
								}
							}
						}
						// 更新出牌按钮操作状态
						ArrayList<Card> cards=mContext.getRoom().getCardBtnManager().getSelectCards();
						if(cards!=null){
							ArrayList<Card> tmpCards = null;
							synchronized (cards) {
								tmpCards=CardAssist.copyList(cards);
							}
							mContext.getRoom().getBtnManager().updateGameControlBtnState(tmpCards);
						}
					}
				}
			}
			if (nextseatid > 0) {
				if (nextseatid == roomInfo.getLastOutCardSeatId()) { // 如果当前操作者是上一个出牌玩家的话，将所有人状态都清除
					roomInfo.setLastOutCardSeatId(0);
					ArrayList<Card> outCards = roomInfo.getLastOutCards();
					if(outCards!=null){
						synchronized (outCards) {
							outCards.clear();
						}
					}
					roomInfo.setLastOutCardType(0);
					roomInfo.setLastOutHighcard(0);
					for (int i = 0, n = roomInfo.getPlayerLength(); i < n; i++) {
						int seatId = i + 1;
						Player player = RoomInfo.getInstance()
								.getPlayer(seatId);
						if (player != null) { // 代表用户存在并且已经准备
							synchronized (player) {
								player.setState(UserState.USER_PLAY_WAIT); // 进入玩牌阶段，所有人开始都是等待状态
							}
							Log.i(this, "seatId" + seatId + "-->state:"
									+ UserState.USER_PLAY_WAIT
									+ "---->出牌没有人要后重新开始一轮出牌");
						}
					}
				}

				Player player = roomInfo.getPlayer(nextseatid);
				if (player != null) {
					roomInfo.setCurSeatId(nextseatid);
					// roomInfo.setCurrentActionSeatId(nextseatid);
					synchronized (player) {
						player.setState(UserState.USER_PLAY_NEED);
					}
				}
				// 更新发送请求状态
				if (nextseatid == roomInfo.getSeatId()) {
					RoomInfo.getInstance().setSendReqing(false);
				}
			}

			Log.i(this, "--------------------------------");
		}
	}

	public void playAnimaAndSound(ArrayList<Card> outCards,
			int lastOutCardSeatId, Player player, int seatid) {
		CardJudge3_Laizi cardJudge3 = new CardJudge3_Laizi();
		CardReturn_Laizi cardReturn_Laizi = cardJudge3.judgeCardType(outCards);
		CardReturn cardReturn = CardReturn_Laizi.copy(cardReturn_Laizi);
		if (lastOutCardSeatId != 0 && outCards.size() > 2
				&& lastOutCardSeatId != seatid
				&& CardType.CardBombWith_4 != cardReturn.mCardType
				&& CardType.CardBombBoss != cardReturn.mCardType
				&& CardType.CardBigBombBoss != cardReturn.mCardType) {// 管上
			DdzApplication.getApplication().play(AudioConfig.kControl,
					player.getSex());
		} else {
			DdzApplication.getApplication().playCardEffect(
					cardReturn.mCardType, cardReturn.mCardHead.getPoint(),
					player.getSex());
			DdzApplication.getApplication()
					.playAnimEffect(cardReturn.mCardType);
		}
		// 播放对应的动画
		playCardAnimation(cardReturn.mCardType);
	}

	public void playCardAnimation(CardType cardType) {
		Animation animation = null;
		switch (cardType) {
		case CardChain:// 顺子
			animation = new AnimationChain();
			break;
		case CardChainPair:// 连对
			animation = new AnimationChainPair();
			break;

		case CardAirplaneNo:// 飞机
		case CardAirplaneOne:
		case CardAirplaneTwo:
			animation = new AnimationAirplane();
			break;

		case CardBombWith_4:// 炸弹
			animation = new AnimationBomb();
			break;

		case CardBombBoss:// 火箭
		case CardBigBombBoss:
			animation = new AnimationRocket();
			break;
		default:
			break;
		}
		if (null != animation) {
			AnimationManager.getInstance().addAnimation(animation);
		}
	}

	/**
	 * 聊天回应 required uint32 seatId = 1; //座位id optional string chatMsg = 2;
	 * //聊天信息 optional uint32 faceId = 3; //表情id optional uint32 roomId = 4;
	 * //table ID
	 * 
	 * @param body
	 */
	public void chatRpy(byte[] data) {
		BroadcastChat rpy = null;
		try {
			rpy = BroadcastChat.parseFrom(data);
		} catch (Exception e) {
			e.printStackTrace();
		}
		if (null != rpy) {
			int seatId = rpy.getSeatId();
			String chatMsg = rpy.getChatMsg();
			int faceId = rpy.getFaceId();
			int roomId = rpy.getRoomId();

			mContext.addToast(seatId, chatMsg);

			Log.i(this, "seatId:" + seatId + "-->chatMsg:" + chatMsg
					+ "---->faceId:" + faceId + "---->bombs:" + roomId
					+ "-->spring:" + roomId);
		}
	}

	/**
	 * 牌局结束
	 */
	public void gameOver(byte[] data) {
		GameOver rpy = null;
		try {
			rpy = GameOver.parseFrom(data);
		} catch (InvalidProtocolBufferException e) {
			e.printStackTrace();
		}

		if (null != rpy) {
			int winside = 0;
			if (rpy.hasWinSide()) {
				winside = rpy.getWinSide();
			}
			Log.i(this, "winside:" + winside);
			if (rpy.getResultCount() > 0) {
				RoomInfo roomInfo = RoomInfo.getInstance();
				for (GameResult result : rpy.getResultList()) {
					gameResult(result, winside);
				}
				Player selfPlayer = roomInfo.getSelfPlayer();
				if (null != selfPlayer) {
					DdzApplication.getApplication().getPlayMedia()
							.stopBgMusic();// 停止播放背景音乐
					long winminey = 0;
					synchronized (selfPlayer) {
						winminey = selfPlayer.getWinMoney();
					}
					if (winminey > 0) {
						DdzApplication.getApplication().play(AudioConfig.kWin);
					} else {
						DdzApplication.getApplication().play(AudioConfig.kLose);
					}
					synchronized (selfPlayer) {
						UserMessageCenter.getInstance().getUserInfo().setMoney(selfPlayer.getMoney());
						UserMessageCenter.getInstance().getUserInfo().setLottery(selfPlayer.getLottery());
					}
				}
				roomInfo.setState(GameState.GAME_OVER);
				mContext.getRoom().showSettleAccountWindow();
			}
			Log.i(this,
					"--------------------------------" + rpy.getResultCount());
		}
	}

	/**
	 * optional uint64 seatid = 1; //用户座位号 optional uint32 winMoney = 2; //赢得金钱
	 * optional uint32 winRatio = 3; //翻倍数 按座位 optional uint32 bombs = 4; //炸弹数
	 * 按座位 optional CardInfo seatCards = 5; //座位上剩余牌 optional uint32 spring = 6;
	 * //春天 按座位 optional uint32 reward = 7; //活动奖励 按座位 实现功能： 弹出结算对话框
	 */
	public void gameResult(GameResult result, int winside) {
		int seatid = 0;
		if (result.hasSeatid()) {
			seatid = result.getSeatid();
		}
		long winMoney = 0;
		if (result.hasWinMoney()) {
			winMoney = result.getWinMoney();
		}
		int winRatio = 0;
		if (result.hasWinRatio()) {
			winRatio = result.getWinRatio();
		}
		int bombs = 0;
		if (result.hasBombs()) {
			bombs = result.getBombs();
		}
		int spring = 0;
		if (result.hasSpring()) {
			spring = result.getSpring();
		}
		int reward = 0;
		if (result.hasReward()) {
			reward = result.getReward();
		}
		long money = 0;
		if (result.hasMoney()) {
			money = result.getMoney();
		}
		long lottery = 0;
		if (result.hasLottery()) {
			lottery = result.getLottery();
		}
		long winLottery = 0;
		if (result.hasWinLottery()) {
			winLottery = result.getWinLottery();
		}
		RoomInfo roomInFo = RoomInfo.getInstance();
		if (seatid > 0) {
			Player player = roomInFo.getPlayer(seatid);
			if (player != null) {
				synchronized (player) {
					if (seatid == roomInFo.getDizhuId() && winside == 1) {
						player.setWin(true);
					} else if (seatid != roomInFo.getDizhuId() && winside == 2) {
						player.setWin(true);
					} else {
						player.setWin(false);
					}
					player.setWinMoney(winMoney);
					player.setWinRatio(winRatio);
					player.setBombs(bombs);
					player.setSpring(spring);
					player.setReward(reward);
					player.setLottery(lottery);
					player.setWinLottery(winLottery);
					Log.i(this, result.getSeatCardsCount());

					ArrayList<Card> cards = player.getLimitedCards();
					if(cards!=null){
						synchronized (cards) {
							cards.clear();
							if (seatid == roomInFo.getSeatId()) {
								UserMessageCenter.getInstance().getUserInfo()
										.setLottery(lottery);
								UserMessageCenter.getInstance().getUserInfo()
										.setMoney(money);
								if(player.isWin()){
									UserMessageCenter.getInstance().getUserInfo().setWinCount(
											UserMessageCenter.getInstance().getUserInfo().getWinCount()+1);
									player.setWinCount(player.getWinCount()+1);
								}
								ArrayList<Card> mycards = RoomInfo.getInstance().getMyCards();
								if (null != mycards) {
									synchronized (mycards) {
										player.setLimitedCards(mycards);
									}
								}
								player.setMoney(money);
							} else {
								if (result.getSeatCardsCount() > 0) {
									for (CardInfo info : result.getSeatCardsList()) {
										cards.add(addCard(info));
									}
								}
							}
							Collections.sort(cards, new CardAssist.Desc());
						}
					}
				}
				Log.i(this, "seatid:" + seatid + "-->winMoney:" + winMoney
						+ "---->winRatio:" + winRatio + "---->bombs:" + bombs
						+ "-->spring:" + spring + "---->reward:" + reward
						+ ",money=" + money + ",lottery=" + lottery
						+ ",winLottery=" + winLottery);
			}
		}
	}

	/**
	 * 托管回应 optional uint32 seatid = 1; //托管座位 optional uint64 uid = 2; //托管uid
	 * optional uint32 isdeposited = 3; //1托管, 2取消托管 实现功能：更新头像托管UI
	 */
	public void depositRpy(byte[] data) {
		PlayerDepositRpy rpy = null;
		try {
			rpy = PlayerDepositRpy.parseFrom(data);
		} catch (InvalidProtocolBufferException e) {
			e.printStackTrace();
		}

		if (null != rpy) {
			long uid = 0;
			if (rpy.hasUid()) {
				uid = rpy.getUid();
			}
			int seatid = 0;
			if (rpy.hasSeatid()) {
				seatid = rpy.getSeatid();
			}
			int isdeposited = 0;
			if (rpy.hasIsdeposited()) {
				isdeposited = rpy.getIsdeposited();
			}
			Log.i(this, "uid:" + uid + "-->seatid:" + seatid
					+ "---->isdeposited:" + isdeposited);
			Log.i(this, "--------------------------------");
			if (seatid > 0 && isdeposited > 0) {
				Player player = RoomInfo.getInstance().getPlayer(seatid);
				if (player != null) {
					boolean bIsDeposited = isdeposited == 1 ? true : false;
					synchronized (player) {
						player.setDeposit(bIsDeposited);
					}
					if (RoomInfo.getInstance().getSeatId() == seatid) {
						RoomInfo.getInstance().setSendReqing(false);
						mContext.getRoom().getBtnManager().updateState(HandlerMsg.MSG_DISPOSIT,
								true, !bIsDeposited);
					}
				}
			}
		}
	}

	/**
	 * 广播新增的癞子牌 optional CardInfo laizicard = 1; //癞子牌 optional uint32 seatid =
	 * 2; //小癞子的玩家座位
	 * 
	 * @param data
	 * 
	 */
	public void addLaiZi(byte[] data,boolean isRebinding) {
		BroadcastLaiziCard rpy = null;
		try {
			rpy = BroadcastLaiziCard.parseFrom(data);
		} catch (InvalidProtocolBufferException e) {
			e.printStackTrace();
		}

		if (null != rpy) {
			RoomInfo roomInfo = RoomInfo.getInstance();
			if (rpy.hasLaizicard()) {
				CardInfo cardInfo = rpy.getLaizicard();
				Card card = new Card(cardInfo.getCardSuit(),
						cardInfo.getCardFace());
				boolean isSelectLaizi = (0 == roomInfo.getLaiziCnt()) ? true
						: false;
				if (!isSelectLaizi) {
					card.setSmallLaizi(true);
					if (rpy.getSeatid() == RoomInfo.getInstance().getSeatId()) {// 出牌过程中暴的癞子
						roomInfo.setLaiZiCard(card);
					}
					Log.i(this, "bomb LaiziCard=" + card.description());
				} else {// 第一次暴的癞子
					roomInfo.updateLaiziCard(card);
					Log.i(this, "select LaiziCard=" + card.description());
				}
				card.setLaiZi(true);
				roomInfo.addLaizi(card);
				ArrayList<Point> burstLaiziPosList = mContext.getRoom().getCardBtnManager().updateCard(card);
				if (null != burstLaiziPosList && !burstLaiziPosList.isEmpty()
						&& !isRebinding) {
					for (Point p : burstLaiziPosList) {
						int posY = p.y
								- (ConfigCenter.burst_Laizi_anim_H - ConfigCenter.self_hand_card_H);
						AnimationManager.getInstance().addAnimation(
								new AnimationBurstLaizi(p.x, posY));
					}
				}
				if (!isRebinding) {
					addLaiziAnimation(card, isSelectLaizi);
				} else {
					roomInfo.setLastLaiziSeaCardDisplay(true);
				}
			}
			int seatid = 0;
			if (rpy.hasSeatid()) {
				seatid = rpy.getSeatid();
			}
			Log.i(this, "seatid:" + seatid);
			Log.i(this, "--------------------------------");
		}
	}

	public void addLaiziAnimation(Card card, boolean isSelectLaizi) {
		RoomInfo roomInfo = RoomInfo.getInstance();
		roomInfo.setLastLaiziSeaCardDisplay(false);
		int laiziCnt = roomInfo.getLaiziCnt() - 1;
		int seaX = (DdzApplication.getApplication().screenWidth - ConfigCenter.seaW) / 2;
		int startX = seaX + ConfigCenter.sea_card_laizi_gap_border_Off_W;
		int offsetX = ConfigCenter.sea_card_laizi_Off_W;
		int posX = startX + laiziCnt * offsetX;

		Animation animation = null;
		if (isSelectLaizi) {
			animation = new AnimationSelectLaizi(
					ConfigCenter.select_laizi_anim_time, posX,
					ConfigCenter.burst_laizi_anim_des_Y, card);
		} else {
			animation = new AnimationTurnMoveLaizi(
					ConfigCenter.burst_laizi_anim_time, posX,
					ConfigCenter.burst_laizi_anim_des_Y, card);
		}
		AnimationManager.getInstance().addAnimation(animation,mContext.getRoom());
	}
}
