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

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

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

    public enum HSLConversionMode
    {
      Raw,
      Scaled,
      Clamped
    }

    [Export]
    public HSLConversionMode hslConversionMode = HSLConversionMode.Scaled;

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

    [Export( PropertyHint.Range, "1,100") ]
    public float redSteps = 10;

    [Export( PropertyHint.Range, "1,10") ]
    public float redStepsMultiplier = 1;

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

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

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

    [Export( PropertyHint.Range, "1,100") ]
    public float greenSteps = 10;

    [Export( PropertyHint.Range, "1,10") ]
    public float greenStepsMultiplier = 1;

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

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

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

    [Export( PropertyHint.Range, "1,100") ]
    public float blueSteps = 10;

    [Export( PropertyHint.Range, "1,10") ]
    public float blueStepsMultiplier = 1;

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

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

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

    [Export( PropertyHint.Range, "1,100") ]
    public float rgbSteps = 10;

    [Export( PropertyHint.Range, "1,10") ]
    public float rgbStepsMultiplier = 1;

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

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

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

    [Export( PropertyHint.Range, "1,100") ]
    public float hueSteps = 10;

    [Export( PropertyHint.Range, "1,10") ]
    public float hueStepsMultiplier = 1;

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

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

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

    [Export( PropertyHint.Range, "1,100") ]
    public float saturationSteps = 10;

    [Export( PropertyHint.Range, "1,10") ]
    public float saturationStepsMultiplier = 1;

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

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

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

    [Export( PropertyHint.Range, "1,100") ]
    public float luminanceSteps = 10;

    [Export( PropertyHint.Range, "1,10") ]
    public float luminanceStepsMultiplier = 1;

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

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

    


    RG_ScreenColorTexure screenColorTexture;
    RG_ColorQuantizer colorQuantizer;    

    void Initialize()
    { 
      screenColorTexture = new RG_ScreenColorTexure( graph );
      colorQuantizer = new RG_ColorQuantizer( graph );


      graph.InitializeNodes();      

      
      colorQuantizer.SetTextureSlotInputs( screenColorTexture, screenColorTexture ); 


      graph.SetProcessOrder( 
        screenColorTexture, 
        colorQuantizer 
      );
    }
   

    protected override void ForAllViews()
    {
      colorQuantizer.constants.Set(
        
        new Vector4( redAmount, redSteps * redStepsMultiplier,  Mathf.Pow( 5f,redGamma ), redOffset ),
        new Vector4( greenAmount, greenSteps * greenStepsMultiplier,  Mathf.Pow( 5f,greenGamma ), greenOffset ),
        new Vector4( blueAmount, blueSteps * blueStepsMultiplier,  Mathf.Pow( 5f,blueGamma ), blueOffset ),
        new Vector4( rgbAmount, rgbSteps * rgbStepsMultiplier,  Mathf.Pow( 5f,rgbGamma ), rgbOffset ),

        new Vector4( hueAmount, hueSteps * hueStepsMultiplier,  Mathf.Pow( 5f,hueGamma), hueOffset ),
        new Vector4( saturationAmount, saturationSteps * saturationStepsMultiplier,  Mathf.Pow( 5f,saturationGamma), saturationOffset ),
        new Vector4( luminanceAmount, luminanceSteps * luminanceStepsMultiplier,  Mathf.Pow( 5f,luminanceGamma), luminanceOffset ),

        new Vector4( amount, (int) hslConversionMode, 0f, 0f )
      );
    }

   
  }
}