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

namespace Rokojori
{ 
  [Tool]
  [GlobalClass]
  public partial class ShadingModule:ShaderGenerationModule
  { 
    [Export]
    public BaseMaterial3D.ShadingModeEnum shadingMode = BaseMaterial3D.ShadingModeEnum.PerPixel;

    [Export]
    public BaseMaterial3D.DiffuseModeEnum diffuseMode = BaseMaterial3D.DiffuseModeEnum.Burley;

    [Export]
    public BaseMaterial3D.SpecularModeEnum specularMode = BaseMaterial3D.SpecularModeEnum.SchlickGgx;

    [Export]
    public bool disableAmbientLight = false;

    [Export]
    public bool disableFog = false;

    [Export]
    public bool disableReceivingShadows = false;

    [Export]
    public bool shadowToOpacity = false;

    [Export]
    public bool wireFrameMode = false;

    public override List<ShaderVariant> GetVariants( ShaderGenerationContext context )
    {
      if ( ShaderPhase.RenderMode != context.phase )
      {
        return null;
      }
      
      var value = "";

      var shadingModes = new Dictionary<BaseMaterial3D.ShadingModeEnum,string>();
      shadingModes[ BaseMaterial3D.ShadingModeEnum.PerPixel ] = "";
      shadingModes[ BaseMaterial3D.ShadingModeEnum.PerVertex ] = "vertex_lighting, ";
      shadingModes[ BaseMaterial3D.ShadingModeEnum.Unshaded ] = "unshaded, ";

      value += shadingModes[ shadingMode ];
      

      var diffuseModes = new Dictionary<BaseMaterial3D.DiffuseModeEnum,string>();
      diffuseModes[ BaseMaterial3D.DiffuseModeEnum.Burley ] = "diffuse_burley";
      diffuseModes[ BaseMaterial3D.DiffuseModeEnum.Lambert] = "diffuse_lambert";
      diffuseModes[ BaseMaterial3D.DiffuseModeEnum.LambertWrap] = "diffuse_lambert_wrap";
      diffuseModes[ BaseMaterial3D.DiffuseModeEnum.Toon ] = "diffuse_toon";     

      value += diffuseModes[ diffuseMode ] + ", ";

      var specularModes = new Dictionary<BaseMaterial3D.SpecularModeEnum,string>();
      specularModes[ BaseMaterial3D.SpecularModeEnum.SchlickGgx ] = "specular_schlick_ggx";
      specularModes[ BaseMaterial3D.SpecularModeEnum.Toon ] = "specular_toon";
      specularModes[ BaseMaterial3D.SpecularModeEnum.Disabled ] = "specular_disabled";

      value += specularModes[ specularMode ] + ", ";

      if ( disableAmbientLight )
      {
        value += "ambient_light_disabled, ";
      }

      if ( disableFog )
      {
        value += "fog_disabled, ";
      }

      if ( disableReceivingShadows )
      {
        value += "shadows_disabled, ";
      }

      if ( disableReceivingShadows )
      {
        value += "shadow_to_opacity, ";
      }

      if ( wireFrameMode )
      {
        value += "wireframe";
      }

      value = RegexUtility.Replace( value, @"\,\s*$", "" );

      return ToVariants( ToCode( value ) ) ;      
    }

  }

}