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

namespace Rokojori
{  
  [Tool]
  [GlobalClass]
  public abstract partial class WipeCompositorEffect:RDGraphCompositorEffect
  {
    [ExportGroup("Wipe")]
    
    [Export(PropertyHint.Range, "0,1")]
    public float wipeState = 0f;

    [Export]
    public Gradient wipeGradient = new Gradient();

    [ExportGroup("Blend Mode")]
    [Export]
    public float replace = 1.0f;

    [Export]
    public float add = 0.0f;

    [Export]
    public float multiply = 0.0f;

    [Export]
    public float colorize = 0.0f;

    [Export]
    public bool normalizeBlendWeights = true;

    protected CEG_ImageProcessor wipe;
    protected CEG_ScreenColorTexure screenColorTexture;

    
    public Color GetWipeColor()
    {
      var clampedState = MathX.Clamp01( wipeState );
      var color = wipeGradient.Sample( clampedState );
      color.A *= clampedState;
      return color;
    }

    protected void InitializeWipe( CEG_ImageProcessor wipe )
    {
      this.wipe = wipe;
      screenColorTexture = new CEG_ScreenColorTexure( graph );

      graph.InitializeNodes();
      wipe.SetTextureSlotInputs( screenColorTexture, screenColorTexture );

      graph.SetProcessOrder( 
        screenColorTexture, 
        wipe
      );
    }

    protected void SetWipeConstants( params object[] wipeConstants )
    {
      var blendWeights = GetBlendModeWeights(); 
      var color = GetWipeColor();

      wipe.constants.SetOrAdd( true,  

        color.R, 
        color.G,
        color.B,
        color.A,

        blendWeights.X, 
        blendWeights.Y, 
        blendWeights.Z,
        blendWeights.W
      );

      wipe.constants.SetOrAdd( false, wipeConstants );

    }

    public Vector4 GetBlendModeWeights()
    {
      var blendR = replace;
      var blendA = add;
      var blendM = multiply;
      var blendC = colorize;

      var v = new Vector4( blendR, blendA, blendM, blendC );

      if ( normalizeBlendWeights )
      {
        var sum = blendR + blendA + blendM + blendC;

        v /= sum;
      }

      return v;
    }
  }
}