/**
 * 预览页面
 */
package com.videogo.ui.realplay;

import static com.videogo.EzvizApplication.getOpenSDK;

import android.annotation.SuppressLint;
import android.content.Context;
import android.content.Intent;
import android.content.res.Configuration;
import android.graphics.Rect;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;

import android.util.DisplayMetrics;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.view.WindowManager;
import android.view.inputmethod.InputMethodManager;
import android.widget.HorizontalScrollView;
import android.widget.ImageButton;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.RelativeLayout.LayoutParams;

import com.videogo.EzvizApplication;

import ezviz.ezopensdkcommon.common.RootActivity;

import com.videogo.constant.Constant;
import com.videogo.constant.IntentConsts;
import com.videogo.errorlayer.ErrorInfo;
import com.videogo.exception.ErrorCode;
import com.videogo.global.ValueKeys;
import com.videogo.openapi.EZConstants;
import com.videogo.openapi.EZConstants.EZRealPlayConstants;
import com.videogo.openapi.EZPlayer;
import com.videogo.openapi.EzvizAPI;
import com.videogo.openapi.bean.EZCameraInfo;
import com.videogo.openapi.bean.EZDeviceInfo;
import com.videogo.openapi.bean.EZPMPlayPrivateTokenInfo;
import com.videogo.realplay.RealPlayStatus;
import com.videogo.ui.common.EZStreamConfigLoader;
import com.videogo.ui.devicelist.EZDeviceListActivity;
import com.videogo.ui.common.EZBusinessTool;
import com.videogo.ui.common.ScreenOrientationHelper;
import com.videogo.ui.realplay.fec.FecHelper;
import com.videogo.ui.realplay.helper.CaptureRecordHelper;
import com.videogo.ui.realplay.helper.GestureZoomHelper;
import com.videogo.ui.realplay.helper.OrientationHelper;
import com.videogo.ui.realplay.helper.PtzHelper;
import com.videogo.ui.realplay.helper.VideoQualityHelper;
import com.videogo.ui.realplay.helper.VoiceTalkHelper;
import com.videogo.ui.realplay.helper.LoadingStateHelper;
import com.videogo.ui.realplay.helper.StreamInfoHelper;
import com.videogo.ui.realplay.helper.SurfaceHelper;
import com.videogo.ui.realplay.helper.TitleBarHelper;
import com.videogo.ui.realplay.helper.UpdateTimerHelper;
import com.videogo.ui.realplay.helper.ScreenEventHelper;
import com.videogo.ui.realplay.helper.WatermarkHelper;
import com.videogo.util.DataManager;
import ezviz.ezopensdkcommon.common.EZPermissionUtil;
import com.videogo.util.SpTool;
import com.videogo.util.VerifyCodeInput;
import com.videogo.util.ConnectionDetector;
import com.videogo.util.LocalInfo;
import com.videogo.util.LogUtil;
import com.videogo.util.Utils;
import com.videogo.widget.CheckTextButton;
import com.videogo.widget.TitleBar;

import ezviz.ezopensdk.R;

