using Godot;
using System.Collections.Generic;

namespace Rokojori
{ 
  [Tool]
  [GlobalClass, Icon("res://addons/rokojori_action_library/Icons/FlareVFX.svg") ]
  public partial class FlareVFX:Node3D
  {
    [Export]
    public FlarePreset preset;

    public Node3D GetContainer()
    {
      return this;
    }

    #if TOOLS
    [Export]
    public bool editMode = false;

    public override void _Process( double delta )
    {
      if ( editMode )
      {
        UpdateFlare();
      }

    }
    #endif

    List<FlareLayer.Data> _layers = [];

    void UpdateFlare()
    {
      if ( preset == null )
      {
        return;
      }

      var numLayers = preset.layers.NonNullCount();

      if ( _layers == null || _layers.Count != numLayers )
      {        
        _layers = [];

        var meshInstances = this.GetDirectChildren<MeshInstance3D>();

        if ( meshInstances.Count != numLayers )
        {
          this.DestroyChildren();

          meshInstances = []; 

          var mIndex = 0;

          for ( int i = 0; i < preset.layers.Length; i++ )
          {
            if ( preset.layers[ i ] == null )
            {
              continue;
            } 

            var mi = this.CreateChild<MeshInstance3D>( "Layer " + i + " " + preset.layers[ i ].layerName );
            meshInstances.Add( mi );
            mIndex++;
          }
        }

        for ( int i = 0; i < preset.layers.Length; i++ )
        {
          if ( preset.layers[ i ] == null )
          {
            _layers.Add( null );
            continue;
          }

          var layer = preset.layers[ i ].Create( this );
          _layers.Add( layer );
          layer.meshInstance = meshInstances[ i ];
        }
      }

      var hasSolo = _layers.Find( l => l != null && l.layer.solo ) != null ;

      _layers.ForEach( 
        l => 
        { 
          if ( l == null )
          {
            return;
          }

          var isHidden = l.layer.hide || hasSolo && ! l.layer.solo;

          l.meshInstance.SetVisibility( ! isHidden );

          if ( isHidden )
          {
            return;
          }

          l.Update();
        }
      );
        
      
    }
  }
}