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

public class Test : MonoBehaviour
{
    public RawImage rawImage;
    public RawImage rawImage1;
    public RawImage rawImage2;
    public RawImage rawImage3;

    private WebCamTexture _webCamTexture;
    private Texture2D mUVCTexture2DTemp;
    // Start is called before the first frame update
    void Start()
    {

        CreateTextureIfNeeded(rawImage.texture);
        rawImage1.texture = m_SourceTexture.zimAutoLight(10) ;

        if (m_SourceTexture != null)
        {

            var pixelData = m_TargetTexture.GetPixelData<Color32>(0);
            var pixelDataSource = m_SourceTexture.GetPixelData<Color32>(0);
            //var pixelDataSource = m_SourceTexture.GetPixels();
            var offset = 0;
            for (var y = 0; y < m_SourceTexture.width; ++y)
            {
                for (var x = 0; x < m_SourceTexture.height; ++x, ++offset)
                {
                   // Debug.Log(pixelDataSource[offset]);
                    pixelData[offset] = pixelDataSource[offset];
                }
            }

            m_TargetTexture.Apply();
        }
    }

    public void OnClick_Open()
    {

        if (_webCamTexture != null)
        {
            Debug.LogError("开启失败，请先关闭正在使用的摄像头！");
            return;
        }
        if (Application.HasUserAuthorization(UserAuthorization.WebCam))
        {
            WebCamDevice[] devices = WebCamTexture.devices;
            for (int i = 0; i < devices.Length; i++)
            {
                Debug.Log("devices[" + i + "].name:" + devices[i].name);
               // this.logText.text += "devices[" + i + "].name:" + devices[i].name + "\n";
            }
            if (devices.Length == 0)
            {
                Debug.LogError("开启失败，没找到可用的摄像头！");
                return;
            }

            string deviceName = devices[0].name;
            _webCamTexture = new WebCamTexture(deviceName, 1280, 720, 30);
            _webCamTexture.Play();
            if (rawImage) rawImage.texture = _webCamTexture;
            Debug.Log("成功开启摄像头 " + deviceName);

        }
        else
        {
            Debug.LogError("开启失败，用户未授予摄像头权限！");
        }
    }

    // Update is called once per frame
    void Update()
    {
       

        if (_webCamTexture && _webCamTexture.didUpdateThisFrame)
        {
            // CreateExternalTextureIfNeeded(rawImage.texture);
            //SaveScreenShot(rawImage.texture);
            if (texture2D != null)
                Destroy(texture2D);
            texture2D = TextureToTexture2D2(rawImage.texture);
            rawImage1.texture = texture2D;
            //var pixels = texture2D.GetPixels();
            //Debug.Log(pixels.Length);

          
        }
        if (Input.GetKeyDown(KeyCode.Space) && texture2D !=null)
        {
            Debug.Log("Input.GetKeyDown(KeyCode.Space)");
            //SaveScreenShot(rawImage.texture);
            if (rawImage3.texture != null)
                DestroyImmediate(rawImage3.texture);
            rawImage3.texture = texture2D.zimAutoLight(10);

        }


    }

    private Texture2D externalTexture;
    public void CreateExternalTextureIfNeeded(Texture texture)
    {
        if (externalTexture != null)
            DestroyImmediate(externalTexture);

        externalTexture = Texture2D.CreateExternalTexture(rawImage.texture.width, rawImage.texture.height, TextureFormat.ARGB32, false, true, rawImage.texture.GetNativeTexturePtr()); //TextureToTexture2D(texture);

        rawImage1.texture = externalTexture;
    }

