using Godot;
using System;
using System.Linq;
using System.Threading.Tasks;

public static class Projector
{
    public static int[,] Points = new int[1024,512];
    private static bool _gathered = false;
    public static void GatherPoints(PlanetHelper helper, int resolutionH = 2048, bool regather = false)
    {
        if (!regather && _gathered)
            return;
        Points = new int[resolutionH,resolutionH / 2];
        string filename = $"user://points-{resolutionH}-{resolutionH / 2}.dat";
        if (FileAccess.FileExists(filename))
        {
            var readfile = FileAccess.Open(filename, FileAccess.ModeFlags.Read);
            for (int x = 0; x < Points.GetLength(0); x++)
            {
                for (int y = 0; y < Points.GetLength(1); y++)
                {
                    Points[x, y] = (int)readfile.Get32();
                }
            }
            readfile.Close();
            return;
        }
        
        Parallel.ForEach(Enumerable.Range(0, Points.GetLength(0)), x =>
        {
            for (int y = 0; y < Points.GetLength(1); y++)
            {
                float yaw = (float)x / Points.GetLength(0) * 360f;
                float pitch = (float)y / Points.GetLength(1) * 180f;
                Vector3 point = Vector3.Up;
                point = point.Rotated(Vector3.Forward, Mathf.DegToRad(pitch));
                point = point.Rotated(Vector3.Up, Mathf.DegToRad(yaw));
                int index = helper.Octree.SearchNearest(point)?.Id ?? -1;
                Points[x,y] =  index;
            }
        });
        var file = FileAccess.Open(filename, FileAccess.ModeFlags.Write);
        for (int x = 0; x < Points.GetLength(0); x++)
            for (int y = 0; y < Points.GetLength(1); y++)
                file.Store32((uint)Points[x,y]);
        _gathered = true;
        file.Close();        
    }

    public static ImageTexture Render(PlanetHelper helper)
    {
        var image = Image.CreateEmpty(Points.GetLength(0) + 1, Points.GetLength(1) + 1, false, Image.Format.Rgb8);;
        
        for (int x = 0; x < Points.GetLength(0); x++)
        {
            for (int y = 0; y < Points.GetLength(1); y++)
            {
                image.SetPixel(x,y, helper.Mdt.GetVertexColor(Points[x,y]));
            }
        }
        return ImageTexture.CreateFromImage(image);
    }
}
