package com.sensetime.demo;

import android.text.TextUtils;

import com.google.gson.Gson;
import com.google.gson.JsonSyntaxException;
import com.orhanobut.logger.Logger;
import com.sensetime.mtc.AiConfig;
import com.sensetime.mtc.MClient;
import com.sensetime.mtc.MtcCode;

import java.io.File;


/**
 * Author:Created by LaoTie on 2019/12/12.
 * Enterprise:SenseTime
 **/
public class SenseTimeMtc {

    public static final int M20 = 20;
    public static final int M10 = 10;
    public static final int UNKNOWN_DEVICE_MODULE = 0;

    public static final int LANDSCAPE_0 = 0x01; // 横屏0度
    public static final int PORTRAIT_90 = 0x02;// 竖屏90度
    public static final int LANDSCAPE_180 = 0x03; // 横屏180度
    public static final int PORTRAIT_270 = 0x04;// 竖屏270度


    public static final int TURN_OFF_AUTO_UPLOAD_AI_INFO = 0x01;// 关闭主动上报的功能
    public static final int TURN_ON_AUTO_UPLOAD_PICTURE_RECO = 0x02;// 打开主动上报的功能，且只上报图片与识别数据
    public static final int TURN_ON_AUTO_UPLOAD_RECO = 0x04;// 打开主动上报的功能，且只上报识别数据

    public static final int TURN_ON_FRAME_CARRIES_AI_INFO = 0x00;// 打开视频帧携带人脸识别数据的功能
    public static final int TURN_OFF_FRAME_CARRIES_AI_INFO = 0x01;// 关闭视频帧携带人脸识别数据的功能

    private final String devNamePrefix = "/dev/ttyACM";
    private int mDeviceModule = UNKNOWN_DEVICE_MODULE;
    private String mDeviceInfo;
    private boolean isInitSuccess = false;
    private int mPreviewWidth = 1280;
    private int mPreviewHeight = 720;
    private boolean mScaleHeight = false;
    private int mM10_L_P = PORTRAIT_90;   //1: 1280x720 ,  2: 720x1280;

    private int autoUploadAiInfoMode = TURN_ON_AUTO_UPLOAD_RECO;
    private int frameCarriesAiInfoMode = TURN_OFF_FRAME_CARRIES_AI_INFO;

    private boolean rgbFaceImg = true;
    private boolean rgbBgImg = true;
    private boolean irImg = true;


    private boolean isPauseAI = false;

    private int mAICameraWidth = 1280; //note 因为给AI的图像都是720*1280的，所以人脸框必须依据这个来绘制，即使是360p的，要不人脸框位置不对
    private int mAICameraHeight = 720; //note 因为给AI的图像都是720*1280的，所以人脸框必须依据这个来绘制，即使是360p的，要不人脸框位置不对

    private boolean isCloseCameraRGB = false; //是否手动关闭RGB摄像头
    private boolean isCloseCameraIR = false; //是否手动关闭了IR摄像头

    /**
     * 模组自带AE RGB摄像头的抗闪是否打开 0x00代表关闭（去使能），0x01代表打开（使能）
     */
    private int deviceAntiFlickerEnabledRGB = 0x00;

    /**
     * 模组自带AE IR摄像头的抗闪是否打开 0x00代表关闭（去使能），0x01代表打开（使能）
     */
    private int deviceAntiFlickerEnabledIR = 0x00;

    /**
     * 模组自带RGB 抗闪频率，0x00代表50HZ，0x01 代表60HZ
     */
    private int deviceAntiFlickerFrequencyRGB = 0x00;

    /**
     * 模组自带IR抗闪频率，0x00代表50HZ，0x01 代表60HZ
     */
    private int deviceAntiFlickerFrequencyIR = 0x01;

    /**
     * 判断是否是IR模式
     */
    private int isIRRGBMode = IR_RGB_NONE;

    public static int IR_RGB_NONE = -1;
    public static int RGB = 0;
    public static int IR = 1;

    private MClient mClient;

    public interface InitCallback {

        void onFinish();
    }

    public static SenseTimeMtc getInstance() {
        return MtcHolder.senseTimeMtcInstance;
    }

