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

namespace Rokojori
{ 
  [Tool]
  [GlobalClass]
  public partial class SpatialShaderGenerator:ShaderGenerator
  { 
    [Export]
    public TransparencyModule transparency = new TransparencyModule();

    [Export]
    public ShadingModule shading = new ShadingModule();

    [Export]
    public VertexModule vertex = new VertexModule();

    [Export]
    public UVModule uv = new UVModule();

    [Export]
    public AlbedoModule albedo = new AlbedoModule();


    public override List<ShaderPhase> GetPhases()
    {
      return new List<ShaderPhase>()
      {
        ShaderPhase.Header,
        ShaderPhase.RenderMode,
        ShaderPhase.Includes,
        ShaderPhase.Variables,
        ShaderPhase.Functions,
        ShaderPhase.Vertex,
        ShaderPhase.Fragment,
        ShaderPhase.Light
      };
    }

    public override List<ShaderGenerationModule> GetShaderGenerationModules( ShaderPhase phase )
    {
      if ( ShaderPhase.Header == phase )
      {
        return
        [
          new ShaderRawModule( "\n\nshader_type spatial;\n" )
        ];
      }

      if ( ShaderPhase.RenderMode == phase )
      {
        return 
        [
          new ShaderRawModule( "render_mode " ),
          transparency,
          new ShaderRawModule( ", " ),
          shading,
          new ShaderRawModule( ";\n\n" ),
        ];
      }

      if ( ShaderPhase.Includes == phase || ShaderPhase.Variables == phase || ShaderPhase.Functions == phase )
      {
        return 
        [         
          transparency,
          shading,
          vertex,
          uv,
          albedo
        ];
      }

      if ( ShaderPhase.Vertex == phase )
      {
        return new List<ShaderGenerationModule>()
        {
          new ShaderRawModule( "\nvoid vertex()\n{\n\n" )
        }
        .Concat
        (
          uv, vertex, albedo
        )
        .Concat
        (
          new ShaderRawModule( "\n}\n" )
        );
      }

      if ( ShaderPhase.Fragment == phase )
      {
        return new List<ShaderGenerationModule>()
        {
          new ShaderRawModule( "\nvoid fragment()\n{\n\n" ) 
        }
        .Concat
        (
          uv, vertex, albedo
        )
        .Concat
        (
          new ShaderRawModule( "\n}\n" )
        );
      }


      return null;

    }
  }
}