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

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

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

    [Export( PropertyHint.Range, "0.01,100") ]
    public float scale = 1f;

    [Export( PropertyHint.Range, "1,5") ]
    public int smearingSteps = 3;

    [Export( PropertyHint.Range, "1,1.5") ]
    public float smearing = 1.1f;

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

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

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

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

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

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

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


    RG_ScreenColorTexure screenColorTexture;
    RG_BufferTexture bufferTexture;    

    CEG_Copy copy;
    RG_NoiseDistortion distortion;    

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

      copy = new CEG_Copy( graph );
      distortion = new RG_NoiseDistortion( graph );
      graph.InitializeNodes();

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

      

      graph.SetProcessOrder(
        screenColorTexture, 
        bufferTexture, 
        copy,
        distortion 
      );
      
    }


    protected override void ForAllViews()
    {
      var time = TimeLine.osTime;

      distortion.constants.Set(        
        new Vector4( 
          xU.X + Mathf.Sin( xU.Y * time ) * xU.Z, 
          xV.X + Mathf.Sin( xV.Y * time ) * xV.Z, 
          yU.X + Mathf.Sin( yU.Y * time ) * yU.Z, 
          yV.X + Mathf.Sin( yV.Y * time ) * yV.Z 
        ),
        amount, 
        scale,
        1.0f + redShift,
        1.0f + greenShift,
        1.0f + blueShift,
        (float) smearingSteps,
        smearing

      );
    }

   
  }
}