package com.bokecc.dwlivedemo.component;

import android.Manifest;
import android.app.Activity;
import android.content.Context;
import android.content.res.Configuration;
import android.util.SparseArray;
import android.view.KeyEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.Toast;

import com.bokecc.dwlivedemo.utils.PermissionRequestBean;
import com.bokecc.dwlivedemo.utils.PermissionUtils;
import com.bokecc.livemodule.live.DWLiveCoreHandler;
import com.bokecc.livemodule.live.DWLiveRTCListener;
import com.bokecc.livemodule.live.morefunction.rtc.RTCControlLayout;
import com.bokecc.livemodule.live.morefunction.rtc.RTCVideoLayout;
import com.bokecc.livemodule.live.multirtc.MultiRTCControlLayout;
import com.bokecc.livemodule.live.multirtc.MultiRTCVideoLayout;
import com.bokecc.livemodule.live.multirtc.RtcCommonMsgPopup;
import com.bokecc.livemodule.live.room.LiveRoomLayout;
import com.bokecc.livemodule.live.video.LiveVideoView;
import com.bokecc.livemodule.popup.FloatingPopupWindow;
import com.bokecc.livemodule.view.BasePopupWindow;
import com.bokecc.livemodule.view.CustomToast;
import com.bokecc.sdk.mobile.live.DWLive;
import com.bokecc.sdk.mobile.live.Exception.ErrorCode;
import com.bokecc.sdk.mobile.live.common.log.ELog;
import com.bokecc.sdk.mobile.live.stream.HDLiveMediaCallRole;
import com.bokecc.sdk.mobile.live.stream.LiveStreamPlayMode;
import com.bokecc.sdk.mobile.live.stream.RemoteStreamInfo;
import com.bokecc.sdk.mobile.live.stream.StreamErrorCode;
import com.bokecc.sdk.mobile.live.stream.live.rtc.HDMediaView;

import static android.view.View.VISIBLE;

/**
 * 连麦管理类 调用register前提是已经登录成功。保持原来单人连麦UI逻辑不变，增加多人连麦。
 * 由于多人连麦横竖屏UI复杂且与视频、悬浮窗等布局深度耦合，所以目前这个管理类必须传入相应的布局容器用于单人连麦、多人连麦状态调度以及UI显示
 * 业务说明：
 */
public class RTCComponent implements DWLiveRTCListener {
    //    private static final String TAG = "RTCComponent";
    private static final String TAG = "RTCComponent";

    private RTCVideoLayout mRtcVideoLayout;
    private MultiRTCControlLayout mMultiRTCControlLayout;
    private RelativeLayout mLiveMsgLayout;
    private MultiRTCVideoLayout mMultiRTCVideoLayout;
    private LiveRoomLayout mLiveRoomLayout;
    private RelativeLayout mVideoContainer;
    private FloatingPopupWindow mLiveFloatingView;
    private LiveVideoView mLiveVideoView;
    private RTCControlLayout mRtcControlLayout;

    private LinearLayout mVideoRightPanel;
    private RelativeLayout mVideoRightRTCCon;
    private RelativeLayout mVideoRightControlCon;
    private RelativeLayout mVideoBottomPanel;
    private boolean isInit = false;
    private Activity mContext;
    private ViewGroup mRootView;
    private ViewGroup mLiveTopLayout;

//    private RtcCommonMsgPopup mRtcCommonMsgPopup;

    private boolean lastAllowRtcFlag = false;


    //Popupwindow键值
    private static final int POP_KEY_RTC_SERVICE_INVALID = 0;
    private static final int POP_KEY_RTC_OPEN = 1;
    private static final int POP_KEY_MASTER_BREAK = 2;
    private static final int POP_KEY_STREAM_ERROR_MUST_EXIT = 3;
    private static final int POP_KEY_ROOM_SETTING_CHANGE_MUST_EXIT = 4;
    private static final int POP_KEY_NET_INVALID_MUST_EXIT = 5;
    private static final int POP_KEY_CANCEL_APPLY = 6;

    private SparseArray<RtcCommonMsgPopup> popupSparseArray = new SparseArray<>();

