using System.Collections;
using System.Collections.Generic;
using Godot;
using System;
using System.Threading.Tasks;



namespace Rokojori
{
  [Tool]
  [GlobalClass]
  public partial class AlbedoBakingPass: _XX_BakingPass
  {
    public AlbedoBakingPass():base(){}

    protected override void CreateBakingOutputs()
    {
      bakingOutputs = [ BakingOutput.Albedo() ];
    }

    protected override bool KeepsOriginalState()
    {
      return false;
    }

    protected override bool KeepsCompositors()
    {
      return true;
    }

    protected override async Task _Bake() 
    {
      Clear( BakingTargetType.Albedo );

      SetMaterial();

      await multiBaker.RequestNextFrame();

      var texture = await GrabDilatedTexture( true, true );

      Set( BakingTargetType.Albedo, texture );

      return;
    }

    public void SetMaterial()
    {
      Dictionary<Material,Material> materials = new Dictionary<Material, Material>();

      Nodes.ForEach<Node3D>( multiBaker.X_bakingTargetContainer,
        ( n )=>
        {
          SetMaterial( n, materials );
        }
      );
    }

    void SetMaterial( Node3D n, Dictionary<Material,Material> materials )
    {
      var material = Materials.Get<Material>( n );

      if ( material == null )
      {
        // n.LogInfo( "No material found" );
        return;
      }

      if ( ! materials.ContainsKey( material ) )
      {
        var appliedMaterial = new StandardMaterial3D();
      
        if ( material is StandardMaterial3D sm )
        {
          // n.LogInfo( "StandardMaterial3D found" );

          appliedMaterial.AlbedoColor   = sm.AlbedoColor;
          appliedMaterial.AlbedoTexture = sm.AlbedoTexture;

          appliedMaterial.Uv1Scale = sm.Uv1Scale;
          appliedMaterial.Uv1Offset = sm.Uv1Offset;

          
          appliedMaterial.Transparency = sm.Transparency;
          appliedMaterial.AlphaScissorThreshold = sm.AlphaScissorThreshold;
          appliedMaterial.AlphaAntialiasingMode = sm.AlphaAntialiasingMode;
          appliedMaterial.AlphaAntialiasingEdge = sm.AlphaAntialiasingEdge;

          appliedMaterial.ShadingMode = BaseMaterial3D.ShadingModeEnum.Unshaded;
        }
        else
        {
          // n.LogInfo( "No StandardMaterial3D found", material.GetType().Name );
        }

        
        materials[ material ] = appliedMaterial;
      }

      
      Materials.Set( n, materials[ material ] );
    }

  }
}