using System;
using System.IO;
using Unity.Collections;
using UnityEngine;
using UnityEngine.UI;

public class WhiteBorad : MonoBehaviour
{
    const int width = 360;// RawImageɐݒ肷Texture2D̃TCY
    const int height = 360;
    const string filePath = "white_board.bin";// texturẻ摜ۑt@C
    public static int brushSize = 3;// LF̂̃TCŶ`uVƂĎg
    RawImage rawImage;// CanvasςɔzuRawImageŁA`Ώ

    void Start()
    {
        Time.fixedDeltaTime = 0.02f;//܂Application.targetFrameRate = 50;

        GameObject rawImageObj = GameObject.Find("RawImage");
        this.rawImage = rawImageObj.GetComponent<RawImage>();
        Color32 color = new Color32(255, 255, 255, 255);
        this.rawImage.texture = createTexture(width, height, color);// colorFTexture2D𐶐;

        // filePath̃t@C݂΁Ãt@Ceŏ\
        FileInfo fileInfo = new FileInfo(filePath);
        if (true && fileInfo.Exists)
        {
            byte[] buff = new byte[fileInfo.Length];
            using (FileStream stream = File.Open(filePath, FileMode.Open))
            {
                int idx = 0;
                while (idx < buff.Length)
                {
                    idx += stream.Read(buff, idx, buff.Length - idx);// t@Cǂݍ
                }
            }
            Texture2D texture = (Texture2D)this.rawImage.texture;
            Color32[] pixels = texture.GetPixels32();
            BytesToColor32(buff, pixels);// t@C擾oCgŃeNX`sNZݒ
            texture.SetPixels32(pixels);
            texture.Apply();
        }
    }

    void FixedUpdate()
    {
        if (Input.GetMouseButton(1))// E{^ŏ
        {
            this.rawImage.texture = createTexture(width, height, new Color32(255, 255, 255, 255));
        }
        if (Input.GetMouseButton(0))// {^
        {
            Vector3 pos = Input.mousePosition;
            Vector3 viewPos = Camera.main.ScreenToViewportPoint(pos);
            int x = (int)(viewPos.x * width);//}EXʒusNZʒu擾
            int y = (int)(viewPos.y * height);
            Debug.Log($"viewPos={viewPos}x ={x:000}y={y:000}");
            Color32 color = new Color32(255, 0, 0, 255);
            draw(color, x, y);// brushSizeŕ`揈// ` 
        }
    }

    public void OnApplicationQuit()// vOIɁArawImage.texturẻ摜t@C
    {
        Texture2D texture = (Texture2D)this.rawImage.texture;
        byte[] buff = getBytesByPixels(texture.GetPixels32());// texturẻ摜oCi
        using (FileStream stream = File.Open(filePath, FileMode.Create))
        {
            stream.Write(buff, 0, buff.Length);// t@Cɏ
        }
    }

    // this.rawImage.texturẻ摜̃sNZQŁA(x,y)ʒuƂbrushSize̐`colorFɐݒ
    private void draw(Color32 color, int x, int y)
    {
        int idx = y * height + x;// NbNʒuTexture2D̃sNZwFɕύXB
        Texture2D texture = (Texture2D)this.rawImage.texture;
        Color32[] pixels = texture.GetPixels32();
        try
        {
            for (int y2 = 0; y2 < brushSize; y2++)
            {
                for (int x2 = 0; x2 < brushSize; x2++)
                {
                    pixels[idx + x2 + y2 * width] = color;
                }
            }
        }
        catch (Exception _) { }
        texture.SetPixels32(pixels);
        texture.Apply();
    }

    // colorFŁAwidth ~ height̃TCYTexture2D𐶐B
    public static Texture2D createTexture(int width, int height, Color32 color)
    {
        Texture2D texture = new Texture2D(width, height, TextureFormat.RGBA32, false);
        NativeArray<Color32> pixels = texture.GetRawTextureData<Color32>();
        Debug.Log($"{pixels.Length}  ( {texture.height}, {texture.width})");
        for (int i = 0; i < pixels.Length; i++)
        {
            pixels[i] = color;
        }
        texture.Apply();
        return texture;
    }

    // bytezŁATexture2D擾pixelszݒ肷ioCi摜ݒj
    public static void BytesToColor32(byte[] bytes, Color32[] pixels)
    {
        bool chk = bytes.Length == pixels.Length * 4;
        if (chk == false) throw new Exception("BytesToColor32: {bytes.Length]bytepixelsɐݒo܂B");
        for (int idx_bytes = 0, idx = 0; idx < pixels.Length; idx++)
        {
            byte r = bytes[idx_bytes++];
            byte g = bytes[idx_bytes++];
            byte b = bytes[idx_bytes++];
            byte a = bytes[idx_bytes++];
            pixels[idx] = new Color32(r, g, b, a);
        }
    }

    // Texture2D擾pixelsz񂩂bytez񂩂𐶐ĕԂBi摜̃oCij
    public static byte[] getBytesByPixels(Color32[] pixels)
    {
        byte[] bytes = new byte[pixels.Length * 4];
        for (int i = 0, idx_bytes = 0; i < pixels.Length; i++)
        {
            bytes[idx_bytes++] = pixels[i].r;
            bytes[idx_bytes++] = pixels[i].g;
            bytes[idx_bytes++] = pixels[i].b;
            bytes[idx_bytes++] = pixels[i].a;
        }
        return bytes;
    }
}