//======================================================================================================
// Company Name:       MotionTechnologies.inc
// Copyright Year:     2025
// File:               MoATposeCalculator.h
//======================================================================================================

#pragma once

#include "CoreMinimal.h"
#include "Animation/Skeleton.h"
#include "MoABoneMapping.h"

class MOALIVELINK_API FMoATposeCalculator
{
public:
	static TMap<FName, FQuat> CalculateTPoseDeltas(
		const USkeleton* TargetSkeleton,
		const USkeleton* TPoseReferenceSkeleton,
		const TArray<FMoABoneMappingRow>& BoneMappings);

	// Calculate Hip-to-FootBottom distance in T-Pose for height correction
	static float CalculateHipToFootBottomDistance(
		const USkeleton* Skeleton,
		const TArray<FMoABoneMappingRow>& BoneMappings);

	// Calculate world position of a bone in reference skeleton
	static FVector CalculateWorldPosition(const FReferenceSkeleton& RefSkeleton, int32 BoneIndex, bool bIgnoreRootRotation = false);

private:
	static FQuat CalculateWorldRotation(const FReferenceSkeleton& RefSkeleton, int32 BoneIndex, bool bIgnoreRootRotation = false);
	static FVector GetBoneDirection(
		const FReferenceSkeleton& RefSkeleton,
		int32 BoneIndex,
		EMoABoneName SourceBone,
		const TArray<FMoABoneMappingRow>& BoneMappings,
		bool bIgnoreRootRotation = false);
	static FVector GetBoneUp(EMoABoneName SourceBone, const FVector& Direction);
	static FVector GetUpHint(EMoABoneName SourceBone);
	static EMoABoneName GetChildBone(EMoABoneName SourceBone);
	static EMoABoneName GetParentBone(EMoABoneName SourceBone);
	static FName FindMappedBoneName(EMoABoneName SourceBone, const TArray<FMoABoneMappingRow>& BoneMappings);
	static FQuat CalculateBoneTPoseRotation(
		const FReferenceSkeleton& TargetRefSkeleton,
		const FReferenceSkeleton& TPoseRefSkeleton,
		int32 TargetBoneIndex,
		EMoABoneName SourceBone,
		const TArray<FMoABoneMappingRow>& BoneMappings);
	static bool ShouldSkipTPoseCalculation(EMoABoneName SourceBone);
	static const TArray<EMoABoneName>& GetTargetBones();
};
