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

namespace Rokojori
{ 
  [Tool]
  [GlobalClass]
  public partial class UVScaleOffset:UVModifier
  {   
    [Export]
    public bool uvScale = true;

    [Export]
    public bool uvUniScale = false;

    [Export]
    public bool uvOffset = true;

    [Export]
    public bool uvScrolling = true;

    
    public override List<ShaderCode> ModifyUV( ShaderGenerationContext context, string uvTarget )
    {
      var uvScale = ! this.uvScale ? null : Vector2Property.Create( uvTarget + "_scale", Vector2.One );
      var uvUniScale = ! this.uvUniScale ? null : FloatProperty.Create( uvTarget + "_scaleAll", 1f );
      var uvOffset = ! this.uvOffset ? null : Vector2Property.Create( uvTarget + "_offset", Vector2.Zero );
      var uvScrolling = ! this.uvScrolling ? null : Vector2Property.Create( uvTarget + "_scrolling", Vector2.Zero );

      if ( ShaderPhase.Variables == context.phase )
      {        
        var lines = new List<string>();


        Lists.From<ShaderProperty>( uvScale, uvUniScale, uvOffset, uvScrolling ).FilterNulls().ForEach(
          ( p )=>
          {
            lines.Add( UniformFor( p ) + "\n" );
          }
        );    


        return AsUniformGroup( uvTarget, lines.Join( "" ) );
           
      }

      if ( ShaderPhase.Vertex == context.phase )
      {        
        var expression = uvTarget + " = " + uvTarget; 

        if ( uvScale != null )
        {
          expression += " * " + uvScale.name;
        }

        if ( uvUniScale != null )
        {
          expression += " * " + uvUniScale.name;
        }

        if ( uvOffset != null )
        {
          expression += " + " + uvOffset.name;
        }

        if ( uvScrolling != null )
        { 
          expression += " + TIME * " + uvScrolling.name;
        }

        expression += ";\n";

        return ToUnsortableCode( expression.Indent( "  " ) );
           
      }

      return null;
    }
  }
}