
using Godot;
using Godot.Collections;
using System.Collections.Generic;

namespace Rokojori
{  
  [Tool]
  [GlobalClass]
  public partial class HDRMappingEffect:ColorEffect
  {
    static float DefaultMaxPoint = 10;

    public HDRMappingEffect():base()
    {
      Initialize();
    } 

    [Export( PropertyHint.Range, "0,1") ]
    public float amount = 1f;
    
    [Export]
    public CurveTexture mapping = new CurveTexture().WithCurve( 
      new Curve().WithDomainRange( 0, 1f ).WithValueRange( 0, DefaultMaxPoint )
      .WithValues( 0f, DefaultMaxPoint ).WithLinearTangents()
    ).WithResolution( 2048 ).WithTextureMode( CurveTexture.TextureModeEnum.Red );

    [Export]
    public float maxDomain = DefaultMaxPoint;

    [Export]
    public float outputScale = 1f;

    [ExportGroup( "Luma Settings")]
    [Export]
    public Vector3 lumaWeights = new Vector3( 0.2f, 0.7f, 0.1f );

    [Export]
    public float lumaPower = 1;

    [Export]
    public float lumaScale = 1;

    RG_ScreenColorTexure screenColorTexture;
    RG_ImageTexture _curvesTexture;
    RG_HDRMapping _mapping;    

    void Initialize()
    { 
      screenColorTexture = new RG_ScreenColorTexure( graph );
      _curvesTexture = new RG_ImageTexture( graph );
      _mapping = new RG_HDRMapping( graph );


      graph.InitializeNodes();      

      
      _mapping.SetTextureSlotInputs( _curvesTexture, screenColorTexture ); 

      _curvesTexture.SetImageTexture( mapping );

      _mapping.input.sampler = context.Sampler( RenderingDevice.SamplerFilter.Linear, RenderingDevice.SamplerRepeatMode.ClampToEdge );

      graph.SetProcessOrder( 
        screenColorTexture, 
        _curvesTexture,
        _mapping 
      );
    }
   

    protected override void ForAllViews()
    {
      _curvesTexture.SetImageTexture( mapping );

      var maxInput = 1f;

      if ( mapping != null && mapping.Curve != null)
      {
        maxInput = mapping.Curve.MaxDomain;
      }

      _mapping.constants.Set(
        maxDomain,
        lumaWeights.X, 
        lumaWeights.Y,
        lumaWeights.Z,

        lumaPower,
        lumaScale,
        outputScale,
        amount
      );
    }

   
  }
}