    private SenseTimeMtc() {
        mClient = MClient.getInstance();
    }

    private static class MtcHolder {
        private static SenseTimeMtc senseTimeMtcInstance = new SenseTimeMtc();
    }

    public String getDevicePath() {
        int devNameIndex = 3;
        String dev = "";
        for (int i = 0; i <= devNameIndex; i++) {
            dev = devNamePrefix + i;
            File device = new File(dev);
            if (device.exists()) {
                if (!device.canRead() || !device.canWrite() || !device.canExecute()) {
                    Logger.e("can't read/write device: " + dev + ", start get root permission.");
                } else {
                    Logger.v(dev + " is exists");
                    return dev;
                }
            } else {
                Logger.v(dev + " is't exists");
            }
        }
        return "";
    }

    public void initMtc(InitCallback initCallback) {
        isInitSuccess = false;
        mDeviceModule = UNKNOWN_DEVICE_MODULE;
        String dev = getDevicePath();
        Logger.d("init mtc");
        if (!TextUtils.isEmpty(dev)) {
            mClient.mtcInit(dev, (mtcCode, result) -> {
                Logger.d("initMtc dev:" + dev + ",  mtcCode:" + mtcCode);
                if (mtcCode == MtcCode.SUCCESS) {
                    isInitSuccess = true;
                    getMTCInfo(initCallback);
                } else {
                    initCallback.onFinish();
                }
            });
        }else{
            initCallback.onFinish();
        }
    }

    public void getMTCInfo(InitCallback initCallback) {
        Logger.d("get device info.");
        mClient.mtcDeviceModuleGet((mtcCode, result) -> {
            if (mtcCode == MtcCode.SUCCESS && !TextUtils.isEmpty(result)) {
                if (result.contains("M10")) {
                    mDeviceModule = M10;
                    mM10_L_P = LANDSCAPE_0;//M10默认横屏
                    mClient.mtcDeviceScreenModeGet((mtcCode1, result1) -> {
                        Logger.d("mtcCode1:"+mtcCode1);
                        if (mtcCode1 == MtcCode.SUCCESS && !TextUtils.isEmpty(result1)) {
                            int mode = Integer.parseInt(result1);
                            Logger.d("screen mode:"+mode);
                            setmM10_L_P(mode);
                        }

                        initCallback.onFinish();
                    });
                } else if (result.contains("M20")) {
                    mDeviceModule = M20;
                } else {
                    mDeviceModule = UNKNOWN_DEVICE_MODULE;
                    Logger.d("Not find m10 or m20,unknow device.");
                }
                Logger.d("mDeviceModule: " + mDeviceModule);
            } else {
                Logger.e("can't get deviceInfo");
            }
            initCallback.onFinish();
        });


        mClient.mtcAiConfigGet((mtcCode, result) -> {
            if (mtcCode == MtcCode.SUCCESS && !TextUtils.isEmpty(result)) {
                try {
                    Gson gson = new Gson();
                    Logger.d("result:" + result);
                    AiConfig aiConfig = gson.fromJson(result, AiConfig.class);
                    if (aiConfig != null) {
                        AiConfig.setInstance(aiConfig);
                    }
                } catch (JsonSyntaxException e) {
                    e.printStackTrace();
                }
            }
        });

        mClient.mtcAiControlAutoUploadAiInfo(autoUploadAiInfoMode,rgbFaceImg,rgbBgImg,irImg, (mtcCode, result) -> Logger.d("open mtcAiControlAutoUploadAiInfo's mtcCode:" + mtcCode));

        mClient.mtcUploadFrameAiInfo(frameCarriesAiInfoMode, (mtcCode, result) -> Logger.d("mtcUploadFrameAiInfo's  mtcCode:"+mtcCode));
    }


    public boolean isRgbFaceImg() {
        return rgbFaceImg;
    }

    public void setRgbFaceImg(boolean rgbFaceImg) {
        this.rgbFaceImg = rgbFaceImg;
    }

    public boolean isRgbBgImg() {
        return rgbBgImg;
    }

    public void setRgbBgImg(boolean rgbBgImg) {
        this.rgbBgImg = rgbBgImg;
    }

    public boolean isIrImg() {
        return irImg;
    }

