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

namespace Rokojori
{  
  [Tool]
  [GlobalClass]
  public partial class Kernel3Effect:RDGraphCompositorEffect
  {
    public Kernel3Effect():base()
    {
      Initialize();
    }

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

    [Export( PropertyHint.Range, "1,10")]
    public int kernelOffset = 1;

    [Export]
    public Vector3 rowTop = new Vector3( 0, 0, 0 );

    [Export]
    public Vector3 rowCenter = new Vector3( 0, 1, 0 );

    [Export]
    public Vector3 rowBottom = new Vector3( 0, 0, 0 );

    [Export]
    public bool normalize = false;

    [Export]
    public bool clamp = false;

    RG_ScreenColorTexure screenColorTexture;
    RG_BufferTexture bufferTexture;    

    CEG_Copy copy;
    RG_Kernel3 kernel;    

    void Initialize()
    { 
      screenColorTexture = new RG_ScreenColorTexure( graph );
      bufferTexture = RG_BufferTexture.ScreenSize( graph );

      copy = new CEG_Copy( graph );
      kernel = new RG_Kernel3( graph );
      graph.InitializeNodes();

      copy.SetTextureSlotInputs( screenColorTexture, bufferTexture );
      kernel.SetTextureSlotInputs( copy.output, copy.input );

      

      graph.SetProcessOrder(
        screenColorTexture, 
        bufferTexture, 
        copy,
        kernel 
      );
      
    }
    
    float v( Vector3 v )
    {
      return v.X + v.Y + v.Z;
    }

    protected override void ForAllViews()
    {
      var s = 1.0f;

      if ( normalize )
      {
        var n = v( rowTop ) + v( rowCenter ) + v( rowBottom );
        
        if ( n != 0 )
        {
          s = 1f / n;
        }

      }

      kernel.constants.Set(
       [ 
        amount,
        rowTop.X * s, rowTop.Y * s, rowTop.Z * s,
        rowCenter.X * s, rowCenter.Y * s, rowCenter.Z * s,
        rowBottom.X * s, rowBottom.Y * s, rowBottom.Z * s,
        (float) kernelOffset,
        clamp ? 1.0f : 0.0f
       ]
      );
     
    }

   
  }
}