// © 2024 Long Ly. All rights reserved. Any unauthorized use, reproduction, or distribution of this trademark is strictly prohibited and may result in legal action.


#include "Data/OLSAnimationData.h"

#include "Data/OLSEnumLibrary.h"

UAnimSequence* FOLSTurnInPlaceAnimSet::GetTurnInPlaceAnimationByDirection(const float direction) const
{
	if (FMath::Abs(direction) < 130.f)
	{
		return (direction > 0) ? TurnInPlace_90_R : TurnInPlace_90_L;
	}
	return (direction > 0) ? TurnInPlace_180_R : TurnInPlace_180_L;
}

bool FOLSIdleAnimSet::HasAnyIdleBreaks() const
{
	return !IdleBreaks.IsEmpty();
}

UAnimSequence* FOLSIdleAnimSet::GetIdleAnimation(const bool isAiming) const
{
	return (isAiming ? IdleADS : Idle);
}

UAnimSequence* FOLSIdleAnimSet::GetRandomIdleBreakAnimation() const
{
	if (!HasAnyIdleBreaks())
	{
		return nullptr;
	}

	const int32 idleBreaksNum = IdleBreaks.Num();
	return IdleBreaks[FMath::RandRange(0, idleBreaksNum - 1)];
}

UAnimSequence* FOLSIdleAndTurnInPlaceAnimSet::GetIdleEntryAnimation() const
{
	return IdleAnimSet.IdleEntry;
}

UAnimSequence* FOLSIdleAndTurnInPlaceAnimSet::GetIdleAnimation(const bool isAiming) const
{
	return IdleAnimSet.GetIdleAnimation(isAiming);
}

UAnimSequence* FOLSIdleAndTurnInPlaceAnimSet::GetRandomIdleBreakAnimation() const
{
	return IdleAnimSet.GetRandomIdleBreakAnimation();
}

UAnimSequence* FOLSIdleAndTurnInPlaceAnimSet::GetTurnInPlaceAnimation(const float direction) const
{
	return TurnInPlaceAnimSet.GetTurnInPlaceAnimationByDirection(direction);
}

bool FOLSIdleAndTurnInPlaceAnimSet::CanPlayIdleBreakAnimation() const
{
	return IdleAnimSet.HasAnyIdleBreaks();
}

UAnimSequence* FOLSMovementAnimSet::GetMovementAnimationByCardinalDirection(const EOLSCardinalDirection& direction) const
{
	TObjectPtr<UAnimSequence> result = nullptr;
	switch (direction)
	{
	case EOLSCardinalDirection::EForward:
		result = Forward;
		break;
	case EOLSCardinalDirection::EBackward:
		result = Backward;
		break;
	case EOLSCardinalDirection::ERight:
		result = Right;
		break;
	case EOLSCardinalDirection::ELeft:
		result = Left;
		break;
	}

	return result;
}

UAnimSequence* FOLSMovementAnimSet_ForwardFacing::GetBackwardLeftRightByAngle(const float angle) const
{
	return (angle > 0.f) ? Backward_R : Backward_L;
}

UAnimSequence* FOLSMovementAnimSet_ForwardFacing::GetMovementAnimationByAngle(const EOLSCardinalDirection direction, const float angle) const
{
	TObjectPtr<UAnimSequence> result = nullptr;

	switch (direction)
	{
	case EOLSCardinalDirection::EForward:
		result = Forward;
		break;
	case EOLSCardinalDirection::ELeft:
		result = Left;
		break;
	case EOLSCardinalDirection::ERight:
		result = Right;
		break;
	case EOLSCardinalDirection::EBackward:
		result = GetBackwardLeftRightByAngle(angle);
		break;
	}

	return result;
}

void FOLSGaitAnimSet::GetPlayRateByLocomotionState(const EOLSLocomotionStatePlayRate& state, FVector2D& outPlayRate) const
{
	switch (state)
	{
	case EOLSLocomotionStatePlayRate::EStart:
		outPlayRate = PlayRate_Start;
		break;
	case EOLSLocomotionStatePlayRate::ECycle:
		outPlayRate = PlayRate_Cycle;
		break;
	case EOLSLocomotionStatePlayRate::EPivot:
		outPlayRate = PlayRate_Pivot;
		break;
	}
}

const FOLSMovementAnimSet& FOLSGaitAnimSet_CameraFacing::GetStartCycleFromHipDirection(
	const EOLSHipDirection hipDirection) const
{
	return (hipDirection == EOLSHipDirection::EForward) ? StartCycle_HipForward : StartCycle_HipBackward;
}

const FOLSMovementAnimSet& FOLSGaitAnimSet_CameraFacing::GetCycleFromHipDirection(
	const EOLSHipDirection hipDirection) const
{
	return (hipDirection == EOLSHipDirection::EForward) ? Cycle_HipForward : Cycle_HipBackward;
}

const FOLSMovementAnimSet& FOLSGaitAnimSet_CameraFacing::GetPivotFromHipDirection(
	const EOLSHipDirection hipDirection) const
{
	return (hipDirection == EOLSHipDirection::EForward) ? Pivot_HipForward : Pivot_HipBackward;
}

const FOLSMovementAnimSet& FOLSGaitAnimSet_CameraFacing::GetStopCycleFromHipDirection(
	const EOLSHipDirection hipDirection) const
{
	return (hipDirection == EOLSHipDirection::EForward) ? StopCycle_HipForward : StopCycle_HipBackward;
}

UAnimSequence* FOLSStanceAnimSets::GetIdleAnimation(const bool isAiming) const
{
	return IdleAndTurnInPlaceAnimSet.GetIdleAnimation(isAiming);
}

UAnimSequence* FOLSStanceAnimSets::GetIdleEntryAnimation() const
{
	return IdleAndTurnInPlaceAnimSet.GetIdleEntryAnimation();
}

UAnimSequence* FOLSStanceAnimSets::GetRandomIdleBreakAnimation() const
{
	return IdleAndTurnInPlaceAnimSet.GetRandomIdleBreakAnimation();
}

bool FOLSStanceAnimSets::CanPlayIdleBreakAnimation() const
{
	return IdleAndTurnInPlaceAnimSet.CanPlayIdleBreakAnimation();
}

UAnimSequence* FOLSStanceAnimSets::GetTurnInPlaceAnimation(const float direction) const
{
	return IdleAndTurnInPlaceAnimSet.GetTurnInPlaceAnimation(direction);
}

const FOLSGaitAnimSets* FOLSStanceAnimSets::SelectGaitAnimSetByGait(const EOLSGait& gait) const
{
	return GaitAnimSets.Find(gait);
}

const FVector2D& FOLSRootYawOffsetClamp::GetRootYawOffsetClamp(const EOLSStance stance) const
{
	return (stance == EOLSStance::EStanding ? RootYawOffsetClamp_Standing : RootYawOffsetClamp_Crouching);
}

const FOLSRootYawOffsetClamp& FOLSRootYawOffsetClamps::GetRootYawOffsetClamp(const EOLSRotationMode& rotationMode) const
{
	return RootYawOffsetClamps.FindChecked(rotationMode);
}
