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 ColorAdjustments:_XX_ColorCorrectionModifier
  { 
    [Export(PropertyHint.Range, "-180,180 suffix:°")]
    public float hue = 0;

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

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

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

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

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

    [Export]
    public Gradient gradient;

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

     [Export(PropertyHint.Range, "-1,1")]
    public float gradientLumaType = 0f;

    protected override Color _Modify( Color sourceColor )
    {
      var hslColor = HSLColor.FromRGBA( sourceColor );
      var luminance = hslColor.l;

      hslColor.h = MathX.Repeat( hslColor.h + hue, 360 );
      hslColor.s = MathX.Clamp01( hslColor.s + saturation/100f );
      

      var vibranceAmount = 1f;
      var angleDistanceAmount = MathX.Clamp01( Mathf.Abs( MathX.AngleDelta( hslColor.h, 0 ) ) / 180f );
      var luminanceAmount = 1f - hslColor.l;
      vibranceAmount = MathX.Clamp01( angleDistanceAmount * luminanceAmount + 0.1f ); 

      // var rgb = new Color( vibrance/100f * vibranceAmount, vibrance/100f * vibranceAmount, vibrance/100f * vibranceAmount, 1 );
      hslColor.s = Mathf.Lerp( hslColor.s, 1f, vibrance/100f * vibranceAmount ); 
      hslColor.s = MathX.Clamp01( hslColor.s );

      hslColor.l = ( hslColor.l - 0.5f ) * Mathf.Pow( 2, contrast/100f ) + 0.5f;
      hslColor.l = MathX.Clamp01( hslColor.l + brightness/100f );

      hslColor.ClampToLimits();
      var rgb = hslColor.ToRGBA();

      rgb = rgb.Gamma( Mathf.Pow( 2.2f, gamma/100f ) );
      rgb = rgb.Clamp();


      if ( gradient != null )
      {
        var hsl2 = HSLColor.FromRGBA( rgb );
        var currentLuminance = hsl2.l;

        var lumaLookUp = Mathf.Lerp( currentLuminance, luminance, gradientLumaType * 0.5f + 0.5f );
        var sampledGradient = gradient.Sample( lumaLookUp );
        var gradientColorHSL = HSLColor.FromRGBA( sampledGradient );
        
        var weigths = new Vector4( 1f * gradientColorHSL.s, 0.2f, 0.1f, 1f ) ;
        weigths = weigths * ( gradientStrength / 100f ) * sampledGradient.A;
        // weigths.W = 1f;
        
        var combined = HSLColor.LerpWithHueInRGB( hsl2, gradientColorHSL, weigths );

        combined.ClampToLimits();

        rgb = combined.ToRGBA();
        rgb = rgb.Clamp();
      }


      return rgb;
    }
  }
}