using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using SmartBowSDK;
using InfraredManager;
using ZIM;

public class InfraredDemo : MonoBehaviour
{
    void Start()
    {
        InitBluetoothModule();
        InitInfraredCamera();
    }

    void Update()
    {
        UpdateBluetoothModule();
        UpdateInfraredCamera();
    }

    #region 红外摄像
    [SerializeField] RawImage _cameraRender;
    [SerializeField] RawImage _imageScreenLocateManual;
    [SerializeField] List<RectTransform> _crosshairsInCamera;

    [SerializeField] Slider _sliderBrightness;
    [SerializeField] Slider _sliderSaturation;
    [SerializeField] Slider _sliderContrast;
    [SerializeField] Slider _sliderShakeFilter;

    [SerializeField] Button _btnReset;
    [SerializeField] Button _btnScreenLocateManual;

    [SerializeField] Dropdown _dropdownResolution;

    [SerializeField] Text _fpsText;
    int frames;
    float lastCheckTime;

    List<Vector2> _screenLocatePoints = new();

    public ParamFloatValue brightness = new ParamFloatValue("ic_brightness", 1.0f);
    public ParamFloatValue saturation = new ParamFloatValue("ic_saturation", 1.0f);
    public ParamFloatValue contrast = new ParamFloatValue("ic_contrast", 1.0f);
    public ParamFloatValue shakeFilterValue = new ParamFloatValue("ic_shakeFilterValue2", 6.0f);
    public ParamFloatValue resoution = new ParamFloatValue("ic_resoution2", 2);

