using System;
using JetBrains.Annotations;
using UnityEngine;
using UnityEngine.UI;

public class Sprite_DownPooling : MonoBehaviour
{

    public Image _image;
    public Image _image_Convert_256;
    public Image _image_Convert_128;
    public Image _image_Convert_256_Up;
    public Image _image_Convert_256_Up2;



    private void Awake()
    {
        





    }


    // Start is called once before the first execution of Update after the MonoBehaviour is created
    void Start()
    {

        //Color[] testPixels = _image.sprite.texture.GetPixels();
        //Debug.Log($"ȼ : {testPixels.Length}");
        //Debug.Log($"ù ° ȼ : {testPixels[0]}");

        //Texture2D tex = GameObject.Instantiate<Texture2D>(_image.sprite.texture);
        //Debug.Log($"ε ؽó ũ: {tex.width}x{tex.height}");

        //Color[] pixels = tex.GetPixels();
        //Debug.Log($"ù ° ȼ : {pixels[0]}");


        //Texture2D sourceTex = _image.sprite.texture;
        
        ////  ؽó 
        //Texture2D processedTex = new Texture2D(sourceTex.width, sourceTex.height, TextureFormat.RGBA32, false);
        //Graphics.CopyTexture(sourceTex, processedTex);

        ////  Ʈ 
        //Sprite newSprite = Sprite.Create(processedTex, new Rect(0, 0, sourceTex.width, sourceTex.height), new Vector2(0.5f, 0.5f));

        //// ̹ 
        //_image_Convert.sprite = newSprite;

    }

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