    /**
     * @param context              context
     * @param rootView             视图根布局，用于挂popupwindow
     * @param liveTopLayout        播放器容器，用于挂连麦控制组件
     * @param rtcVideoLayout       单人/多人连麦视频组件，用于填充rtc模式远端流（老师角色视频放入大屏）
     * @param liveRoomLayout       大屏视频控制器，视频控制器，引用目的为了在rtc模式下不显示error tips
     * @param videoContainer       大屏视频或者rtc video容器
     * @param liveFloatingView     悬浮窗，用于调度rtc与rtm流视频切换（上下麦操作）
     * @param liveVideoView        大屏视频组件，rtm流视频显示组件，用于与rtc组件调度
     * @param rtcControlLayout     单人连麦控制组件，单人连麦控制器与多人连麦走两套
     * @param controlLayout        多人连麦控制器，新版多人连麦控制器
     * @param liveMsgLayout        多人连麦控制器竖屏状态下的容器
     * @param multiRTCVideoLayout  多人连麦video展示组件
     * @param videoRightPanel      多人连麦横屏状态接通连麦状态下，视频右侧布局容器
     * @param videoRightRTCCon     多人连麦横屏状态接通连麦状态下，视频右侧布局 RTC展示video 容器
     * @param videoRightControlCon 多人连麦横屏状态接通连麦状态下，视频右侧布局 控制器 容器
     * @param videoBottomPanel     多人连麦竖屏状态接通连麦状态下，视频下方布局容器
     */
    public void register(
            Activity context,
            View rootView,
            ViewGroup liveTopLayout,
            RTCVideoLayout rtcVideoLayout,
            LiveRoomLayout liveRoomLayout,
            RelativeLayout videoContainer,
            FloatingPopupWindow liveFloatingView,
            LiveVideoView liveVideoView,
            RTCControlLayout rtcControlLayout,
            MultiRTCControlLayout controlLayout,
            RelativeLayout liveMsgLayout,
            MultiRTCVideoLayout multiRTCVideoLayout,
            LinearLayout videoRightPanel,
            RelativeLayout videoRightRTCCon,
            RelativeLayout videoRightControlCon,
            RelativeLayout videoBottomPanel) {
        if (rtcVideoLayout == null
                || rootView == null
                || liveTopLayout == null
                || controlLayout == null
                || multiRTCVideoLayout == null
                || liveFloatingView == null
                || liveVideoView == null
                || rtcControlLayout == null
                || liveRoomLayout == null
                || videoContainer == null
                || videoRightPanel == null
                || videoRightRTCCon == null
                || videoRightControlCon == null
                || videoBottomPanel == null) {
            throw new RuntimeException("demo_bokecc.RTCComponent register params must not be null");
        }
        this.mContext = context;
        this.mRtcVideoLayout = rtcVideoLayout;
        this.mMultiRTCControlLayout = controlLayout;
        this.mLiveMsgLayout = liveMsgLayout;
        this.mMultiRTCVideoLayout = multiRTCVideoLayout;
        this.mLiveRoomLayout = liveRoomLayout;
        this.mVideoContainer = videoContainer;
        this.mLiveFloatingView = liveFloatingView;
        this.mLiveVideoView = liveVideoView;
        this.mVideoRightPanel = videoRightPanel;
        this.mVideoRightRTCCon = videoRightRTCCon;
        this.mVideoRightControlCon = videoRightControlCon;
        this.mVideoBottomPanel = videoBottomPanel;
        this.mRootView = (ViewGroup) rootView;
        this.mLiveTopLayout = liveTopLayout;
        this.mRtcControlLayout = rtcControlLayout;
        init();
    }

    private void init() {
        // 设置连麦监听
        DWLiveCoreHandler dwLiveCoreHandler = DWLiveCoreHandler.getInstance();

        initSingleRTC();

        initMultiRTC();

        //初始化rtc回调,sdk回调给demo层
        dwLiveCoreHandler.initRtc();
        //连麦回调，demo层回调给本类
        dwLiveCoreHandler.setDwLiveRTCListener(this);

        ELog.d(TAG, "[demo_bokecc.RTCComponent.init]  init success");
        isInit = true;
    }


    private void initSingleRTC() {
        ELog.d(TAG, "[demo_bokecc.RTCComponent.initSingleRTC] empty, don`t care");
    }

    private void showMultiRtc(boolean show) {
        mMultiRTCControlLayout.setVisibility(show ? View.VISIBLE : View.GONE);
        if (!show) {//当rtc视频组件设置为不可见的时候，代表连麦结束，此时要尝试移除自己的预览视图
            mMultiRTCVideoLayout.removeVideo(MultiRTCVideoLayout.SELF_VIDEO_TAG);
        }
        mMultiRTCVideoLayout.setVisibility(show ? View.VISIBLE : View.GONE);

    }

