using o0;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Unity.VisualScripting;
using UnityEngine;
using Color = UnityEngine.Color;

namespace ZIM
{
    internal class PixelArea
    {
        public static int gridLength = 16;
        //public static (int x, int y) gridSize;
        public static (int x, int y) GetGrid(Vector2 v)
        {
            var m = (int)(v.x / gridLength);
            var n = (int)(v.y / gridLength);
            return (m, n);
        }
        public static List<(double cos, double sin)> AngleMathList {
            get
            {
                if (angleMathList != null)
                    return angleMathList;
                // 三角函数值记录在list中
                double step = angleStep * 0.017453292519943295;
                angleMathList = new List<(double cos, double sin)>();
                for (double i = 0; i < 6.2831853; i += step)
                {
                    var cos = Math.Cos(i);
                    var sin = Math.Sin(i);
                    angleMathList.Add((cos, sin));
                }
                return angleMathList;
            }

        }

        static float angleStep = 11.25f;
        static List<(double cos, double sin)> angleMathList;


        public Vector2 Center;
        public float MaxRadius;
        public HashSet<Vector2> Pixels;

        HashSet<(int, int)> grids;

        public PixelArea(Vector2 location)
        {
            Center = location;
            Pixels = new HashSet<Vector2> { location };
            MaxRadius = 0;
            grids = new HashSet<(int, int)>();
            Add(location);
        }

        public PixelArea(IList<PixelArea> areas)
        {
            Center = Vector2.zero;
            Pixels = new HashSet<Vector2>();
            MaxRadius = 0;
            grids = new HashSet<(int, int)>();
            foreach (var a in areas)
            {
                Pixels.AddRange(a.Pixels);
                grids.AddRange(a.grids);
            }
            foreach (var p in Pixels)
            {
                Center += p;
            }
            Center /= Pixels.Count;
            foreach (var p in Pixels)
            {
                var radius = (p - Center).magnitude;
                if (radius > MaxRadius)
                    MaxRadius = radius;
            }
        }

        public bool Include((int, int) grid) => grids.Contains(grid);

        public void Add(Vector2 point) => Add(point, GetGrid(point));

        public void Add(Vector2 point, (int x, int y) grid)
        {
            Center += (point - Center) / Pixels.Count;
            var radius = (point - Center).magnitude;
            if (radius > MaxRadius)
                MaxRadius = radius;

            Pixels.Add(point);
            grids.AddRange(new (int, int)[]
            {
                    (grid.x + -1, grid.y +  0) , (grid.x + 1 , grid.y + 0),
                    (grid.x + 1,  grid.y + -1) , (grid.x + -1, grid.y + 1),
                    (grid.x + 0,  grid.y + -1) , (grid.x + 0 , grid.y + 1),
                    (grid.x + -1, grid.y + -1) , (grid.x + 1 , grid.y + 1),
                    grid
            });
        }

        public float TotalBrightness(Color[] pixels,Func<int,int,int> Vector2ToIndex, int outer_size = 3)
        {
            (int x, int y) rectMin = ((int)(Center.x - MaxRadius - outer_size), (int)(Center.y - MaxRadius - outer_size));
            (int x, int y) rectMax = ((int)(Center.x + MaxRadius + outer_size), (int)(Center.y + MaxRadius + outer_size));

            var total = 0f;
            Parallel.For(rectMin.x, rectMax.x, (i) =>
            {
                var t = 0;
                for (int j = rectMin.y; j < rectMax.y; j++)
                {
                    var index = Vector2ToIndex(i, j);
                    var b = pixels[index].Brightness(64);
                    t += b;
                }
                lock (InfraredLocate.locker)
                {
                    total += t;
                }
            });
            //total /= (rectMax.y - rectMin.y) * (rectMax.x - rectMin.x);

            return total;
        }
    }

}