    public void setIrImg(boolean irImg) {
        this.irImg = irImg;
    }

    public String getmDeviceInfo() {
        return mDeviceInfo;
    }

    public boolean isInitSuccess() {
        return isInitSuccess;
    }

    public int getmPreviewWidth() {
        return mPreviewWidth;
    }

    public int getmPreviewHeight() {
        return mPreviewHeight;
    }

    public boolean ismScaleHeight() {
        return mScaleHeight;
    }

    public void setmScaleHeight(boolean mScaleHeight) {
        this.mScaleHeight = mScaleHeight;
    }

    public int getmM10_L_P() {
        return mM10_L_P;
    }

    public void setmM10_L_P(int mM10_L_P) {
        this.mM10_L_P = mM10_L_P;
    }

    public void setmPreviewWidth(int mPreviewWidth) {
        this.mPreviewWidth = mPreviewWidth;
    }

    public void setmPreviewHeight(int mPreviewHeight) {
        this.mPreviewHeight = mPreviewHeight;
    }

    public int getmDeviceModule() {
        return mDeviceModule;
    }

    public int getAutoUploadAiInfoMode() {
        return autoUploadAiInfoMode;
    }

    public void setAutoUploadAiInfoMode(int autoUploadAiInfoMode) {
        this.autoUploadAiInfoMode = autoUploadAiInfoMode;
    }

    public int getFrameCarriesAiInfoMode() {
        return frameCarriesAiInfoMode;
    }

    public void setFrameCarriesAiInfoMode(int frameCarriesAiInfoMode) {
        this.frameCarriesAiInfoMode = frameCarriesAiInfoMode;
    }

    public boolean isPauseAI() {
        return isPauseAI;
    }

    public void setPauseAI(boolean pauseAI) {
        isPauseAI = pauseAI;
    }


    public int getIsIRRGBMode() {
        return isIRRGBMode;
    }

    public void setIsIRRGBMode(int isIRRGBMode) {
        this.isIRRGBMode = isIRRGBMode;
    }

    public int getmAICameraWidth() {
        return mAICameraWidth;
    }

    public void setmAICameraWidth(int mAICameraWidth) {
        this.mAICameraWidth = mAICameraWidth;
    }

    public int getmAICameraHeight() {
        return mAICameraHeight;
    }

    public void setmAICameraHeight(int mAICameraHeight) {
        this.mAICameraHeight = mAICameraHeight;
    }


    public int getDeviceAntiFlickerEnabledRGB() {
        return deviceAntiFlickerEnabledRGB;
    }

    public void setDeviceAntiFlickerEnabledRGB(int deviceAntiFlickerEnabledRGB) {
        this.deviceAntiFlickerEnabledRGB = deviceAntiFlickerEnabledRGB;
    }

    public int getDeviceAntiFlickerEnabledIR() {
        return deviceAntiFlickerEnabledIR;
    }

    public void setDeviceAntiFlickerEnabledIR(int deviceAntiFlickerEnabledIR) {
        this.deviceAntiFlickerEnabledIR = deviceAntiFlickerEnabledIR;
    }

    public int getDeviceAntiFlickerFrequencyRGB() {
        return deviceAntiFlickerFrequencyRGB;
    }

    public void setDeviceAntiFlickerFrequencyRGB(int deviceAntiFlickerFrequencyRGB) {
        this.deviceAntiFlickerFrequencyRGB = deviceAntiFlickerFrequencyRGB;
    }

    public int getDeviceAntiFlickerFrequencyIR() {
        return deviceAntiFlickerFrequencyIR;
    }

    public void setDeviceAntiFlickerFrequencyIR(int deviceAntiFlickerFrequencyIR) {
        this.deviceAntiFlickerFrequencyIR = deviceAntiFlickerFrequencyIR;
    }


    public boolean isCloseCameraRGB() {
        return isCloseCameraRGB;
    }

    public void setCloseCameraRGB(boolean closeCameraRGB) {
        isCloseCameraRGB = closeCameraRGB;
    }

    public boolean isCloseCameraIR() {
        return isCloseCameraIR;
    }

    public void setCloseCameraIR(boolean closeCameraIR) {
        isCloseCameraIR = closeCameraIR;
    }
}