    private void initMultiRTC() {
        showMultiRtc(false);
        mMultiRTCControlLayout.setOnRTCControlListener(new MultiRTCControlLayout.OnRTCControlListener() {
            @Override
            public void onCallClick() {
                //先检查权限
                if (mMultiRTCControlLayout.getCurrentState() == MultiRTCControlLayout.RECEIVE_CALL) {
                    ELog.d(TAG, "[demo_bokecc.RTCComponent.onCallClick] RECEIVE_CALL");
                    DWLiveCoreHandler.getInstance().agreeRTCCall();
                    //按钮直接显示中间态
                    mMultiRTCControlLayout.setCurrentState(MultiRTCControlLayout.CONNECTING);
                } else {
                    ELog.d(TAG, "[demo_bokecc.RTCComponent.onCallClick] NORMAL");

                    //检查存储权限
                    PermissionRequestBean permissionRequestBean = new PermissionRequestBean(new String[]{Manifest.permission.CAMERA, Manifest.permission.RECORD_AUDIO});

                    permissionRequestBean.request(mContext, new PermissionRequestBean.PermissionCallback() {
                        @Override
                        public void onResult(boolean success) {
                            if (success) {
                                DWLiveCoreHandler.getInstance().startRTCConnect(DWLiveCoreHandler.getInstance().isVideoRtc());
                            } else {
                                Toast.makeText(mContext, "前往系统权限设置页面中手动打开相机与录音权限后方可使用连麦功能", Toast.LENGTH_SHORT).show();
                            }
                        }

                    });
                }
            }

            @Override
            public void onBreakClick() {
                String msg = "确定要结束连麦吗？";
                switch (mMultiRTCControlLayout.getCurrentState()) {
                    case MultiRTCControlLayout.RECEIVE_CALL:
                        msg = "确认要拒绝连麦邀请吗？";
                        break;
                    case MultiRTCControlLayout.CALLING:
                        msg = "确认要取消连麦申请吗？";
                        break;
                    default:
                        break;
                }
                //弹窗提示
                showPopupWindow(
                        POP_KEY_CANCEL_APPLY,
                        "提示",
                        msg,
                        false,
                        true,
                        new RtcCommonMsgPopup.CommonPopListener() {
                            @Override
                            public void onOkClick(BasePopupWindow popupWindow) {
                                popupWindow.dismiss();
                                if (mMultiRTCControlLayout.getCurrentState() == MultiRTCControlLayout.RECEIVE_CALL) {
                                    ELog.d(TAG, "[demo_bokecc.RTCComponent.onBreakClick] RECEIVE_CALL");
                                    DWLiveCoreHandler.getInstance().refuseSpeak();
                                } else {
                                    DWLiveCoreHandler.getInstance().disConnectSpeak();
                                }
                            }

                            @Override
                            public void onCancelClick(BasePopupWindow popupWindow) {
                                popupWindow.dismiss();
                            }
                        });
            }

            @Override
            public void onBreakDisableClick() {
                showToast("操作频繁，请稍后再试", true);
            }

            @Override
            public void onMicStateChange(boolean on) {
                ELog.d(TAG, "[demo_bokecc.RTCComponent.onMicStateChange]  [on=" + on + "]");
                DWLiveCoreHandler.getInstance().changeMicState(on);
            }

            @Override
            public void onCameraStateChange(boolean on) {
                ELog.d(TAG, "[demo_bokecc.RTCComponent.onCameraStateChange]  [on=" + on + "]");
                DWLiveCoreHandler.getInstance().changeCameraState(on);
            }

            @Override
            public void onCameraSwitch(boolean isCameraOn, boolean isCameraFront) {
                ELog.d(TAG, "[demo_bokecc.RTCComponent.onCameraSwitch]  [isCameraOn=" + isCameraOn + ",isCameraFront=" + isCameraFront + "]");
                //禁用摄像头期间禁止切换
                if (isCameraOn) {
                    if (isCameraFront) {
                        showToast("切换为前置摄像头", true);
                    } else {
                        showToast("切换为后置摄像头", true);
                    }
                    DWLiveCoreHandler.getInstance().switchCamera();
                } else {
                    showToast("摄像头已禁用，不可切换", true);
                }
            }
        });
    }

