
using System.Collections.Generic;
using Godot;
using Rokojori;

namespace Rokojori
{  
  [Tool]
  [GlobalClass, Icon("res://addons/rokojori_action_library/Icons/OnEvent.svg") ]
  public partial class OnCollision:Node
  {
    [Export]
    public Area3D area;

    [Export]
    public Selector selector;

    [Export]
    public Action onEntered;

    [Export]
    public Action onInside;

    [Export]
    public Action onExit;

    

    Dictionary<Node,System.Action> _inside = new Dictionary<Node,System.Action>();


    public override void _Ready()
    {
      if ( area == null )
      { 
        return;
      }

      area.AreaEntered += TriggerOnEnter;
      area.BodyEntered += TriggerOnEnter;

      area.AreaExited  += TriggerOnExited;
      area.BodyExited  += TriggerOnExited;
    }     

    void TriggerOnEnter( Node n )
    {
      if ( ! Math3D.IsValid( area.GlobalPosition ) )
      {
        return;
      } 

      if ( ! Selector.IsSelecting( selector, n ) )
      {
        
        return;
      }

      

      this.LogInfo( "Selecting Enter", area.GlobalPosition, HierarchyName.Of( n ), ( (Node3D)n ).GlobalPosition );
      Action.Trigger( onEntered );

      if ( onInside == null )
      {
        return;
      }

      var tm = Unique<TimeLineManager>.Get();

      if ( tm == null )
      {
        return;
      }
      
      var callback = ()=>{ Action.Trigger( onInside ); };
      _inside[ n ] = callback;
      tm.AddProcessCallback( callback );
      
    }

    void TriggerOnExited( Node n )
    {
      if ( ! Selector.IsSelecting( selector, n ) )
      {
        return;
      }

      Action.Trigger( onExit );

      if ( ! _inside.ContainsKey( n ) )
      {
        return;
      }

      var tm = Unique<TimeLineManager>.Get();

      if ( tm == null )
      {
        return;
      }
      
      var callback = _inside[ n ];
      tm.RemoveProcessCallback( callback );

      _inside.Remove( n );
    }
  }
}