// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "CoreMinimal.h"
#include "Kismet/BlueprintFunctionLibrary.h"
#include "VectorLibrary.generated.h"

/**
* An enumeration defining the three possible 2D planes.
*/
UENUM(BlueprintType)
enum class EPlane2D : uint8
{
	XY	UMETA(DisplayName = "XY"),
	XZ	UMETA(DisplayName = "XZ"),
	YZ	UMETA(DisplayName = "YZ")
};

/**
 * Utility library containing common operations with vectors.
 */
UCLASS()
class GAMEJAMTEMPLATE_API UVectorLibrary : public UBlueprintFunctionLibrary
{
	GENERATED_BODY()
	
public:

	/**
	* Gets a normalized vector going from the source towards the target vector.
	* @param Source The source vector in world space.
	* @param Target The target vector in world space.
	* @return The normalized delta vector.
	*/
	UFUNCTION(BlueprintCallable, Category = "Vector Library")
	static FVector GetDeltaVector(FVector Source, FVector Target);

	/**
	* Gets the angle between two vectors in degrees.
	* Always returns a positive number.
	* @param First The first vector.
	* @param Second The second vector.
	* @return The angle between the vectors.
	*/
	UFUNCTION(BlueprintCallable, Category = "Vector Library")
	static float GetDeltaAngle(FVector First, FVector Second);

	/**
	* Checks if two vectors are facing the same direction.
	* @param First The first vector.
	* @param Second The second vector.
	* @param Tolerance The tolerated angle between the vectors.
	* @return True if the vectors are pointing in the same direction, else false.
	*/
	UFUNCTION(BlueprintCallable, Category = "Vector Library")
	static bool AreFacingSameDirection(FVector First, FVector Second, float Tolerance = 45.0f);

	/**
	* Checks if two vectors are facing the same direction within a 2D plane.
	* Flatten the vectors' third axis before performing the equation.
	* @param First The first vector.
	* @param Second The second vector.
	* @param Plane The 2D plane in which to perform the equation.
	* @param Tolerance The tolerated angle between the vectors.
	* @return True if the vectors are pointing in the same direction, else false. 
	*/
	UFUNCTION(BlueprintCallable, Category = "Vector Library")
	static bool AreFacingSameDirection2D(FVector First, FVector Second, EPlane2D Plane, float Tolerance = 45.0f);

	/**
	* Checks if two vector are overlapping.
	* @param First The first vector.
	* @param Second The second vector.
	* @return True if the vectors are overlapping, else false.
	*/
	UFUNCTION(BlueprintCallable, Category = "Vector Library")
	static bool AreOverlapping(FVector First, FVector Second);

	/**
	* Checks if two vector are overlapping within a 2D plane.
	* Flatten the vectors' third axis before performing the equation.
	* @param First The first vector.
	* @param Second The second vector.
	* @return True if the vectors are overlapping, else false.
	*/
	UFUNCTION(BlueprintCallable, Category = "Vector Library")
	static bool AreOverlapping2D(FVector First, FVector Second, EPlane2D Plane);

	/*
	* Checks if the first specified vector is right of the second specified vector within a 2D plane.
	* Flatten the vectors' third axis before performing the equation.
	* @param First The first vector.
	* @param Second The second vector.
	* @return True if the first vector is right of the second vector, else false.
	*/
	UFUNCTION(BlueprintCallable, Category = "Vector Library")
	static bool IsRightOfVector2D(FVector First, FVector Second, EPlane2D Plane);

private:

	/**
	* Flattens a vector inside the specified 2D plane.
	* @param Vector The specified vector.
	* @param Plane The specified 2D plane.
	* @return The flattened vector.
	*/
	static FVector FlattenVector(FVector Vector, EPlane2D Plane);

};
