using System.Collections;
using System.Collections.Generic;
using Godot;
using System;
using System.Threading;
using System.Threading.Tasks;


namespace Rokojori
{
  [Tool]
  [GlobalClass]
  public partial class ColorCorrectionStack:Node
  {
    [Export]
    public WorldEnvironment worldEnvironment;

    [Export]
    public ColorCorrectionPreset preset;

    [Export(PropertyHint.Range, "0,100 suffix:%")]
    public float amount = 100;

    [Export]
    public bool changed = false;

    Godot.Collections.Array<Image> luts;

    

    ImageTexture3D outputTexture;

    [Export]
    public bool refresh = false;

    [Export]
    public int lutSize = 33;

    public override void _Process( double delta )
    {
      if ( worldEnvironment == null || preset == null || ! changed )
      {
        return;
      }

      if ( refresh )
      {
        luts = null;
        outputTexture = null;
      }

      EnsureImages();

      for ( int bi = 0; bi < lutSize; bi++ )
      {
        var image = luts[ bi ];
        var b = bi / ( lutSize - 1f );

        for ( int ri = 0; ri < lutSize; ri ++ )
        {
          var r = ri / ( lutSize - 1f );

          for ( int gi = 0; gi < lutSize; gi ++ )
          {
            
            var g = gi / ( lutSize - 1f );
            
            var color = new Color( r, g, b );
            var modifiedColor = preset.Process( color );

            modifiedColor = ColorX.Lerp( color, modifiedColor, amount / 100f );

            image.SetPixel( ri, gi, modifiedColor );


          }
        }
      } 


      if ( outputTexture == null )
      {
        outputTexture = new ImageTexture3D();
        outputTexture.Create( Image.Format.Rgb8, lutSize, lutSize, lutSize, false, luts );
        
      }
      else
      {
        outputTexture.Update( luts );
      }

      worldEnvironment.Environment.AdjustmentEnabled = true;
      worldEnvironment.Environment.AdjustmentColorCorrection = outputTexture;


    }

    void EnsureImages()
    {
      if ( luts != null )
      {
        return;
      }

      luts = new Godot.Collections.Array<Image>();

      for ( int i = 0; i < lutSize; i++ )
      {
        luts.Add( Image.CreateEmpty( lutSize, lutSize, false, Image.Format.Rgb8 ) );
      } 
    }

    // void GrabOriginal()
    // {
    //   if ( original != null )
    //   {
    //     return;
    //   }

    //   var path = "res://addons/rokojori_action_library/Runtime/VirtualCameras/PostProcess/environment_adjustments_3d_lut_template.webp"; 
    //   original = TextureCombinerBuffer.FromPath( path );
    //   output = TextureCombinerBuffer.Create( original.width, original.height );
    // }
  }
}