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

namespace Rokojori
{
  [Tool]
  [GlobalClass]
  public partial class StrafeMovementType:CharacterMovementType
  {
    public enum StrafeDirectionSource
    {
      Character_Movement_Direction_Source,
      Character_Controller_Body
    }

    [ExportGroup( "Movement" )]
    [Export]
    public Sensor forward;

    [Export]
    public Sensor backwards;
    
    [Export]
    public CharacterDirectionProcessing directionProcessing;    

    [ExportGroup( "Strafing" )]
    [Export]
    public float strafeSpeedMultiply = 1.0f;

    [Export]
    public Sensor strafeLeft;

    [Export]
    public Sensor strafeRight;   

    [Export]
    public StrafeDirectionSource strafeDirectionSource = StrafeDirectionSource.Character_Controller_Body;

    public override void ProcessMovement( CharacterMovementData characterMovementData )
    {
      var characterMovement = characterMovementData.characterMovement;
      var directionSource = characterMovement.directionSource;
      var body = characterMovement.body;

      var dir = directionSource != null ? directionSource : body;
      var forwardDirection = dir.GlobalForward();
      var rightDirection   = StrafeDirectionSource.Character_Controller_Body == strafeDirectionSource ? 
                             body.GlobalRight() : dir.GlobalRight();

      if ( CharacterDirectionProcessing.Zero_Y_And_Normalize == directionProcessing ) 
      {
        forwardDirection.Y = 0;
        rightDirection.Y = 0;        
      } 
      else if ( CharacterDirectionProcessing.Project_On_TransformPlane == directionProcessing ) 
      {
        var bodyPlane = Plane3.CreateFromNode3D( body );
        forwardDirection = bodyPlane.ConstrainToPlane( forwardDirection + body.GlobalPosition ) - body.GlobalPosition;
        rightDirection   = bodyPlane.ConstrainToPlane( rightDirection + body.GlobalPosition ) - body.GlobalPosition;
      }
     
      forwardDirection = forwardDirection.Normalized();
      rightDirection   = rightDirection.Normalized();

      var movement = forwardDirection * Sensors.PolarAxis( backwards, forward ) * characterMovement.moveSpeed;

      movement += rightDirection * Sensors.PolarAxis( strafeLeft, strafeRight ) * characterMovement.moveSpeed * strafeSpeedMultiply; 

      characterMovementData.movement = movement;
      characterMovementData.isMovingForward = forward.isActive;
      characterMovementData.forwardDirection = forwardDirection;


    }
  }
}