    /**
     * 主线程显示toast
     *
     * @param msg          内容
     * @param isShortToast true，short   false，long
     */
    private void showToast(final String msg, final boolean isShortToast) {
        if (mContext != null) {
            mContext.runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    CustomToast.showToast(mContext, msg, isShortToast ? Toast.LENGTH_SHORT : Toast.LENGTH_LONG);
                }
            });
        }

    }


    //屏幕旋转
    public void onConfigurationChanged(Configuration newConfig) {
        ELog.d(TAG, "[demo_bokecc.RTCComponent.onConfigurationChanged]  [newConfig.orientation = " + newConfig.orientation + "]");
        if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
            // 视频联通状态，右侧视频面板显示，并且把连麦video组件放入其中
            if (DWLiveCoreHandler.getInstance().isMultiRtc()
                    && (mMultiRTCControlLayout.getCurrentState() == MultiRTCControlLayout.ANSWERING_VIDEO)) {
                showMultiRtcPanel(true, true);
            } else {
                showMultiRtcPanel(true, false);
            }
        } else {
            //竖屏状态下如果是多人连麦视频联通状态
            if (DWLiveCoreHandler.getInstance().isMultiRtc()
                    && mMultiRTCControlLayout.getCurrentState() == MultiRTCControlLayout.ANSWERING_VIDEO
                    && DWLiveCoreHandler.getInstance().isVideoRtc()) {
                showMultiRtcPanel(false, true);
            } else {
                showMultiRtcPanel(false, false);
            }
        }
    }


    //根据横竖屏状态和是否在通话中，来确定应用哪种布局方案
    private void showMultiRtcPanel(boolean land, boolean isConnected) {
        ELog.d(TAG, "[demo_bokecc.RTCComponent.showMultiRtcPanel]  [land=" + land + ", isConnected=" + isConnected + "]");
        if (land && isConnected) {
            mVideoRightPanel.setVisibility(VISIBLE);
            mVideoBottomPanel.removeAllViews();
            mVideoRightRTCCon.removeAllViews();
            mVideoRightRTCCon.addView(mMultiRTCVideoLayout);
            mMultiRTCVideoLayout.changeOrientation(land);
            //添加控制器
            mVideoRightControlCon.removeAllViews();
            //控制器添加
            //控制器添加
            ViewGroup controlParnt = ((ViewGroup) mMultiRTCControlLayout.getParent());
            if (controlParnt != null) {
                controlParnt.removeView(mMultiRTCControlLayout);
            }
            mVideoRightControlCon.addView(mMultiRTCControlLayout);
            mMultiRTCControlLayout.setLandScape(true);
//            if (DWLiveCoreHandler.getInstance().isVideoRtc()) {
//                mMultiRTCControlLayout.setLandScape(true);
//            } else {
//                mMultiRTCControlLayout.setLandScape(false);
//            }
        } else if (land && DWLiveCoreHandler.getInstance().isMultiStreamMode()) {//横屏分流未联通状态
            //显示右侧面板
            mVideoRightPanel.setVisibility(VISIBLE);
            mVideoBottomPanel.removeAllViews();
            mVideoRightRTCCon.removeAllViews();
            mVideoRightRTCCon.addView(mMultiRTCVideoLayout);
            mMultiRTCVideoLayout.changeOrientation(land);
            //隐藏bottom面板
            mVideoBottomPanel.removeAllViews();
            mVideoRightControlCon.removeAllViews();
            //控制器添加
            ViewGroup controlParnt = ((ViewGroup) mMultiRTCControlLayout.getParent());
            if (controlParnt != null) {
                controlParnt.removeView(mMultiRTCControlLayout);
            }
            mLiveTopLayout.addView(mMultiRTCControlLayout);
            mMultiRTCControlLayout.setLandScape(false);
        } else if (land) {//横屏非分流未联通状态
            //隐藏right面板
            mVideoRightPanel.setVisibility(View.GONE);
            mVideoRightRTCCon.removeAllViews();
            //隐藏bottom面板
            mVideoBottomPanel.removeAllViews();
            mVideoRightControlCon.removeAllViews();
            //控制器添加
            ViewGroup controlParnt = ((ViewGroup) mMultiRTCControlLayout.getParent());
            if (controlParnt != null) {
                controlParnt.removeView(mMultiRTCControlLayout);
            }
            mLiveTopLayout.addView(mMultiRTCControlLayout);
            mMultiRTCControlLayout.setLandScape(false);
        } else {
            mVideoRightPanel.setVisibility(View.GONE);
            mVideoRightRTCCon.removeAllViews();
            mVideoBottomPanel.removeAllViews();
            mVideoBottomPanel.addView(mMultiRTCVideoLayout);
            mMultiRTCVideoLayout.changeOrientation(land);
            //控制器添加
            //控制器添加
            ViewGroup controlParnt = ((ViewGroup) mMultiRTCControlLayout.getParent());
            if (controlParnt != null) {
                controlParnt.removeView(mMultiRTCControlLayout);
            }
            mLiveMsgLayout.addView(mMultiRTCControlLayout);
            mMultiRTCControlLayout.setLandScape(false);
        }
    }

    //释放
    public void release() {
        ELog.d(TAG, "[demo_bokecc.RTCComponent.release] release success");
    }

    //根据状态调度UI view,先决条件：是否是横屏、是否是多人连麦、是否是分流、是否是视频连麦、是否正在连麦
    private void refreshUI(boolean connected) {
        //1. 大屏和悬浮窗切换
        //2. 控制器状态切换
        //3. 横竖屏UI切换
        boolean isLand = mContext.getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE;
        boolean isMultiRtc = DWLiveCoreHandler.getInstance().isMultiRtc();
        boolean isMultiStream = DWLiveCoreHandler.getInstance().isMultiStreamMode();
        boolean isVideoMode = DWLiveCoreHandler.getInstance().isVideoRtc();
        boolean isVideoMain = mLiveRoomLayout.isVideoMain();
        boolean isAllowRtc = DWLiveCoreHandler.getInstance().isAllowRtc();

        ELog.d(TAG, "[demo_bokecc.RTCComponent.refreshUI]" +
                "  [connected=" + connected + ",isLand=" + isLand + "," +
                "isMultiRtc=" + isMultiRtc + ",isMultiStream=" + isMultiStream + "," +
                "isVideoMode=" + isVideoMode + ",isVideoMain=" + isVideoMain + ",isAllowRtc=" + isAllowRtc + "]");


        if (connected) {//开启连麦
            if (isVideoMode) {//视频连麦
                if (mRtcVideoLayout.getParent() != null) {
                    ((ViewGroup) (mRtcVideoLayout.getParent())).removeView(mRtcVideoLayout);
                }
                //大小屏切换
                if (isVideoMain) {
                    mVideoContainer.addView(mRtcVideoLayout);
                } else {
                    mLiveFloatingView.addView(mRtcVideoLayout);
                }
                //横竖屏布局切换
                showMultiRtcPanel(isLand, true);
                //切换大屏 视频与连麦
                if (mLiveVideoView != null) {
                    mLiveVideoView.enterRtcMode(isVideoMode);
                }
                if (mRtcVideoLayout != null) {
                    mRtcVideoLayout.enterSpeak(isVideoMode);
                }
            }

            //控制器状态进入连麦
            if (isMultiRtc) {
                if (mMultiRTCControlLayout != null) {
                    mMultiRTCControlLayout.onRTCAvailableTypeChange(isAllowRtc, isVideoMode);
                    mMultiRTCControlLayout.onEnterRTC(isVideoMode);
                }
            } else {
                if (mRtcControlLayout != null) {
                    mRtcControlLayout.onEnterRTC(isVideoMode);
                }
            }
        } else {//断开连麦
            if (isMultiStream) {//分流模式
                if (isMultiRtc) {
                    //只移除自己的预览
                    if (mMultiRTCVideoLayout != null) {
                        mMultiRTCVideoLayout.removeVideo(MultiRTCVideoLayout.SELF_VIDEO_TAG);
                    }
                }
            } else {
                if (mRtcVideoLayout != null) {
                    mRtcVideoLayout.disconnectSpeak();
                }
                if (mLiveVideoView != null) {
                    if (isVideoMode) {
                        if (mLiveVideoView.getParent() != null) {
                            ((ViewGroup) (mLiveVideoView.getParent())).removeView(mLiveVideoView);
                        }
                        if (isVideoMain) {
                            mVideoContainer.addView(mLiveVideoView);
                        } else {
                            mLiveFloatingView.addView(mLiveVideoView);
                        }
                    }
                    mLiveVideoView.exitRtcMode();
                }
                if (isMultiRtc) {
                    //移除多人连麦视频组件
                    if (mMultiRTCVideoLayout != null) {
                        mMultiRTCVideoLayout.removeAllVideo();
                        mMultiRTCVideoLayout.setVisibility(View.GONE);
                    }
                }
                //修改rtc video组件与控制器布局状态
                if (isVideoMode) {
                    showMultiRtcPanel(isLand, false);
                }
            }
            //修改控制器布局状态
            if (DWLiveCoreHandler.getInstance().isMultiRtc()) {
                if (mMultiRTCControlLayout != null) {
                    mMultiRTCControlLayout.setLandScape(false);
                    mMultiRTCControlLayout.onRTCAvailableTypeChange(isAllowRtc, isVideoMode);
                    mMultiRTCControlLayout.onExitRTC();
                }
            } else {
                if (mRtcControlLayout != null) {
                    mRtcControlLayout.onExitRTC();
                }
            }

            showMultiRtc(false);
            if (isAllowRtc && isMultiRtc) {
                showMultiRtc(true);
            }
            showMultiRtcPanel(isLand, false);
        }

    }


    // region -------------------- DWLiveRTCListener回调 -------------------------

    @Override
    public void onEnterSpeak(boolean isVideoRtc) {//进入连麦（发起连麦就算，不一定要接通）
        ELog.d(TAG, "[demo_bokecc.RTCComponent.onEnterSpeak]  [isVideoRtc = " + isVideoRtc + "]");
        refreshUI(true);
    }

    @Override
    public void onDisconnectSpeak() {//连麦结束
        ELog.d(TAG, "[demo_bokecc.RTCComponent.onDisconnectSpeak]");
        refreshUI(false);
    }

    @Override
    public void onSpeakError(final String msg, final int code) {//连麦错误
        ELog.d(TAG, "[demo_bokecc.RTCComponent.onSpeakError]  [msg = " + msg + ", code=" + code + "]  ");
        //走下麦流程
        onDisconnectSpeak();
        showToast(msg, false);
    }

    @Override
    public void onMessageShow(String msg) {
        showToast(msg, true);
    }

    @Override
    public void onRemoteStreamEnable(boolean mIsVideoRtc, String userId, String role) {//远端流可用
        ELog.d(TAG, "[demo_bokecc.RTCComponent.onRemoteStreamEnable]  [mIsVideoRtc = " + mIsVideoRtc + ", userId = " + userId + ", role = " + role + "]");
        //如果不是无延迟直播，并且自己没有上麦，那么不订阅
        if (!DWLiveCoreHandler.getInstance().isMultiStreamMode() && !DWLiveCoreHandler.getInstance().isOnCalling()) {
            return;
        }
        DWLiveCoreHandler.getInstance().pullRemoteStreamByStreamId(userId, role);
    }

    private String teacherId;

    @Override
    public void onRemoteStreamAdded(HDMediaView hdMediaView, String userId, String role, RemoteStreamInfo info) {//远端流添加
        ELog.d(TAG, "[demo_bokecc.RTCComponent.onRemoteStreamAdded]  [hdMediaView = " + hdMediaView + ", userId = " + userId + ", role = " + role + ", info==null = " + (info == null) + "]");
        if (hdMediaView == null || userId == null || role == null) {
            return;
        }
        if (HDLiveMediaCallRole.TEACHER.equals(role)) {
            teacherId = userId;
        }
        if (mMultiRTCVideoLayout != null) {
            mMultiRTCVideoLayout.setVisibility(VISIBLE);
            //多人连麦添加
            if (HDLiveMediaCallRole.TEACHER.equals(role) && (DWLiveCoreHandler.getInstance().isVideoRtc() || DWLiveCoreHandler.getInstance().isMultiStreamMode())) {
                //如果大屏布局没显示出来，需要切换
                //分流，或者是视频连麦，老师视频加到大窗
                if (mRtcVideoLayout != null) {
//                    if (mRtcVideoLayout.getVisibility() == View.GONE) {
                    if (mRtcVideoLayout.getParent() != null) {
                        ((ViewGroup) (mRtcVideoLayout.getParent())).removeView(mRtcVideoLayout);
                    }
                    if (mLiveRoomLayout.isVideoMain()) {
                        mVideoContainer.addView(mRtcVideoLayout);
                    } else {
                        mLiveFloatingView.addView(mRtcVideoLayout);
                    }
                    //切换大屏 视频与连麦
                    if (mLiveVideoView != null) {
                        mLiveVideoView.enterRtcMode(DWLiveCoreHandler.getInstance().isVideoRtc() || DWLiveCoreHandler.getInstance().isMultiStreamMode());
                    }
                    if (mRtcVideoLayout != null) {
                        mRtcVideoLayout.enterSpeak(DWLiveCoreHandler.getInstance().isVideoRtc() || DWLiveCoreHandler.getInstance().isMultiStreamMode());
                    }
//                    }
                    //老师布局添加到大屏幕
                    mRtcVideoLayout.addVideo(hdMediaView, userId, role, info);
                }
                //
            } else {
                if (DWLiveCoreHandler.getInstance().isVideoRtc() && DWLiveCoreHandler.getInstance().isMultiRtc()) {
                    mMultiRTCVideoLayout.addVideo(hdMediaView, userId, role, info);
                }
            }
        }
    }

    @Override
    public void onRemoteStreamRemoved(String userId) {//远端流移除
        if (userId == null || userId.equals("")) {
            ELog.e(TAG, "[demo_bokecc.RTCComponent.onRemoteStreamRemoved]  [userId=" + userId + "]  userId must not be null");
            return;
        } else {
            ELog.d(TAG, "[demo_bokecc.RTCComponent.onRemoteStreamRemoved]  [userId = " + userId + "]");
        }
        DWLiveCoreHandler.getInstance().removeRemoteStreamByStreamId(userId);

        //多人连麦移除，内部进行判断
        if (mMultiRTCVideoLayout != null) {
            mMultiRTCVideoLayout.removeVideo(userId);
            if (mMultiRTCVideoLayout.getChildCount() == 0) {
                //空，横屏移除
            }
        }
        if (mRtcVideoLayout != null) {
            mRtcVideoLayout.removeVideo(userId);
        }

        //如果在移除view
    }

    @Override
    public void onMasterBreak() {//老师主动挂断
        ELog.d(TAG, "[demo_bokecc.RTCComponent.onMasterBreak]  master hang up");
        showToast("讲师中断了您的连麦", false);
        onDisconnectSpeak();
    }

    @Override
    public void onRoomSettingChange(int code) {//后台通知连麦房间变化，退出Activity
        ELog.d(TAG, "[demo_bokecc.RTCComponent.onRoomSettingChange] may be you need execute re login operation for live room");
        //断开连麦
        onDisconnectSpeak();
        boolean isRoomSettingChanged = code == ErrorCode.ROOM_SETTING_CHANGE.getCode();
        showPopupWindow(
                isRoomSettingChanged ? POP_KEY_ROOM_SETTING_CHANGE_MUST_EXIT : POP_KEY_NET_INVALID_MUST_EXIT,
                "提示",
                isRoomSettingChanged ? "连麦服务变更，请重新登录" : "您的网络异常，请重新登录，尝试恢复",
                true,
                false,
                new RtcCommonMsgPopup.CommonPopListener() {
                    @Override
                    public void onOkClick(BasePopupWindow popupWindow) {
                        popupWindow.dismiss();
                        if (mContext != null) {
                            mContext.finish();
                        }
                    }

                    @Override
                    public void onCancelClick(BasePopupWindow popupWindow) {
                        popupWindow.dismiss();
                    }
                }
        );
    }

    @Override
    public void onStreamError() {
        ELog.d(TAG, "[demo_bokecc.RTCComponent.onStreamError]");
        //先走断开连麦，再弹窗
        onDisconnectSpeak();
        showPopupWindow(
                POP_KEY_STREAM_ERROR_MUST_EXIT,
                "提示",
                "网络异常，请确认是否重新登录恢复连麦服务",
                false,
                false,
                new RtcCommonMsgPopup.CommonPopListener() {
                    @Override
                    public void onOkClick(BasePopupWindow popupWindow) {
                        popupWindow.dismiss();
                        if (mContext != null) {
                            mContext.finish();
                        }
                    }

                    @Override
                    public void onCancelClick(BasePopupWindow popupWindow) {
                        popupWindow.dismiss();
                    }
                });
    }

    @Override
    public void onRTCModeChanged(boolean isAllowRtc, boolean isMultiRtc, boolean isVideoRtc) {//后台通知连麦状态改变
        ELog.d(TAG, "[demo_bokecc.RTCComponent.onRTCModeChanged]  [isAllowRtc = " + isAllowRtc + ", isMultiRtc = " + isMultiRtc + ", isVideoRtc = " + isVideoRtc + "]");

        //连麦功能关闭，弹出提示，isAllowRtc与上次值不一样，并且为false时弹出提示
        if (!isAllowRtc && lastAllowRtcFlag) {
            showPopupWindow(
                    POP_KEY_MASTER_BREAK,
                    "连麦提示",
                    "讲师结束连麦",
                    true,
                    true,
                    new RtcCommonMsgPopup.CommonPopListener() {
                        @Override
                        public void onOkClick(BasePopupWindow popupWindow) {
                            popupWindow.dismiss();
                        }

                        @Override
                        public void onCancelClick(BasePopupWindow popupWindow) {
                            popupWindow.dismiss();
                        }
                    });
        } else if (isAllowRtc && !lastAllowRtcFlag) {
            showPopupWindow(
                    POP_KEY_RTC_OPEN,
                    "提示",
                    "讲师开启了连麦，赶快去申请吧~",
                    true,
                    true,
                    new RtcCommonMsgPopup.CommonPopListener() {
                        @Override
                        public void onOkClick(BasePopupWindow popupWindow) {
                            popupWindow.dismiss();
                        }

                        @Override
                        public void onCancelClick(BasePopupWindow popupWindow) {
                            popupWindow.dismiss();
                        }
                    });
        }
        if (isMultiRtc) {
            //多人连麦直接挂断
            onDisconnectSpeak();
        } else {
            if (!isAllowRtc) {
                onDisconnectSpeak();
            }
        }


        if (DWLiveCoreHandler.getInstance().isMultiRtc()) {//多人连麦连麦
            if (mMultiRTCControlLayout != null) {
                mMultiRTCControlLayout.onRTCAvailableTypeChange(isAllowRtc, DWLiveCoreHandler.getInstance().isVideoRtc());
                mMultiRTCControlLayout.onExitRTC();
            }
        } else {
            //单人连麦问题：34179 断网重连，回调状态相同导致连麦组建消失
            if (lastAllowRtcFlag != isAllowRtc) {
                if (mRtcControlLayout != null) {
                    mRtcControlLayout.onExitRTC();
                }
            }
        }
        lastAllowRtcFlag = isAllowRtc;


    }

    @Override
    public void onAudioStatusChange(String userId, boolean isAllowAudio, boolean isSelf, boolean isRemote) {//收到音频状态改变
        ELog.d(TAG, "[demo_bokecc.RTCComponent.onAudioStatusChange]  [userId=" + userId + ", isAllowAudi=" + isAllowAudio + ", isSelf=" + isSelf + "，isRemote=" + isRemote + "]");
        if (mMultiRTCControlLayout != null && isSelf) {
            String msg = (isRemote ? "讲师" : "您已") + (isAllowAudio ? "开启" : "关闭") + "了" + (isRemote ? "您的" : "") + "麦克风";
            showToast(msg, true);
            mMultiRTCControlLayout.setMicOn(isAllowAudio);
        }
    }

    @Override
    public void onVideoStatusChange(String userId, boolean isAllowVideo, boolean isSelf, boolean isRemote) {//收到视频状态改变
        ELog.d(TAG, "[demo_bokecc.RTCComponent.onVideoStatusChange]  [userId=" + userId + ", isAllowVideo=" + isAllowVideo + ", isSelf=" + isSelf + "，isRemote=" + isRemote + "]");
        if (mMultiRTCVideoLayout != null) {
            mMultiRTCVideoLayout.updateItemViewState(userId, isAllowVideo);
            if (isSelf) {
                mMultiRTCVideoLayout.updateItemViewState(MultiRTCVideoLayout.SELF_VIDEO_TAG, isAllowVideo);
            }
        }
        if (mMultiRTCControlLayout != null && isSelf) {
            String msg = (isRemote ? "讲师" : "您已") + (isAllowVideo ? "开启" : "关闭") + "了" + (isRemote ? "您的" : "") + "摄像头";
            showToast(msg, true);
            mMultiRTCControlLayout.setCameraOn(isAllowVideo);
        }
    }

    @Override
    public void onPlayModeChange(LiveStreamPlayMode.MODE mode) {//scRole 7 rtc模式
        ELog.d(TAG, "[demo_bokecc.RTCComponent.onPlayModeChange]  [mode=" + mode + "]");
        //后台配置直播模式发生变化，低延迟、超低延迟、无延迟（分流RTC）
        if (mode == LiveStreamPlayMode.MODE.NO_DELAY) {
            //切换大屏布局
            if (mRtcVideoLayout.getParent() != null) {
                ((ViewGroup) (mRtcVideoLayout.getParent())).removeView(mRtcVideoLayout);
            }
            if (mLiveRoomLayout.isVideoMain()) {
                mVideoContainer.addView(mRtcVideoLayout);
            } else {
                mLiveFloatingView.addView(mRtcVideoLayout);
            }
            //横竖屏布局切换
            boolean isLand = mContext.getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE;
            showMultiRtcPanel(isLand, DWLiveCoreHandler.getInstance().isRtcing());
            //切换大屏 视频与连麦
            if (mLiveVideoView != null) {
                mLiveVideoView.enterRtcMode(true);
            }
            if (mRtcVideoLayout != null) {
                mRtcVideoLayout.enterSpeak(true);
            }

        } else {
            refreshUI(false);
        }
    }

    @Override
    public void onHideVideoLayout() {
        DWLive.getInstance().removeRemoteStream(teacherId, null);
        if (mMultiRTCVideoLayout != null) {
            mMultiRTCVideoLayout.removeAllVideo();
            mMultiRTCVideoLayout.setVisibility(View.GONE);
        }
    }

    @Override
    public void onShowVideoLayout() {
        if (mMultiRTCVideoLayout != null) {
            mMultiRTCVideoLayout.setVisibility(VISIBLE);
        }
    }

    @Override
    public void onStartCallFail(int code) {//主动呼叫报错
        if (code == StreamErrorCode.NUMBER_OF_TRANSFINITE) {
            onSpeakError("抱歉，连麦人数已达上限", code);
        } else if (code == StreamErrorCode.LECTURER_NOT_RESPOND) {
            //不做提示
        }else if (code == StreamErrorCode.RTC_SERVICE_PREPARING){
            showPopupWindow(
                    POP_KEY_MASTER_BREAK,
                    "提示",
                    "连麦服务器初始化，请稍后重试",
                    true,
                    true,
                    new RtcCommonMsgPopup.CommonPopListener() {
                        @Override
                        public void onOkClick(BasePopupWindow popupWindow) {
                            popupWindow.dismiss();
                        }

                        @Override
                        public void onCancelClick(BasePopupWindow popupWindow) {
                            popupWindow.dismiss();
                        }
                    });
        }else {
            showPopupWindow(
                    POP_KEY_MASTER_BREAK,
                    "提示",
                    "申请上麦失败，请重试",
                    true,
                    true,
                    new RtcCommonMsgPopup.CommonPopListener() {
                        @Override
                        public void onOkClick(BasePopupWindow popupWindow) {
                            popupWindow.dismiss();
                        }

                        @Override
                        public void onCancelClick(BasePopupWindow popupWindow) {
                            popupWindow.dismiss();
                        }
                    });
        }
        if (DWLiveCoreHandler.getInstance().isMultiRtc()) {//多人连麦
            if (mMultiRTCControlLayout != null) {
                mMultiRTCControlLayout.onExitRTC();
            }
        } else {//单人连麦
            //单人连麦控制器状态
            if (mRtcControlLayout != null) {
                mRtcControlLayout.onExitRTC();
            }
        }

    }

    @Override
    public void onStartCallSuccess(HDMediaView hdMediaView) {
        onEnterSpeak(DWLiveCoreHandler.getInstance().isVideoRtc());
        if (hdMediaView != null && DWLiveCoreHandler.getInstance().isVideoRtc()) {//单人连麦本地预览不显示
            RemoteStreamInfo info = new RemoteStreamInfo();
            String nickName = "我";
            if (DWLive.getInstance().getViewer() != null && DWLive.getInstance().getViewer().getName() != null && !DWLive.getInstance().getViewer().getName().equals("")) {
                nickName = DWLive.getInstance().getViewer().getName();
            }
            info.setUserName("(我)" + nickName);
            info.setAllowVideo(true);
            info.setAllowAudio(true);
            onRemoteStreamAdded(hdMediaView, MultiRTCVideoLayout.SELF_VIDEO_TAG, HDLiveMediaCallRole.STUDENT, info);
        }
    }

    @Override
    public void onStartCall() {
        //开始连麦，控制器状态置为申请中
        if (DWLiveCoreHandler.getInstance().isMultiRtc()) {//多人连麦连麦
            if (mMultiRTCControlLayout != null) {
                mMultiRTCControlLayout.onCalling();
            }
        } else {
            if (mRtcControlLayout != null) {
                mRtcControlLayout.onCalling();
            }
        }
    }

    @Override
    public void onReceiveCall() {
        //收到上麦邀请，控制器状态置为收到申请
        if (DWLiveCoreHandler.getInstance().isMultiRtc()) {//多人连麦连麦
            if (mMultiRTCControlLayout != null) {
                mMultiRTCControlLayout.onReceiveCall();
            }
        } else {
            if (mRtcControlLayout != null) {
                mRtcControlLayout.onReceiveCall();
            }
        }
    }

    @Override
    public void onReceiveCancelCall() {
        //收到取消上麦邀请，控制器状态置为idle
        if (DWLiveCoreHandler.getInstance().isMultiRtc()) {//多人连麦连麦
            if (mMultiRTCControlLayout != null) {
                mMultiRTCControlLayout.onReceiveCancelCall();
            }
        } else {
            if (mRtcControlLayout != null) {
                mRtcControlLayout.onReceiveCancelCall();
            }
        }
    }

    @Override
    public void onMasterRefuseCall() {
        //讲师拒绝连麦
        showToast("讲师取消了连麦邀请", false);
        if (DWLiveCoreHandler.getInstance().isMultiRtc()) {//多人连麦连麦
            if (mMultiRTCControlLayout != null) {
                mMultiRTCControlLayout.onExitRTC();
            }
        } else {
            if (mRtcControlLayout != null) {
                mRtcControlLayout.onExitRTC();
            }
        }
    }


    // endregion


    /**
     * 由于popupwindow在6.0之后不能处理back按键事件，所以需要activity传递事件过来，pop判断是否需要消费
     * 调用此方法前提是pop没有获取焦点，keydown事件能被activity捕获
     *
     * @param keyCode 按键
     * @param event   事件
     * @return 是否消费
     */
    public boolean performKeyDown(int keyCode, KeyEvent event) {
//        if (mRtcCommonMsgPopup != null && mRtcCommonMsgPopup.isShowing() && event.getAction() == KeyEvent.ACTION_DOWN && keyCode == KeyEvent.KEYCODE_BACK) {
//            return !mRtcCommonMsgPopup.getKeyBackCancel();
//        }
        return false;
    }


    private void showPopupWindow(int keyType, String title, String content, boolean hideCancelButton, boolean cancelable, RtcCommonMsgPopup.CommonPopListener listener) {
        //查找当前pop是否存在
        if (popupSparseArray != null && popupSparseArray.size() > 0 && popupSparseArray.indexOfKey(keyType) >= 0) {
            RtcCommonMsgPopup popup = popupSparseArray.get(keyType);
            if (popup.isShowing()) {
                popup.dismiss();
            }
            popup = null;
            popupSparseArray.delete(keyType);
        }
        RtcCommonMsgPopup rtcCommonMsgPopup = new RtcCommonMsgPopup(mContext)
                .setTitle(title)
                .setContent(content)
                .setCancelable(true)
                .setListener(listener);
        if (hideCancelButton) {
            rtcCommonMsgPopup.setHideCancelBtn();
        }

        if (mRootView != null) {
            rtcCommonMsgPopup.show(mRootView);
        }
        popupSparseArray.put(keyType, rtcCommonMsgPopup);
    }


    /**
     * 检查多人连麦摄像头、麦克风、存储相关权限
     *
     * @return 是否具有权限
     */
    public boolean checkMultiVoicePermission(Context context) {
        return PermissionUtils.permitPermission(context, Manifest.permission.CAMERA)
                && PermissionUtils.permitPermission(context, Manifest.permission.RECORD_AUDIO)
                && PermissionUtils.permitPermission(context, Manifest.permission.WRITE_EXTERNAL_STORAGE);
    }

}