@SuppressLint({"NonConstantResourceId"})
public class EZRealPlayActivity extends RootActivity implements
        Handler.Callback, VerifyCodeInput.VerifyCodeInputListener {

    // region --- 全局变量|global variable ---

    private static final String TAG = EZRealPlayActivity.class.getSimpleName();

    public LocalInfo mLocalInfo = null;
    public float mRealRatio = Constant.LIVE_VIEW_RATIO;
    public int mOrientation = Configuration.ORIENTATION_PORTRAIT;
    public Rect mRealPlayRect = null;// 状态栏Rect

    public TitleBar mPortraitTitleBar;// 竖屏导航栏
    public TitleBar mLandscapeTitleBar;// 横屏导航栏
    public LinearLayout mRealPlayPage;// 预览页面
    public RelativeLayout mRealPlayPlayRl;// 预览UI父视图
    public ViewGroup mPlayWindowVg;// 播放窗口容器

    public LinearLayout mRealPlayControlRl;// 播放器下方的工具条
    private ImageButton mRealPlayBtn;// 播放/暂停
    private ImageButton mRealPlaySoundBtn;// 声音开关
    private CheckTextButton mFullscreenButton;// 放大
    public HorizontalScrollView mRealPlayOperateBar;// 操控栏

    private LoadingStateHelper mLoadingStateHelper;// 加载状态管理Helper
    public StreamInfoHelper mStreamInfoHelper;// 码流信息展示Helper
    public SurfaceHelper mSurfaceHelper;// Surface生命周期管理Helper
    public PtzHelper mPtzHelper;// 云台功能Helper
    public VoiceTalkHelper mVoiceTalkHelper;// 对讲功能Helper
    public CaptureRecordHelper mCaptureRecordHelper;// 截图/录像功能Helper
    public VideoQualityHelper mVideoQualityHelper;// 清晰度设置功能Helper
    public WatermarkHelper mWatermarkHelper;// 水印功能Helper
    private GestureZoomHelper mGestureZoomHelper;// 手势/缩放功能Helper
    public TitleBarHelper mTitleBarHelper;// 导航栏功能Helper
    private FecHelper mFecHelper;// 鱼眼矫正功能Helper
    private ScreenEventHelper mScreenEventHelper;// 屏幕事件Helper
    private UpdateTimerHelper mUpdateTimerHelper;// 定时器管理Helper
    public OrientationHelper mOrientationHelper;// 屏幕旋转/全屏功能Helper

    public EZPlayer mEZPlayer = null;
    public Handler mHandler = null;
    public int mStatus = RealPlayStatus.STATUS_INIT;
    public boolean mIsOnStop = false;// 是否停止录制中
    private long mStartTime = 0;// 取流开始时间

    public boolean isMultiChannelDevice;// 是否是双目设备，如果接入的设备没有双目设备，可以忽略相关逻辑
    private boolean isQulityModeAuto = false;// 当前设备本地清晰度 是否是"自动"

    // 视频宽高
    public int mVideoWidth;
    public int mVideoHeight;

    public int mControlDisplaySec = 0;// 计时，5秒后关闭某些弹出框

    // 以下为设备列表页面通过Bundle传递的数据
    public EZDeviceInfo mDeviceInfo = null;
    public EZCameraInfo mCameraInfo = null;
    public String mRtspUrl = null;// 通过rtsp协议url进行预览
    // 以上为设备列表页面通过Bundle传递的数据

    // endregion

    // region --- 页面启动方法|Page startup method ---

    public static void launch(Context context, EZDeviceInfo deviceInfo, EZCameraInfo cameraInfo) {
        Intent intent = new Intent(context, EZRealPlayActivity.class);
        intent.putExtra(IntentConsts.EXTRA_CAMERA_INFO, cameraInfo);
        intent.putExtra(IntentConsts.EXTRA_DEVICE_INFO, deviceInfo);
        context.startActivity(intent);
    }

    public static void launch(Context context, String deviceSerial, int cameraNo) {
        EZCameraInfo cameraInfo = new EZCameraInfo();
        cameraInfo.setDeviceSerial(deviceSerial);
        cameraInfo.setCameraNo(cameraNo);
        launch(context, new EZDeviceInfo(), cameraInfo);
    }

    // endregion

    // region --- 生命周期|Life Cycle ---

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.ez_realplay_page);
        // 保持屏幕常亮 Keep the screen on
        getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
        initData();// 数据初始化
        initView();// 视图初始化设置
        initEZPlayer();// 播放器初始化
        initHelpers();// Helper 初始化
    }

    @Override
    protected void onResume() {
        super.onResume();
        EZPermissionUtil.onResume(this);
        if (mOrientation == Configuration.ORIENTATION_LANDSCAPE) {
            return;
        }
        // 关闭软键盘
        new Handler().postDelayed(() -> {
            if (mSurfaceHelper.mRealPlaySv != null) {
                InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
                imm.hideSoftInputFromWindow(mSurfaceHelper.mRealPlaySv.getWindowToken(), 0);
            }
        }, 200);

        LogUtil.i(TAG, "onResume real play status:" + mStatus);
        if (mStatus == RealPlayStatus.STATUS_PAUSE || mStatus == RealPlayStatus.STATUS_DECRYPT) {
            playerStartRealPlay();// 开始播放
        }
        mIsOnStop = false;
    }

    @Override
    protected void onStop() {
        super.onStop();
        mOrientationHelper.postOnStop();
        if (mCameraInfo == null && mRtspUrl == null) {
            return;
        }
        mPtzHelper.closePtzPopupWindow();
        mVoiceTalkHelper.closeTalkPopupWindow(true);
        if (mStatus != RealPlayStatus.STATUS_STOP) {
            setRealPlayResult(false);
            mIsOnStop = true;
            mStatus = RealPlayStatus.STATUS_PAUSE;
        } else {
            mLoadingStateHelper.setStopLoading();
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (mEZPlayer != null) {
            getOpenSDK().releasePlayer(mEZPlayer);
        }
        mHandler = null;

        mScreenEventHelper.unregisterScreenReceiver();
        mOrientationHelper.release();
    }

    @Override
    public void finish() {
        if (mCameraInfo != null) {
            // 更新设备列表 该设备的清晰度
            Intent intent = new Intent();
            intent.putExtra(IntentConsts.EXTRA_DEVICE_ID, mCameraInfo.getDeviceSerial());
            intent.putExtra(IntentConsts.EXTRA_CAMERA_NO, mCameraInfo.getCameraNo());
            intent.putExtra("video_level", mCameraInfo.getVideoLevel().getVideoLevel());
            setResult(EZDeviceListActivity.RESULT_CODE, intent);
        }
        super.finish();
    }

    @Override
    public void onBackPressed() {
        if (mOrientationHelper.handleBackPressed()) return;
        exit();
    }

    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        mOrientation = newConfig.orientation;
        mOrientationHelper.onOrientationChanged();
        super.onConfigurationChanged(newConfig);
    }

    // endregion

    // region --- 播放器消息回调|Player message callback ---

    @Override
    public boolean handleMessage(Message msg) {
        if (this.isFinishing()) {
            return false;
        }
        LogUtil.i(TAG, "handleMessage:" + msg.what);
        switch (msg.what) {
            // 以下消息为SDK发送的消息，用于取流相关消息回调
            case EZRealPlayConstants.MSG_REALPLAY_PLAY_SUCCESS:// 播放成功
                handlePlaySucceed();
                break;
            case EZRealPlayConstants.MSG_REALPLAY_PLAY_FAIL:// 播放失败
                handlePlayFailed((ErrorInfo) msg.obj);
                break;
            case EZRealPlayConstants.MSG_PTZ_GET_SUCCESS:// 设备云台角度数据回调
                mPtzHelper.handleDevicePtzAngleInfo(msg.obj);
                break;
            case EZRealPlayConstants.MSG_PRIVATE_TOKEN_GET_SUCCESS:// 智能门锁开门token回调
                // 如果门锁设备没有回调开门token的话，请确认该设备的远程开锁开关是否打开。萤石云视频App入口：设备设置-开锁设置-远程开锁-开启远程开锁
                EZPMPlayPrivateTokenInfo tokenInfo = (EZPMPlayPrivateTokenInfo)msg.obj;
                LogUtil.e(TAG, "token--->" + tokenInfo.getToken());
                break;
            case EZRealPlayConstants.MSG_REALPLAY_VOICETALK_SUCCESS:// 对讲成功
                mVoiceTalkHelper.handleVoiceTalkSucceed();
                break;
            case EZRealPlayConstants.MSG_REALPLAY_VOICETALK_STOP:// 对讲结束
                mVoiceTalkHelper.handleVoiceTalkStoped();
                break;
            case EZRealPlayConstants.MSG_REALPLAY_VOICETALK_FAIL:// 对讲失败
                mVoiceTalkHelper.handleVoiceTalkFailed((ErrorInfo) msg.obj);
                break;
            case EZConstants.MSG_VIDEO_SIZE_CHANGED:// 播放器尺寸变化
                try {
                    String temp = (String) msg.obj;
                    String[] strings = temp.split(":");
                    mVideoWidth = Integer.parseInt(strings[0]);
                    mVideoHeight = Integer.parseInt(strings[1]);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                break;
            case EZRealPlayConstants.MSG_VIDEO_LEVEL_AUTO_IMPROVE:// 清晰度升档，EZPlayer.enableDeviceAutoVideolevel开关打开后才会有此回调
                mVideoQualityHelper.tryAutoAdjustLevel(true, mCaptureRecordHelper.isRecording());
                break;
            case EZRealPlayConstants.MSG_VIDEO_LEVEL_AUTO_REDUCE:// 清晰度降档，EZPlayer.enableDeviceAutoVideolevel开关打开后才会有此回调
                mVideoQualityHelper.tryAutoAdjustLevel(false, mCaptureRecordHelper.isRecording());
                break;
            // 以上消息为SDK发送的消息，用于取流相关消息回调
            default:
                // do nothing
                break;
        }
        return false;
    }

    /**
     * 播放失败后处理
     *
     * @param errorInfo 错误信息
     */
    private void handlePlayFailed(ErrorInfo errorInfo) {
        LogUtil.d(TAG, "handlePlayFail. realPlay failed. error info is " + errorInfo.toString());
        mStatus = RealPlayStatus.STATUS_STOP;
        setRealPlayResult(false);
        // 获取设备详情 & 刷新视图
        getDeviceDetailInfoAndRefreshUI();
        switch (errorInfo.errorCode) {
            // 收到这两个错误码，可以弹出对话框，让用户输入密码后，重新取流预览
            case ErrorCode.ERROR_INNER_VERIFYCODE_NEED:
            case ErrorCode.ERROR_INNER_VERIFYCODE_ERROR: {
                VerifyCodeInput.VerifyCodeInputDialog(this, this).show();
            }
            break;
            default:// 显示错误码信息
                String errorInfoText = Utils.getErrorTip(this, R.string.realplay_play_fail, errorInfo.errorCode);
                mLoadingStateHelper.setLoadingFail(errorInfoText);
                showToast(errorInfo.toString());
                break;
        }
    }

    /**
     * 播放成功后处理
     */
    private void handlePlaySucceed() {
        LogUtil.d(TAG, "handlePlaySucceed");
        mStatus = RealPlayStatus.STATUS_PLAY;
        // 1.视图状态设置
        setRealPlayResult(true);
        mLoadingStateHelper.setLoadingSuccess();
        // 2.设置取流方式 & 更多 UI
        mStreamInfoHelper.onPlaySucceed();
        // 3.获取设备详情更新清晰度
        mVideoQualityHelper.setDeviceDetailPublicInfo(this.mEZPlayer.getDeviceDetailInfo());
        mCameraInfo.setVideoLevel(mVideoQualityHelper.getDeviceDetailPublicInfo().videoLevel);
        mVideoQualityHelper.setCurrentQulityMode(mCameraInfo.getVideoLevel());
        mVideoQualityHelper.setVideoLevelUI();
        // 4.声音设置  Sound setting
        setRealPlaySound();
        // 5.开启计时，每秒刷新UI
        mUpdateTimerHelper.startUpdateTimer();
        mOrientationHelper.updateOrientation();
        mFecHelper.onPlaySucceed();
    }

    // endregion

    // region --- Click点击事件|Click event ---

    /**
     * 暂停/播放Action
     */
    private void onRealPlayClick() {
        if (mStatus != RealPlayStatus.STATUS_STOP) {
            // 暂停前获取最后一帧作为封面
            mSurfaceHelper.captureCoverImage();
            mLoadingStateHelper.setStopLoading();
            setRealPlayResult(false);
        } else {
            playerStartRealPlay();
        }
    }

    /**
     * 声音开关Action
     */
    private void onSoundBtnClick() {
        if (mLocalInfo.isSoundOpen()) {
            mLocalInfo.setSoundOpen(false);
            mRealPlaySoundBtn.setImageResource(R.drawable.ez_sound_off_selector);
        } else {
            mLocalInfo.setSoundOpen(true);
            mRealPlaySoundBtn.setImageResource(R.drawable.ez_sound_on_selector);
        }
        setRealPlaySound();
    }

    // endregion

    // region --- 验证码校验|CAPTCHA Verification ---

    @Override
    public void onInputVerifyCode(final String verifyCode) {
        LogUtil.d(TAG, "verify code is " + verifyCode);
        DataManager.getInstance().setDeviceSerialVerifyCode(mCameraInfo.getDeviceSerial(), verifyCode);
        if (mEZPlayer != null) {
            mEZPlayer.setPlayVerifyCode(verifyCode);
            playerStartRealPlay();
        }
    }

    // endregion

    // region --- 自定义方法|custom method ---

    private void initEZPlayer() {
        if (mCameraInfo != null) {
            // 1.创建播放器（Android 预览、对讲共用一个EZPlayer）
            mEZPlayer = EzvizApplication.getOpenSDK().createPlayer(mCameraInfo.getDeviceSerial(), mCameraInfo.getCameraNo());
            // 2.配置播放器：设置回调，设置验证码，设置播放视图等配置
            mEZPlayer.setHandler(mHandler);
            // 判断设备是否加密，加密就从demo的归档文件中获取设备验证码填入到播放器的验证码接口里
            if (mDeviceInfo.getIsEncrypt() == 1) {
                mEZPlayer.setPlayVerifyCode(DataManager.getInstance().getDeviceSerialVerifyCode(mCameraInfo.getDeviceSerial()));
            }
            mEZPlayer.setSurfaceHold(mSurfaceHelper.getSurfaceHolder());// 设置SurfaceHold
            if (isMultiChannelDevice) {// 双目设备设置第二个SurfaceHold
                mEZPlayer.setSurfaceHold(mSurfaceHelper.getSecondSurfaceHolder(), 1);
            }
            if (isQulityModeAuto) {
                mEZPlayer.enableDeviceAutoVideoLevel();
            }
            // 设置解码方式
            mEZPlayer.setHardDecode(SpTool.obtainBooleanValue(ValueKeys.VideoPlayHardDecodingStatus + "_" + mCameraInfo.getDeviceSerial()));
        } else if (mRtspUrl != null) {
            mEZPlayer = EzvizApplication.getOpenSDK().createPlayerWithUrl(mRtspUrl);
            mEZPlayer.setHandler(mHandler);
            mEZPlayer.setSurfaceHold(mSurfaceHelper.getSurfaceHolder());
        }
    }

    /**
     * 初始化各功能 Helper
     */
    private void initHelpers() {
        mFecHelper = FecHelper.createFromRealPlayActivity(this);// 创建鱼眼设备 Helper
        mStreamInfoHelper = new StreamInfoHelper(this);// 码流信息展示 Helper 初始化
        mPtzHelper = new PtzHelper(this);// 云台功能 Helper 初始化
        mVoiceTalkHelper = new VoiceTalkHelper(this);// 对讲功能 Helper 初始化
        mCaptureRecordHelper = new CaptureRecordHelper(this);// 截图/录像功能 Helper 初始化
        mVideoQualityHelper = new VideoQualityHelper(this);// 清晰度设置功能 Helper 初始化
        if (mCameraInfo != null) {
            mVideoQualityHelper.setCurrentQulityMode(mCameraInfo.getVideoLevel());
        }
        mWatermarkHelper = new WatermarkHelper(this);// 水印功能 Helper 初始化
        mUpdateTimerHelper = new UpdateTimerHelper(this);// 定时器管理 Helper 初始化
        mScreenEventHelper = new ScreenEventHelper(this);// 注册息屏广播
        mScreenEventHelper.registerScreenReceiver();
    }

    /**
     * 开始播放
     */
    public void playerStartRealPlay() {
        mVoiceTalkHelper.resetStartingTalk();
        LogUtil.d(TAG, "startRealPlay");
        if (mStatus == RealPlayStatus.STATUS_START || mStatus == RealPlayStatus.STATUS_PLAY) {
            return;
        }
        // 检查网络是否可用 | Check if the network is available
        if (!ConnectionDetector.isNetworkAvailable(this)) {
            // 提示没有连接网络 | Prompt not to connect to the network
            setRealPlayResult(false);
            mLoadingStateHelper.setNetworkUnavailableTip(getString(R.string.realplay_play_fail_becauseof_network));
            return;
        }

        mStatus = RealPlayStatus.STATUS_START;
        setRealPlayLoadingUI();
        mLoadingStateHelper.updateLoadingProgress(0);
        mSurfaceHelper.mRealPlaySv.setVisibility(View.VISIBLE);

        // 加载预览特殊配置，一般开发者可不用配置，按需设置
        EZStreamConfigLoader.loadRealPlaySpecialConfigToPlayer(mEZPlayer);

        mEZPlayer.startRealPlay();
    }

    /**
     * 停止播放
     */
    public void playerStopRealPlay() {
        LogUtil.d(TAG, "stopRealPlay");
        mStatus = RealPlayStatus.STATUS_STOP;

        mUpdateTimerHelper.stopUpdateTimer();
        if (mEZPlayer != null) {
            mCaptureRecordHelper.stopRealPlayRecord();
            mEZPlayer.stopRealPlay();
        }
        mStreamInfoHelper.resetStreamFlow();
    }

    /**
     * 退出当前页面
     */
    private void exit() {
        mPtzHelper.closePtzPopupWindow();
        mVoiceTalkHelper.closeTalkPopupWindow(true);
        if (mStatus != RealPlayStatus.STATUS_STOP) {
            playerStopRealPlay();
            setRealPlayResult(false);
        }
        mScreenEventHelper.unregisterScreenReceiver();
        finish();
    }

    private void initData() {
        // 初始化mLocalInfo，记录屏幕尺寸信息
        mLocalInfo = LocalInfo.getInstance();
        DisplayMetrics metric = new DisplayMetrics();
        getWindowManager().getDefaultDisplay().getMetrics(metric);
        mLocalInfo.setScreenWidthHeight(metric.widthPixels, metric.heightPixels);
        mLocalInfo.setNavigationBarHeight((int) Math.ceil(25 * getResources().getDisplayMetrics().density));
        // handler消息处理初始化 & 工具类初始化
        mHandler = new Handler(this);
        // 传递参数获取
        Intent intent = getIntent();
        if (intent != null) {
            mCameraInfo = intent.getParcelableExtra(IntentConsts.EXTRA_CAMERA_INFO);
            mDeviceInfo = intent.getParcelableExtra(IntentConsts.EXTRA_DEVICE_INFO);
            boolean isSupportDeviceAutoVideolevel = EZBusinessTool.isSupportDeviceAutoVideolevel(mDeviceInfo, mCameraInfo);
            isQulityModeAuto = isSupportDeviceAutoVideolevel &&
                    SpTool.obtainBooleanValue(ValueKeys.QUALITY_AUTO + "_" + mCameraInfo.getDeviceSerial());
            isMultiChannelDevice = EZBusinessTool.isSupportMultiChannel(mDeviceInfo, mCameraInfo);
            if (isMultiChannelDevice) {// 双目设备调整画面比例
                mRealRatio = Constant.LIVE_MULTI_VIEW_RATIO;
            }
            mRtspUrl = intent.getStringExtra(IntentConsts.EXTRA_RTSP_URL);
            LogUtil.d(TAG, "rtspUrl:" + mRtspUrl);
        }
    }

    // endregion

    // region --- UI ---

    private void initView() {
        mTitleBarHelper = new TitleBarHelper(this);
        // Surface 生命周期管理 Helper 初始化
        mSurfaceHelper = new SurfaceHelper(this);
        // 手势/缩放功能 Helper 初始化（必须在 initRealPlayPageLy 之前，因为后者会触发 setRealPlaySvLayout）
        mGestureZoomHelper = new GestureZoomHelper(this);
        // 绑定手势监听器到 SurfaceView（必须在 GestureZoomHelper 初始化后）
        mSurfaceHelper.bindTouchListeners();
        mRealPlayPage = (LinearLayout) findViewById(R.id.realplay_page);
        /** 测量状态栏高度 Measure the status bar height**/
        ViewTreeObserver viewTreeObserver = mRealPlayPage.getViewTreeObserver();
        viewTreeObserver.addOnGlobalLayoutListener(() -> {
            if (mRealPlayRect == null) {
                // 获取状况栏高度
                mRealPlayRect = new Rect();
                getWindow().getDecorView().getWindowVisibleDisplayFrame(mRealPlayRect);
            }
        });
        mFullscreenButton = (CheckTextButton) findViewById(R.id.fullscreen_button);
        mLoadingStateHelper = new LoadingStateHelper(this);
        mOrientationHelper = new OrientationHelper(this);
        mOrientationHelper.initScreenOrientationHelper(
                new ScreenOrientationHelper(this, mFullscreenButton, mTitleBarHelper.mFullScreenTitleBarBackBtn));

        mRealPlayPlayRl = (RelativeLayout) findViewById(R.id.realplay_play_rl);
        mPlayWindowVg = (ViewGroup) findViewById(R.id.vg_play_window);
        mRealPlayControlRl = (LinearLayout) findViewById(R.id.realplay_control_rl);
        mRealPlayBtn = (ImageButton) findViewById(R.id.realplay_play_btn);
        mRealPlaySoundBtn = (ImageButton) findViewById(R.id.realplay_sound_btn);
        mRealPlayBtn.setOnClickListener(v -> onRealPlayClick());
        mRealPlaySoundBtn.setOnClickListener(v -> onSoundBtnClick());

        if (mRtspUrl == null) {
            mRealPlayOperateBar = (HorizontalScrollView) findViewById(R.id.ezopen_realplay_operate_bar);
            if (EzvizAPI.getInstance().isUsingGlobalSDK()) {// 海外不支持云录制截图上传
                findViewById(R.id.realplay_snapshot_upload_btn_ly).setVisibility(View.GONE);
            }
        } else {
            LinearLayout.LayoutParams realPlayPlayRlLp = new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
            realPlayPlayRlLp.gravity = Gravity.CENTER;
            mRealPlayPlayRl.setLayoutParams(realPlayPlayRlLp);
            mRealPlayPlayRl.setBackgroundColor(getResources().getColor(R.color.common_bg));
        }
        mOrientationHelper.setRealPlaySvLayout();
    }

    /**
     * 声音开关 - Player声音设置
     */
    private void setRealPlaySound() {
        if (mEZPlayer == null || mRtspUrl != null) {
            return;
        }
        if (mLocalInfo.isSoundOpen()) {
            mRealPlaySoundBtn.setImageResource(R.drawable.ez_sound_on_selector);
            mEZPlayer.openSound();
        } else {
            mRealPlaySoundBtn.setImageResource(R.drawable.ez_sound_off_selector);
            mEZPlayer.closeSound();
        }
    }

    /**
     * 重置相关UI
     */
    private void setRealPlayLoadingUI() {
        mStartTime = System.currentTimeMillis();
        mLoadingStateHelper.setStartLoading();
        mRealPlayBtn.setImageResource(R.drawable.ez_pause_selector);
        if (mCameraInfo != null && mDeviceInfo != null) {
            mVideoQualityHelper.setQualityBtnEnabled(mDeviceInfo.getStatus() == 1);
            mPtzHelper.setPtzBtnEnabled(false);
            mWatermarkHelper.setWatermarkBtnEnabled(false);
            mCaptureRecordHelper.setButtonsEnabled(false, false, false);
        }
        mTitleBarHelper.showControlRlAndFullOperateBar();
    }

    /**
     * 播放器播放 成功 / 失败
     * @param isSuccess 播放器播放是否成功
     */
    public void setRealPlayResult(boolean isSuccess) {
        // 1.统计播放耗时
        if (isSuccess && mStartTime > 0) {
            long mStopTime = System.currentTimeMillis();
            showToast("cost: " + (mStopTime - mStartTime) + " ms");
            mStartTime = 0;
        }
        // 2.底部6个功能按钮设置
        mPtzHelper.setPtzBtnEnabled(isSuccess);
        // 未在预览时也能发起对讲
        mVoiceTalkHelper.setTalkBtnEnabled(
                EZBusinessTool.isSupportTalk(mDeviceInfo, mCameraInfo) != EZConstants.EZTalkbackCapability.EZTalkbackNoSupport);
        mWatermarkHelper.setWatermarkBtnEnabled(isSuccess && !isMultiChannelDevice);
        mCaptureRecordHelper.setButtonsEnabled(isSuccess, isSuccess, isSuccess);
        // 3.封面设置
        mSurfaceHelper.setCoverVisibility(isSuccess);
        // 4.设置水印
        mWatermarkHelper.restoreWatermarkIfNeeded(mEZPlayer);
        // 5.播放器左下角播放按钮设置
        mRealPlayBtn.setImageResource(isSuccess ? R.drawable.ez_pause_selector : R.drawable.ez_play_selector);
        if (!isSuccess) {
            playerStopRealPlay();
        }
        mFecHelper.onPlayStopped();
        mTitleBarHelper.hideLandscapeTitleBar(true);
    }

    /**
     * 获取设备详情信息 & 更新UI
     */
    public void getDeviceDetailInfoAndRefreshUI() {
        mVideoQualityHelper.setDeviceDetailPublicInfo(this.mEZPlayer.getDeviceDetailInfo());
        if (mVideoQualityHelper.getDeviceDetailPublicInfo() != null) {
            mCameraInfo.setVideoLevel(mVideoQualityHelper.getDeviceDetailPublicInfo().videoLevel);
        }
        mVideoQualityHelper.setCurrentQulityMode(mCameraInfo.getVideoLevel());
        mVideoQualityHelper.setVideoLevelUI();
        if (mStreamInfoHelper.isMoreInfoVisible()) {
            mStreamInfoHelper.showStreamInfoMore();
        }
    }

    /**
     * 供 Helper 调用的 copyDialog 包装
     */
    public void showCopyDialog(String title, String content) {
        copyDialog(title, content);
    }

    /**
     * 供 Helper 调用的 dismissPopWindow 包装（父类 protected 方法对外暴露）
     */
    public void dismissPopWindowPublic(android.widget.PopupWindow popupWindow) {
        dismissPopWindow(popupWindow);
    }

    // endregion

    // region --- 动态权限申请|Dynamic permission application ---

    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        EZPermissionUtil.handleResult(requestCode, permissions, grantResults);
    }

    // endregion
}
