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

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

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

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

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

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

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

    public enum Channel
    {
      Red,
      Green,
      Blue,
      Hue,
      Saturation,
      Lightness,
      RGB
    }

    [Export]
    public Channel targetChannel;

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

    [Export( PropertyHint.Range, "0.01,100") ]
    public float noiseScale = 3;

    [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 );

    

    RG_ScreenColorTexure screenColorTexture;
    RG_BufferTexture bufferTexture;    

    CEG_Copy copy;
    RG_ChannelPixelation pixelation;    

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

      copy = new CEG_Copy( graph );
      pixelation = new RG_ChannelPixelation( graph );
      graph.InitializeNodes();

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

      

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


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

      pixelation.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 
        ),

        (float)pixelSizeX,
        (float)pixelSizeY,
        amount,
        (float)(int)targetChannel,

        noiseAmount,
        noiseScale,
        pixelOffsetX,
        pixelOffsetY
      );
    }

   
  }
}