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

namespace Rokojori
{ 
  [Tool]
  [GlobalClass]
  public partial class EmissionModule:TextureModule
  { 
    
    public EmissionModule()
    {
      _domainName = "emission";
      _domainScaleName = "emission";
      _domainIntensityName = "emissionIntensity";
      _domainValueName = "emission";

      _target = "EMISSION";
      _srgb = true;
      _type = TextureChannelType.RGB;
      scaleType = TextureChannelType.RGB;
    }

    [Export]
    public TextureFilter filter = TextureFilter.Linear_MipMap_Anisotropic;

    public enum EmissionMode
    {
      Texture,
      Texture_Tint,
      Texture_Tint_Intensity
    }

    [Export]
    public EmissionMode mode = EmissionMode.Texture_Tint_Intensity;

    [Export]
    public bool srgb = true;

    [Export]
    public bool repeat = true;

    [Export]
    public string uvChannel = "UV";

    [Export]
    public TextureDefault textureDefault = TextureDefault.Black;

    [Export]
    public AssignmentType assignmentType = AssignmentType.Set;   

    [Export]
    public EmissionOverlayLayer[] overlayLayers = [];
    
    public override void GrabValues()
    {
      _domainMode = EmissionMode.Texture == mode ? DomainMode.Texture : 
        EmissionMode.Texture_Tint == mode ? DomainMode.Texture_Scale : 
        DomainMode.Texture_Scale_Intensity;

      _textureFilter = filter;
      _srgb = srgb;
      _repeat = repeat;
      _textureDefault = textureDefault;
      _uvChannel = uvChannel;
      
      _assignmentType = assignmentType;
    }
    

    public override List<ShaderVariant> GetVariants( ShaderGenerationContext context )
    {
      var variants = base.GetVariants( context );

      if ( overlayLayers != null )
      {
        overlayLayers.ForEach(
          ( layer )=>
          {
            var layerName = "emission" + ( overlayLayers.IndexOf( layer ) + 2 );
            var uniformGroup = "emission" + ( overlayLayers.IndexOf( layer ) + 2 );
            layer.uniformGroup = uniformGroup; 
            var shaderCode = layer.GetOverlayCode( context, layerName, "EMISSION", "EMISSION" );

            if ( shaderCode == null )
            {
              return;
            }

            variants = ShaderVariant.CombineVariants( variants, ToVariants( shaderCode ) );
          }
        );
      }

      return variants;  

    }
  }
}