    void InitInfraredCamera()
    {
        //SDK创建
        InfraredCameraHelper.GetInstance().Create();
        InfraredCameraHelper.GetInstance().OnPositionUpdate += (Vector2 point) =>
        {
            Ray ray = Camera.main.ScreenPointToRay(point);
            Vector3 rayEndPoint = ray.GetPoint(200);
            Bow.Instance.transform.LookAt(rayEndPoint);
        };
        //参数面板
        SetBrightness(brightness.Get());
        SetSaturation(saturation.Get());
        SetContrast(contrast.Get());
        SetShakeFilterValue(shakeFilterValue.Get());
        _sliderBrightness.onValueChanged.AddListener(SetBrightness);
        _sliderSaturation.onValueChanged.AddListener(SetSaturation);
        _sliderContrast.onValueChanged.AddListener(SetContrast);
        _sliderShakeFilter.onValueChanged.AddListener(SetShakeFilterValue);
        //功能按钮
        _btnReset.onClick.AddListener(OnClick_Reset);
        _btnScreenLocateManual.onClick.AddListener(OnClick_ScreenLocateManual);
        //分辨率
        SetResolution((int)resoution.Get());
        _dropdownResolution.onValueChanged.AddListener(v =>
        {
            SetResolution(v);
            StartCoroutine(RestartOrKillApp());
        });
    }
    IEnumerator RestartOrKillApp()
    {
        yield return new WaitForSeconds(0.3f);
        if (Application.isEditor) yield break;
        if (Application.platform == RuntimePlatform.Android)
        {
            using (var unityPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer"))
            {
                const int kIntent_FLAG_ACTIVITY_CLEAR_TASK = 0x00008000;
                const int kIntent_FLAG_ACTIVITY_NEW_TASK = 0x10000000;
                var currentActivity = unityPlayer.GetStatic<AndroidJavaObject>("currentActivity");
                var pm = currentActivity.Call<AndroidJavaObject>("getPackageManager");
                var intent = pm.Call<AndroidJavaObject>("getLaunchIntentForPackage", Application.identifier);
                intent.Call<AndroidJavaObject>("setFlags", kIntent_FLAG_ACTIVITY_NEW_TASK | kIntent_FLAG_ACTIVITY_CLEAR_TASK);
                currentActivity.Call("startActivity", intent);
                currentActivity.Call("finish");
                var process = new AndroidJavaClass("android.os.Process");
                int pid = process.CallStatic<int>("myPid");
                process.CallStatic("killProcess", pid);
            }
        }
        else Application.Quit();
    }
    void SetBrightness(float v)
    {
        brightness.Set(v);
        _sliderBrightness.SetValueWithoutNotify(brightness.Get());
        _sliderBrightness.transform.Find("Value").GetComponent<Text>().text = brightness.Get().ToString("f1");
        InfraredCameraHelper.GetInstance().SetBrightness(brightness.Get());
    }
    void UpdateInfraredCamera()
    {
        //渲染相机画面
        _cameraRender.texture = InfraredCameraHelper.GetInstance().GetCameraTexture();
        _cameraRender.material = InfraredCameraHelper.GetInstance().GetCameraMaterial();
        //手动定位
        if (InfraredCameraHelper.GetInstance().IsScreenLocateManualDoing())
        {
            //引导提示
            string tipText = "单击屏幕 左下角";
            if (_screenLocatePoints.Count == 1) tipText = "单击屏幕 右下角";
            if (_screenLocatePoints.Count == 2) tipText = "单击屏幕 右上角";
            if (_screenLocatePoints.Count == 3) tipText = "单击屏幕 左上角";
            _imageScreenLocateManual.transform.Find("Text").GetComponent<Text>().text = tipText;
            //点击检测
            if (Input.GetMouseButtonDown(0))
            {
                Vector2 mouse = Input.mousePosition;
                float u = Mathf.Clamp01(mouse.x / Screen.width);
                float v = Mathf.Clamp01(mouse.y / Screen.height);
                float texWidth = _imageScreenLocateManual.texture.width;
                float texHeight = _imageScreenLocateManual.texture.height;
                Vector2 texPoint = new Vector2(u * texWidth, v * texHeight);
                _screenLocatePoints.Add(texPoint);
            }
            //定位点显示
            Transform pointsTF = _imageScreenLocateManual.transform.Find("Points");
            for (int i = 0; i < pointsTF.childCount; i++)
            {
                Transform pointTF = pointsTF.GetChild(i);
                if (i < _screenLocatePoints.Count)
                {
                    float texWidth = _imageScreenLocateManual.texture.width;
                    float texHeight = _imageScreenLocateManual.texture.height;
                    Vector2 texSize = new Vector2(texWidth, texHeight);
                    Vector2 pos = _screenLocatePoints[i];
                    pointTF.localPosition = pos.pixelToLocalPosition_AnchorCenter(texSize, _imageScreenLocateManual.rectTransform.rect);
                    pointTF.gameObject.SetActive(true);
                }
                else pointTF.gameObject.SetActive(false);
            }
            //完成定位
            if (_screenLocatePoints.Count == 4)
            {
                _imageScreenLocateManual.gameObject.SetActive(false);
                InfraredCameraHelper.GetInstance().QuitScreenLocateManual(_screenLocatePoints);
                Transform pointsTF2 = _cameraRender.transform.Find("Points");
                if (pointsTF2.childCount == _screenLocatePoints.Count)
                {
                    float texWidth = _imageScreenLocateManual.texture.width;
                    float texHeight = _imageScreenLocateManual.texture.height;
                    Vector2 texSize = new Vector2(texWidth, texHeight);
                    for (int i = 0; i < pointsTF2.childCount; i++)
                    {
                        Transform pointTF = pointsTF2.GetChild(i);
                        Vector2 pos = _screenLocatePoints[i];
                        pointTF.localPosition = pos.pixelToLocalPosition_AnchorCenter(texSize, _cameraRender.rectTransform.rect);
                        pointTF.gameObject.SetActive(true);
                    }
                }
            }
        }
        //在相机画面显示准心
        if (ScreenLocate.Main)
        {
            var _sl = ScreenLocate.Main;
            var buffer = _sl.infraredSpotBuffer;
            if (buffer != null)
            {
                for (int i = 0; i < buffer.Length; i++)
                {
                    if (buffer[i].CameraLocation != null)
                    {
                        // 检测到光点
                        var pos = buffer[i].CameraLocation.Value.pixelToLocalPosition_AnchorCenter(_sl.mUVCCameraInfo.Size, _cameraRender.rectTransform.rect);
                        _crosshairsInCamera[i].gameObject.SetActive(true);
                        _crosshairsInCamera[i].anchoredPosition = pos;

                    }
                    else
                        _crosshairsInCamera[i].gameObject.SetActive(false);
                }
            }
        }
        //性能检测
        ++frames;
        float timeNow = Time.realtimeSinceStartup;
        const float UpdateInterval = 0.5f;
        if (timeNow > lastCheckTime + UpdateInterval)
        {
            float fps = (float)(frames / (timeNow - lastCheckTime));
            frames = 0;
            lastCheckTime = timeNow;
            _fpsText.text = "FPS:" + fps.ToString("f2");
        }
    }
    void SetSaturation(float v)
    {
        saturation.Set(v);
        _sliderSaturation.SetValueWithoutNotify(saturation.Get());
        _sliderSaturation.transform.Find("Value").GetComponent<Text>().text = saturation.Get().ToString("f1");
        InfraredCameraHelper.GetInstance().SetSaturation(saturation.Get());
    }
    void SetContrast(float v)
    {
        contrast.Set(v);
        _sliderContrast.SetValueWithoutNotify(contrast.Get());
        _sliderContrast.transform.Find("Value").GetComponent<Text>().text = contrast.Get().ToString("f1");
        InfraredCameraHelper.GetInstance().SetContrast(contrast.Get());
    }
    void SetShakeFilterValue(float v)
    {
        shakeFilterValue.Set(v);
        _sliderShakeFilter.SetValueWithoutNotify(shakeFilterValue.Get());
        _sliderShakeFilter.transform.Find("Value").GetComponent<Text>().text = shakeFilterValue.Get().ToString("f1");
        InfraredCameraHelper.GetInstance().SetShakeFilterValue(shakeFilterValue.Get());
    }
    void SetResolution(int optionIndex)
    {
        resoution.Set(optionIndex);
        _dropdownResolution.SetValueWithoutNotify(optionIndex);
        switch (optionIndex)
        {
            case 0:
                InfraredCameraHelper.GetInstance().SetCameraResolution(1280, 720);
                break;
            case 1:
                InfraredCameraHelper.GetInstance().SetCameraResolution(640, 360);
                break;
            case 2:
                InfraredCameraHelper.GetInstance().SetCameraResolution(320, 240);
                break;
        }
    }
    void OnClick_Reset()
    {
        SetBrightness(1);
        SetSaturation(1);
        SetContrast(1);
        SetShakeFilterValue(6);
    }
    void OnClick_ScreenLocateManual()
    {
        if (InfraredCameraHelper.GetInstance().IsScreenLocateManualDoing()) return;
        Texture2D texture2D = InfraredCameraHelper.GetInstance().EnterScreenLocateManual();
        if (texture2D == null)
        {
            InfraredCameraHelper.GetInstance().QuitScreenLocateManual(null);
            return;
        }
        _imageScreenLocateManual.texture = texture2D;
        _imageScreenLocateManual.material = InfraredCameraHelper.GetInstance().GetCameraMaterial();
        _screenLocatePoints.Clear();
        _imageScreenLocateManual.gameObject.SetActive(true);
    }
    #endregion

    #region 蓝牙模块
    [SerializeField] Button _btnConnect;
    [SerializeField] Text _textMacAddress;
    [SerializeField] Text _textBattery;
    void InitBluetoothModule()
    {
        SmartBowHelper.GetInstance().OnBluetoothModuleInited += OnBluetoothModuleInited;
        SmartBowHelper.GetInstance().OnBluetoothError += OnBluetoothError;
        SmartBowHelper.GetInstance().OnShooting += OnShooting;
        _btnConnect.onClick.AddListener(OnClick_Connect);
    }
    void UpdateBluetoothModule()
    {
        //更新显示蓝牙状态
        BluetoothStatusEnum bluetoothStatus = SmartBowHelper.GetInstance().GetBluetoothStatus();
        Text btnConnectText = _btnConnect.GetComponentInChildren<Text>();
        if (bluetoothStatus == BluetoothStatusEnum.None) btnConnectText.text = "<color=blue>未连接</color>（点击连接）";
        if (bluetoothStatus == BluetoothStatusEnum.Connecting) btnConnectText.text = "<color=#FF670D>连接中</color>";
        if (bluetoothStatus == BluetoothStatusEnum.Connected)
        {
            if (SmartBowHelper.GetInstance().IsBluetoothModuleInited()) btnConnectText.text = "<color=green>已连接</color>（点击断开）";
            else btnConnectText.text = "<color=green>已连接</color><color=blue>（正在初始化）</color>";
        }
        //更新显示电量
        int battery = SmartBowHelper.GetInstance().GetBattery();
        _textBattery.text = battery > 0 ? $"电量值:{battery}" : "未获得电量值";
        //更新显示Mac地址
        string macAddress = SmartBowHelper.GetInstance().GetMacAddress();
        _textMacAddress.text = macAddress != null ? $"Mac地址:{macAddress}" : "未获得Mac地址";
    }
    void OnBluetoothModuleInited()
    {
        SmartBowHelper.GetInstance().StartShootingSensor();
    }
    void OnBluetoothError(BluetoothError error, string message)
    {
        Debug.Log("OnBluetoothError:" + error);
        if (error == BluetoothError.ScanNotFoundTargetDevice)
        {
            TipText.Show("连接失败，未发现目标设备！");
            return;
        }
        TipText.Show(message);
    }
    void OnShooting(float speed)
    {
        Bow.Instance.Shoot();
    }
    void OnClick_Connect()
    {
        if (SmartBowHelper.GetInstance().GetBluetoothStatus() == BluetoothStatusEnum.Connecting) return;
        if (SmartBowHelper.GetInstance().GetBluetoothStatus() == BluetoothStatusEnum.None)
        {
            SmartBowHelper.GetInstance().Connect("test", 1);
            return;
        }
        if (SmartBowHelper.GetInstance().GetBluetoothStatus() == BluetoothStatusEnum.Connected)
        {
            SmartBowHelper.GetInstance().Disconnect();
            return;
        }
    }
    #endregion
}
public class ParamFloatValue
{
    private string _saveKey;
    private float _valueDefault;
    private bool _valueLoaded;
    private float _value;
    public ParamFloatValue(string saveKey, float valueDefault)
    {
        _saveKey = saveKey;
        _valueDefault = valueDefault;
    }
    public float Get()
    {
        if (!_valueLoaded) _value = PlayerPrefs.GetFloat(_saveKey, _valueDefault);
        return _value;
    }
    public void Set(float value)
    {
        _value = value;
        PlayerPrefs.SetFloat(_saveKey, _value);
        PlayerPrefs.Save();
    }
}
