package com.backfire.socket;

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

import android.os.Handler;
import android.os.Looper;

import com.backfire.arithmetic.Card;
import com.backfire.arithmetic.CardAssist;
import com.backfire.doudizhu.common.DdzApplication;
import com.backfire.doudizhu.userinfo.UserInfo;
import com.backfire.doudizhu.userinfo.UserMessageCenter;
import com.backfire.room.Room;
import com.backfire.room.data.RoomInfo;
import com.backfire.socket.socketProto.Doudizhu.AuthReq;
import com.backfire.socket.socketProto.Doudizhu.CardInfo;
import com.backfire.socket.socketProto.Doudizhu.ChatReq;
import com.backfire.socket.socketProto.Doudizhu.PlayerDepositReq;
import com.backfire.socket.socketProto.Doudizhu.PlayerPlayActionReq;
import com.backfire.socket.socketProto.Doudizhu.QiangdizhuReq;
import com.backfire.socket.socketProto.Doudizhu.Ready;
import com.backfire.socket.socketProto.Doudizhu.RebindReq;
import com.backfire.socket.socketProto.Doudizhu.SeatReq;
import com.backfire.utils.Log;

public class SocketDataSend implements SocketConnectImp.OnSocketEvent{
	private Room mRoom;
	private SocketConnectImp socket;
	private SocketDataReceiveProcessor mProcessor;
	private boolean hasConnected = false;
	
	public SocketDataSend(Room mContext) {
		DdzApplication.getApplication().NetworkStatus = -1;
		this.mRoom = mContext;
	}
	
	public void Connect(String ip, int port)
	{
		mProcessor = new SocketDataReceiveProcessor(this.mRoom);
		socket = new SocketConnectImp();
		socket.setIP(ip);
		socket.setPORT(port);
		socket.setSocketEvent(this);
		socket.open();		
	}
	
	public void close() {
		Log.v(this, "close");
		if (socket != null) {
			socket.close();
			socket = null;
		}
		
		if (mProcessor != null) {
			mProcessor.close();
			mProcessor = null;
		}
	}

	public void onServerPacket(final int cmd, final DataPacket packet) {
		
		Handler handler = new Handler(Looper.getMainLooper());
		if (null!=handler) {
			Runnable r = new Runnable() {
				@Override
				public void run() {
					if (packet!=null && mProcessor!=null) {
						mProcessor.process(packet, cmd);
						if(null!=SocketDataSend.this.mRoom){
							SocketDataSend.this.mRoom.updateManagerBtn();
						}
						packet.recycle();
					}
				}
			};
			handler.post(r);
		}
	}

	public void onConnected() {
		hasConnected = true;
		//connected! OK, send login
		int roomId = UserMessageCenter.getInstance().getUserInfo().getRoomId();
		if(0!=roomId){
			RoomInfo.getInstance().setRebinding(true);
			rebindReq();
		}else{
			RoomInfo.getInstance().setRebinding(false);
			authReq();
		}
	}

	public void onReconnect(int num) {
		Log.i("onCmdSender", "on Reconnect");
	}

	public void onLogoutTimeout() {
		Log.w(this, "onLogoutTimeout");
		
		new Handler(Looper.getMainLooper()).post(new Runnable() {

			@Override
			public void run() {
				if(mRoom!=null)mRoom.onLogoutSuccess("网络异常，超时退出");
			}

		});
	}

	public void onFailed() {
		this.socket.close();
		//TODO 连接断开，要处理
		Log.w(this, "connect failed");
		Handler handler = new Handler(Looper.getMainLooper());
		if (handler != null ) {
			Runnable r = new Runnable() {
				@Override
				public void run() {
					if (hasConnected) {
						Log.w(this, "掉线了~~~");
						if(mRoom!=null)mRoom.onLogoutSuccess("网络异常，请检查您的网络");
					}
					else{
						Log.w(this, "网络错误");
						if(mRoom!=null)mRoom.onLogoutSuccess("网络异常，请检查您的网络");
					}
				}
			};
			handler.post(r);
		}
	}
	/**
	 * 发送认证请求
	 * optional	uint64 uid			= 1;	//用户id
	 * optional string key			= 2;	//用户session key
	 */
	public void authReq(){
		//建立一个请求坐下的protobuf
		UserInfo myself = UserMessageCenter.getInstance().getUserInfo();
		AuthReq auth = AuthReq.newBuilder().setUid(myself.getUid())
				.setKey(myself.getSession()).build();
		if(socket!=null)socket.sendCmd(DataPacket.createMsg(SocketCommand.CLI_AUTH_REQ, auth.toByteArray()));
	}
	
	/**
	 * 坐下位置请求
	 *  optional    uint64	uid         = 1;     //用户ID
	 * 	optional    uint32  seatId      = 2;     //座位ID
     *  optional    uint32  action      = 3;     //动作，1坐下，2站起
     *  optional    uint32  autoready   = 4;     //1自动准备 2不自动准备
     *  optional	uint32  roomid      = 5;     //房间ID
	 */
	public void seatReq(int action) {
		UserInfo userInfo=UserMessageCenter.getInstance().getUserInfo();
		SeatReq req=SeatReq.newBuilder().setUid(userInfo.getUid())
				.setAction(action)
				.setAutoready(2)
				.setRoomid(0).build();
		if(socket!=null){
			socket.sendCmd(DataPacket.createMsg(SocketCommand.CLI_USER_SIT_REQ, req.toByteArray()));
		}
	}
	