    private Texture2D texture2D;
    private Texture2D TextureToTexture2D(Texture texture)
    {
        if(texture2D == null) texture2D = new Texture2D(texture.width, texture.height, TextureFormat.ARGB32, false, true);
        RenderTexture currentRT = RenderTexture.active;
        RenderTexture renderTexture = RenderTexture.GetTemporary(
                    texture.width,
                    texture.height,
                    0,
                    RenderTextureFormat.ARGB32,
                    RenderTextureReadWrite.Linear);
        Graphics.Blit(texture, renderTexture);
        RenderTexture.active = renderTexture;
        texture2D.ReadPixels(new Rect(0, 0, renderTexture.width, renderTexture.height), 0, 0);
        texture2D.Apply();
        RenderTexture.active = currentRT;
        RenderTexture.ReleaseTemporary(renderTexture);
        return texture2D;
    }
    private Texture2D TextureToTexture2D2(Texture texture)
    {
        Texture2D _texture2D = new Texture2D(texture.width, texture.height, TextureFormat.ARGB32, false, true);
        RenderTexture currentRT = RenderTexture.active;
        RenderTexture renderTexture = RenderTexture.GetTemporary(
                    texture.width,
                    texture.height,
                    0,
                    RenderTextureFormat.ARGB32,
                    RenderTextureReadWrite.Linear);
        Graphics.Blit(texture, renderTexture);
        RenderTexture.active = renderTexture;
        _texture2D.ReadPixels(new Rect(0, 0, renderTexture.width, renderTexture.height), 0, 0);
        _texture2D.Apply();
        RenderTexture.active = currentRT;
        RenderTexture.ReleaseTemporary(renderTexture);
        return _texture2D;
    }
    Texture2D m_SourceTexture;
    Texture2D m_TargetTexture;
    private void CreateTextureIfNeeded(Texture texture)
    {
        //&& (m_SourceTexture.width != texture.width || m_SourceTexture.height != texture.height)
        //if (m_SourceTexture != null)
        //{
        //    DestroyImmediate(m_SourceTexture);
        //    m_SourceTexture = null;
        //}
        if(m_SourceTexture == null) m_SourceTexture = new Texture2D(texture.width, texture.height,TextureFormat.ARGB32,false,true);
        RenderTexture renderTexture = RenderTexture.GetTemporary(
                    texture.width,
                    texture.height,
                    0,
                    RenderTextureFormat.ARGB32,
                    RenderTextureReadWrite.Linear);

        Graphics.Blit(texture, renderTexture);

        RenderTexture currentRT = RenderTexture.active;
        RenderTexture.active = renderTexture;

        m_SourceTexture.ReadPixels(new Rect(0, 0, renderTexture.width, renderTexture.height), 0, 0);
        m_SourceTexture.Apply();

        RenderTexture.active = currentRT;
        RenderTexture.ReleaseTemporary(renderTexture);


        if (m_TargetTexture != null)
        {
            DestroyImmediate(m_TargetTexture);
            m_TargetTexture = null;
        }
        if (m_TargetTexture == null)
        {
            m_TargetTexture = new Texture2D(texture.width, texture.height, TextureFormat.ARGB32, false, true);
            m_TargetTexture.wrapMode = TextureWrapMode.Clamp;
            rawImage2.texture = m_TargetTexture;
        }

    }

    private static Texture2D ResizeTexture(Texture source)
    {
        if (source != null)
        {
            int width = source.width;
            int height = source.height;
            // 创建临时的RenderTexture
            RenderTexture renderTex = RenderTexture.GetTemporary(width, height, 24, RenderTextureFormat.ARGB32, RenderTextureReadWrite.Linear);
            // 复制source的纹理到RenderTexture里
            Graphics.Blit(source, renderTex);
            // 开启当前RenderTexture激活状态
            RenderTexture previous = RenderTexture.active;
            RenderTexture.active = renderTex;
            // 创建修改后的纹理，保持与源纹理相同压缩格式
            Texture2D resizedTexture = new Texture2D(width, height, TextureFormat.ARGB32, false,true);
            // 读取像素到创建的纹理中
            resizedTexture.ReadPixels(new Rect(0, 0, width, height), 0, 0);
            // 应用修改到GPU上
            resizedTexture.Apply();
            // 停止当前RenderTexture工作
            RenderTexture.active = previous;
            // 释放内存
            RenderTexture.ReleaseTemporary(renderTex);
            return resizedTexture;
        }
        else
        {
            return null;
        }
    }



    private Texture2D CreateTextureBySetGetPixels(Texture2D sourceTexture)
    {
        if (sourceTexture != null)
        {

            int sourceMipLevel = 0;

            Color[] srcPixels = sourceTexture.GetPixels(sourceMipLevel);

            //newTextureByPixels = new Texture2D(sourceTexture.width, sourceTexture.height);

            Texture2D newTextureByPixels = new Texture2D(sourceTexture.width, sourceTexture.height, sourceTexture.format, false);

            newTextureByPixels.SetPixels(srcPixels);

            newTextureByPixels.Apply();

            return newTextureByPixels;

        }
        else
        {

            Debug.LogWarning("Texture is null");

            return null;

        }
    }
    private Texture2D CreateTextureByRawData(Texture2D sourceTexture)
    {

        if (sourceTexture != null)
        {
            Texture2D newTextureByRawData = new Texture2D(sourceTexture.width, sourceTexture.height, sourceTexture.format, false);
            // 对于运行时纹理生成，也可以通过GetRawTextureData直接写入纹理数据，返回一个Unity.Collections.NativeArray
            // 这可以更快，因为它避免了 LoadRawTextureData 会执行的内存复制。
            newTextureByRawData.LoadRawTextureData(sourceTexture.GetRawTextureData());
            newTextureByRawData.Apply();
            return newTextureByRawData;
        }
        else
        {
            Debug.LogWarning("Texture is null");
            return null;
        }

    }
}
