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

namespace Rokojori
{
  public enum CollisionPhase
  {
    None,
    Entered,
    Inside,
    Exit
  }

  [Tool]
  [GlobalClass,Icon("res://addons/rokojori_action_library/Icons/Collidable.svg")]
  public partial class Collidable:Node3D
  {
    [Export]
    public CollisionFlag[] collisionTypes;

    [Export]
    public Action onEntered;

    [Export]
    public Node3D onEnteredColliderPose;

    [Export]
    public Action onInside;

    [Export]
    public Node3D onInsideColliderPose;

    [Export]
    public Action onExit;

    [Export]
    public Node3D onExitColliderPose;

    public bool IsCollidingWith( Collider collider )
    {
      if ( ( collisionTypes == null || collisionTypes.Length == 0 ) && collider.collisionType == null )
      {
        return true;
      }

      if ( collisionTypes == null )
      {
        return false;
      }

      return collisionTypes.IndexOf( collider.collisionType ) != -1;
    }

    Collider _collider;
    CollisionPhase _collisionPhase;

    public Collider collider => _collider;
    public CollisionPhase collisionPhase => _collisionPhase;

    
    public void Collide( Collider collider, CollisionPhase phase )
    {
      // this.LogInfo( "Colliding with", phase, HierarchyName.Of( collider ) );

      _collider = collider;
      _collisionPhase = phase;

      _Collide( collider, phase );

      if ( phase == CollisionPhase.Entered )
      { 
        // this.LogInfo( "Entered", HierarchyName.Of( collider ) );

        if ( onEnteredColliderPose != null )
        {
          onEnteredColliderPose.CopyGlobalPoseFrom( collider.area );
        }

        Action.Trigger( collider.onEntered );
        Action.Trigger( onEntered );
      }
      else if ( phase == CollisionPhase.Inside )
      { 
        // this.LogInfo( "Inside", HierarchyName.Of( collider ) );

        if ( onInsideColliderPose != null )
        {
          onInsideColliderPose.CopyGlobalPoseFrom( collider.area );
        }

        Action.Trigger( collider.onInside );
        Action.Trigger( onInside );
      }
      else if ( phase == CollisionPhase.Exit )
      { 
        // this.LogInfo( "Exit", HierarchyName.Of( collider ) );

        if ( onExitColliderPose != null )
        {
          onExitColliderPose.CopyGlobalPoseFrom( collider.area );
        }

        Action.Trigger( collider.onExit );
        Action.Trigger( onExit );
      }

      _collider = null;
      _collisionPhase = CollisionPhase.None;
    }

    protected virtual void _Collide( Collider collider, CollisionPhase phase )
    {

    }
  }
}