#[compute]
#version 450

#include "res://addons/rokojori_action_library/Runtime/Shading/Library/Colors.gdshaderinc"

layout( local_size_x = 8, local_size_y = 8, local_size_z = 1 ) in;

layout( rgba16f, set = 0, binding = 0 ) 
uniform image2D inputImage;
layout( rgba16f, set = 1, binding = 0 ) 
uniform image2D outputImage;

layout( set = 2, binding = 0 ) 
uniform sampler2D curves;


layout( push_constant, std430 ) 
uniform Parameters 
{
  float amount;
  float driverChannel;
  float targetChannel;
  float pad;

  float p0;
  float p1;
  float p2;
  float p3;

} parameters;


void main( ) 
{
  ivec2 size = imageSize( inputImage );
  ivec2 xy = ivec2( gl_GlobalInvocationID.xy );
  
  if ( any( greaterThanEqual( xy, size ) )  ) 
  {
    return;
  }

  vec2 uv = ( vec2( xy ) + 0.5 ) / vec2( size );    

  vec4 color = imageLoad( inputImage, ivec2( uv * size ) ); 

  vec4 processedColor = color;
  float scale = getRGBScale( color );

  int driver = int( round( parameters.driverChannel ) );
  int target = int( round( parameters.targetChannel ) );

  bool driverIsHSL = false;
  
  vec4 driverColor = color;

  if ( driver >= 3 )
  {
    driver -= 3;
    driverColor = RGBtoHSL( color, scale );
    driverIsHSL = true;
  }

  float driverValue = getRGBByIndex( driverColor.rgb, driver );
 
  float offset = texture( curves, vec2( driverValue, 0 ) ).r * 2.0 - 1.0;

  if ( target >= 3 )
  {
    processedColor = RGBtoHSL( color, scale );
 
    if ( target == 6 )
    {
      processedColor.r = changeTemparature( processedColor.r, offset, 30 );
    }
    else
    {
      processedColor.rgb = changeRGBByIndex( processedColor.rgb, target - 3, offset );
    }    
    
    processedColor = HSLtoRGB( processedColor, scale );
  }
  else
  {
    processedColor.rgb = changeRGBByIndex( processedColor.rgb, target, offset );
  }
  

  vec4 blended = mix( color, processedColor, parameters.amount );

  imageStore( outputImage, xy, blended );
}