	/**
	 * 准备请求
	 * optional    uint32  isready     = 1;     //是否准备,如果不想在这个房间,可以发送这条指令,也可直接退出
	 * optional    uint32  handcardAnimMS  = 2; //发牌的动画时间(毫秒)
	 */
	public void readyReq() {
		Ready req=Ready.newBuilder().setIsready(1)
				.setHandcardAnimMS(3000).build();
		if(socket!=null){
			RoomInfo.getInstance().setSendReqing(true);
			socket.sendCmd(DataPacket.createMsg(SocketCommand.CLI_PLAYER_READY, req.toByteArray()));
		}
	}

	/**
	 * 抢地主请求
	 *  optional    uint32  ratio       = 1;    //抢地主,抢倍率
     *  optional    uint32  giveup      = 2;    // 0代表不抢地主，1代表抢地主
	 */
	public void qiangdizhuReq(int action) {
		QiangdizhuReq req=null;
		try {
			req=QiangdizhuReq.newBuilder().setRatio(RoomInfo.getInstance().getCurrRatio())
					.setGiveup(action).build();
		} catch (Exception e) {
			e.printStackTrace();
			return;
		}
		if(socket!=null){
			RoomInfo.getInstance().setSendReqing(true);
			socket.sendCmd(DataPacket.createMsg(SocketCommand.CLI_QIANGDIZHU_REQ, req.toByteArray()));
		}
	}

	/**
	 * 玩家动作请求（出牌，pass，发表情等）
	 * optional    uint64  uid             = 1;     //用户ID
     * optional    uint32  action          = 2;     //动作
     * repeated    CardInfo  pushCardList  = 3;     //出牌列表
     * optional    uint32  emotionId       = 4;     //表情ID
	 */
	public void playActionReq(ArrayList<Card> cards) {
		PlayerPlayActionReq.Builder builder=PlayerPlayActionReq.newBuilder()
				.setUid(UserMessageCenter.getInstance().getUserInfo().getUid())
				.setAction(RoomInfo.getInstance().getSelfPlayer().getAction())
				.setEmotionId(0);
		
		if(null!=cards&&!cards.isEmpty()){
			try {
				List<Card> tmpCards=CardAssist.copyList(cards);
				List<CardInfo> list=RoomInfo.getInstance().getSelectCardInfoList(tmpCards);
				if(null!=list&&0!=list.size()){
					builder.addAllPushCardList(list);
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	
		PlayerPlayActionReq req=builder.build();
		if(socket!=null){
			RoomInfo.getInstance().setSendReqing(true);
			socket.sendCmd(DataPacket.createMsg(SocketCommand.CLI_USER_PLAY_ACTION_REQ, req.toByteArray()));
		}
	}

	/**
	 * 重绑请求
	 *  optional  	uint64  uid         = 1;
     *	optional	string	session		= 2;
	 */
	public void rebindReq() {
		RebindReq req=RebindReq.newBuilder()
				.setUid(UserMessageCenter.getInstance().getUserInfo().getUid())
				.setSession(UserMessageCenter.getInstance().getUserInfo().getSession())
				.build();
		if(socket!=null){
			socket.sendCmd(DataPacket.createMsg(SocketCommand.CLI_REBIND_REQ, req.toByteArray()));
		}
	}

	/***
	 * 托管请求
	 * optional	uint32	isdeposited			= 1;	//1托管, 2取消托管
	 */
	public void depositReq(int action) {
		PlayerDepositReq req=PlayerDepositReq.newBuilder()
				.setIsdeposited(action)
				.build();
		if(socket!=null){
			RoomInfo.getInstance().setSendReqing(true);
			socket.sendCmd(DataPacket.createMsg(SocketCommand.CLI_PLAYER_DEPOSIT_REQ, req.toByteArray()));
		}
	}

	/**
	 * 发送聊天信息请求
	 */
	public void chatReq(String Message) {
		DataPacket packet = DataPacket.allocPacket();
		packet.writeBegin(SocketCommand.CLI_CHAT_REQ);
		UserInfo myself = UserMessageCenter.getInstance().getUserInfo();
		ChatReq l = ChatReq.newBuilder()
				.setUId(myself.getUid())
				.setSeatId(RoomInfo.getInstance().getSeatId())
				.setRoomId(UserMessageCenter.getInstance().getUserInfo().getRoomId())
				.setFaceId(RoomInfo.getInstance().getSelfPlayer().getFaceId())
				.setChatMsg(Message).build();
		packet.writeBody(l.toByteArray());
		packet.writeEnd();
		if(socket!=null)socket.sendCmd(packet);
	}
	
	/**
	 * 发送退出请求(返回大厅)
	 */
	public void logoutReq() {
		DataPacket packet = DataPacket.allocPacket();
		packet.writeBegin(SocketCommand.CLI_LOGIN_OUT_REQ);
		packet.writeEnd();
		if(socket!=null && socket.canUse()&&false){
			socket.sendCmd(packet);
			socket.setLogoutTimeout();
			// 设定5秒后自动关闭(哪怕接收不到成功退出的服务端包)
		}else{
			RoomInfo.getInstance().setSendReqing(true);
			mRoom.onLogoutSuccess(null);
		}
		
		//RoomInfo.getInstance().clearAll();
		
		//socket.setLogoutTimeout();
	}
}
