
using Godot;
using System.Collections.Generic;

namespace Rokojori
{  
  public class CompositorEffectShaderProcessor:CompositorEffectGraphProcessor
  {
    protected string _shaderPath;

    public CompositorEffectShaderProcessor( _XX_CompositorEffectGraph graph, string shaderPath ):base( graph )
    {
      this._shaderPath = shaderPath;
    }

    protected RDShader _shader;
    protected RDPipeline _pipeline;
    protected RDPushConstants _constants;
    public RDPushConstants constants => _constants;
    protected Vector3I _groupSize = new Vector3I( 8, 8, 0 );
    protected List<CompositorEffectGraphTextureSlot> _textureSlots = new List<CompositorEffectGraphTextureSlot>(); 
    
    protected override void OnInitialize()
    {
      graph.Verbose( "Trying to load shader: ", _shaderPath );

      if ( _shaderPath == null )
      {
        graph.Error( "_shaderPath == null" );
        return;
      }

      var glslFile = GD.Load<RDShaderFile>( _shaderPath );

      if ( glslFile == null )
      {
        graph.Error( "Couldn't load shader at path:", _shaderPath );
        return;
      }

      _shader = RDShader.CreateFromSpirV( graph, glslFile.GetSpirV() );      

      if ( _shader == null )
      {
        graph.Error( "Couldn't create shader from code, path:", _shaderPath );
        return;
      }

      _pipeline = RDPipeline.Create( graph, _shader );

      if ( _shader == null )
      {
        graph.Error( "Couldn't create pipeline from compiled shader, path:", _shaderPath );
        return;
      }
      
      graph.Verbose( "Created shader at path: ", _shaderPath );
    }
   
    public override void Process()
    {
      var context = graph.context;

      context.Clear();
      context.ComputeGroups( _groupSize );
      context.SetShaderAndPipeline( _shader, _pipeline );

      _textureSlots.ForEach( t => 
        { 
          t.ResolveTexture();
          graph.context.AssignUniformSet_Texture( t.GetTexture(), t.sampler ); 
        } 
      );
      

      context.pushConstants = _constants;

      context.Render();
    }
  }
}