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

#include "VectorLibrary.h"

FVector UVectorLibrary::GetDeltaVector(FVector Source, FVector Target)
{
	FVector DeltaVector = Target - Source;
	DeltaVector.Normalize();
	return DeltaVector;
}

float UVectorLibrary::GetDeltaAngle(FVector First, FVector Second)
{
	if (First.Size() == 0.0f || Second.Size() == 0.0f)
	{
		return 0.0f;
	}

	float DotProduct = First | Second;
	float CosineOfAngle = DotProduct / (First.Size() * Second.Size());
	return FMath::Acos(CosineOfAngle);
}

bool UVectorLibrary::AreFacingSameDirection(FVector First, FVector Second, float Tolerance)
{
	float Angle = GetDeltaAngle(First, Second);
	Tolerance = Tolerance < 0.0f ? 0.0f : Tolerance;
	return Angle >= 0.0f && Angle <= Tolerance;
}

bool UVectorLibrary::AreFacingSameDirection2D(FVector First, FVector Second, EPlane2D Plane, float Tolerance)
{
	return AreFacingSameDirection(FlattenVector(First, Plane), FlattenVector(Second, Plane), Tolerance);
}

bool UVectorLibrary::AreOverlapping(FVector First, FVector Second)
{
	FVector CrossProduct = First ^ Second;
	return CrossProduct.Size() == 0.0f;
}

bool UVectorLibrary::AreOverlapping2D(FVector First, FVector Second, EPlane2D Plane)
{
	return AreOverlapping(FlattenVector(First, Plane), FlattenVector(Second, Plane));
}

bool UVectorLibrary::IsRightOfVector2D(FVector First, FVector Second, EPlane2D Plane)
{
	FVector CrossProduct = FlattenVector(First, Plane) ^ FlattenVector(Second, Plane);

	switch (Plane)
	{
	case EPlane2D::XY:
		return CrossProduct.Z > 0;
	case EPlane2D::XZ:
		return CrossProduct.Y > 0;
	case EPlane2D::YZ:
	default:
		return CrossProduct.X > 0;
	}
}

FVector UVectorLibrary::FlattenVector(FVector Vector, EPlane2D Plane)
{
	FVector FlattenedVector = Vector;

	switch (Plane)
	{
	case EPlane2D::XY:
		FlattenedVector.Z = 0.0f;
		break;
	case EPlane2D::XZ:
		FlattenedVector.Y = 0.0f;
		break;
	case EPlane2D::YZ:
	default:
		FlattenedVector.X = 0.0f;
		break;
	}

	return FlattenedVector;
}