        if (Input.GetKeyDown(KeyCode.Z))
        {

            //  Ʈ 

            // ̹ 

            Texture2D tex_Next256 = SampleTestCode(_image.sprite.texture);

            Sprite newSprite = Sprite.Create(tex_Next256, new Rect(0, 0, tex_Next256.width, tex_Next256.height), new Vector2(0.5f, 0.5f));
            _image_Convert_256.sprite = newSprite;

            SampleTestCode(tex_Next256);

            Texture2D tex_Next128 = SampleTestCode(tex_Next256);

            newSprite = Sprite.Create(tex_Next128, new Rect(0, 0, tex_Next128.width, tex_Next128.height), new Vector2(0.5f, 0.5f));
            _image_Convert_128.sprite = newSprite;

            Texture2D tex_Up256 = SampleUpPooling(tex_Next128);

            // Ʈ ȯϿ UI 
            newSprite = Sprite.Create(tex_Up256, new Rect(0, 0, tex_Up256.width, tex_Up256.height), new Vector2(0.5f, 0.5f));
            _image_Convert_256_Up.sprite = newSprite;

            Texture2D tex_Up256_2 = sampleBilinearUpUpPooling(tex_Next128);

            newSprite = Sprite.Create(tex_Up256_2, new Rect(0, 0, tex_Up256_2.width, tex_Up256_2.height), new Vector2(0.5f, 0.5f));
            _image_Convert_256_Up2.sprite = newSprite;

        }
    }

    public Texture2D sampleBilinearUpUpPooling(Texture2D sourceTex)
    {
        if (sourceTex == null)
        {
            Debug.LogError("̹ ε !");
            return null;
        }

        int srcWidth = sourceTex.width;
        int srcHeight = sourceTex.height;
        int destWidth = srcWidth * 2;
        int destHeight = srcHeight * 2;

        // ø ؽó (2 ũ)
        Texture2D upSampledTex = new Texture2D(destWidth, destHeight, TextureFormat.RGBA32, false);

        // ø  (Bilinear)
        for (int y = 0; y < destHeight; y++)
        {
            for (int x = 0; x < destWidth; x++)
            {
                //  ؽó ǥ  
                float gx = (float)x / (destWidth - 1) * (srcWidth - 1);
                float gy = (float)y / (destHeight - 1) * (srcHeight - 1);

                int x0 = Mathf.FloorToInt(gx);
                int x1 = Mathf.Min(x0 + 1, srcWidth - 1);
                int y0 = Mathf.FloorToInt(gy);
                int y1 = Mathf.Min(y0 + 1, srcHeight - 1);

                float dx = gx - x0;
                float dy = gy - y0;

                // ֺ 4ȼ 
                Color c00 = sourceTex.GetPixel(x0, y0);
                Color c10 = sourceTex.GetPixel(x1, y0);
                Color c01 = sourceTex.GetPixel(x0, y1);
                Color c11 = sourceTex.GetPixel(x1, y1);

                // Bilinear 
                Color c0 = Color.Lerp(c00, c10, dx);
                Color c1 = Color.Lerp(c01, c11, dx);
                Color finalColor = Color.Lerp(c0, c1, dy);

                upSampledTex.SetPixel(x, y, finalColor);
            }
        }

        upSampledTex.Apply();

        return upSampledTex;
    }

    public Texture2D SampleUpPooling(Texture2D sourceTex)
    {

        if (sourceTex == null)
        {
            Debug.LogError("̹ ε !");
            return null;
        }

        int width = sourceTex.width;
        int height = sourceTex.height;

        // ø ؽó (2 ũ)
        Texture2D upSampledTex = new Texture2D(width * 2, height * 2, TextureFormat.RGBA32, false);

        // ø  (Nearest Neighbor)
        for (int y = 0; y < height; y++)
        {
            for (int x = 0; x < width; x++)
            {
                Color pixelColor = sourceTex.GetPixel(x, y);

                // 2x2  
                upSampledTex.SetPixel(x * 2, y * 2, pixelColor);
                upSampledTex.SetPixel(x * 2 + 1, y * 2, pixelColor);
                upSampledTex.SetPixel(x * 2, y * 2 + 1, pixelColor);
                upSampledTex.SetPixel(x * 2 + 1, y * 2 + 1, pixelColor);
            }
        }

        upSampledTex.Apply();

        return upSampledTex;

        
    }

    public Texture2D SampleTestCode(Texture2D aSourceTex)
    {
        if (aSourceTex == null)
        {
            Debug.LogError("̹ ε !  Ȯ");
            return null;
        }

        //  ؽó 
        Texture2D downSampledTex = new Texture2D(aSourceTex.width / 2, aSourceTex.height / 2, TextureFormat.RGBA32, false);


        int width = aSourceTex.width;
        int height = aSourceTex.height;

        // Ǯ ũ
        int poolSize = 2;

        for (int y = 0; y < height; y += poolSize)
        {
            for (int x = 0; x < width; x += poolSize)
            {
                #region __ٿǮ__

                //// 2x2 ȼ հ 
                //Color c1 = sourceTex.GetPixel(x, y);
                //Color c2 = sourceTex.GetPixel(x + 1, y);
                //Color c3 = sourceTex.GetPixel(x, y + 1);
                //Color c4 = sourceTex.GetPixel(x + 1, y + 1);

                //Color avgColor = (c1 + c2 + c3 + c4) / 4f;

                //// ٿø ġ Ҵ
                //downSampledTex.SetPixel(x / 2, y / 2, avgColor);

                #endregion  //__ٿǮ__


                #region __ƽǮ__

                // 2x2  ȼ 
                Color c1 = aSourceTex.GetPixel(x, y);
                Color c2 = aSourceTex.GetPixel(x + 1, y);
                Color c3 = aSourceTex.GetPixel(x, y + 1);
                Color c4 = aSourceTex.GetPixel(x + 1, y + 1);

                //  äκ ִ 
                float r = Mathf.Max(c1.r, c2.r, c3.r, c4.r);
                float g = Mathf.Max(c1.g, c2.g, c3.g, c4.g);
                float b = Mathf.Max(c1.b, c2.b, c3.b, c4.b);
                float a = Mathf.Max(c1.a, c2.a, c3.a, c4.a);

                // ִ ÷ 
                Color maxColor = new Color(r, g, b, a);
                //maxColor.a = a / 2;

                // ƽø ؽó 
                downSampledTex.SetPixel(x / 2, y / 2, maxColor);

                #endregion  //__ƽǮ__



            }
        }
        downSampledTex.Apply();


        return downSampledTex;
    }



}
