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

#pragma once

#include "CoreMinimal.h"
#include "Components/ActorComponent.h"
#include "MoALiveLinkPropComponent.generated.h"

class ILiveLinkClient;

UCLASS(ClassGroup = (MoA), meta = (BlueprintSpawnableComponent))
class MOALIVELINK_API UMoALiveLinkPropComponent : public UActorComponent
{
	GENERATED_BODY()

public:
	UMoALiveLinkPropComponent();

	virtual void TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) override;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "MoA LiveLink", meta = (GetOptions = "GetAvailableSubjectNames"))
	FName SubjectName;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "MoA LiveLink")
	bool bApplyPosition = true;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "MoA LiveLink")
	bool bApplyRotation = true;

	bool bConvertCoordinateSystem = true;

	// Enable position scaling
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "MoA LiveLink|Position Scale")
	bool bUsePositionScale = false;

	// Position scale to apply (X=Forward/Back, Y=Left/Right, Z=Up/Down)
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "MoA LiveLink|Position Scale", meta = (EditCondition = "bUsePositionScale"))
	FVector ManualPositionScale = FVector(1.0f, 1.0f, 1.0f);

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "MoA LiveLink|Visualization")
	bool bEnableVisualization = false;

	UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "MoA LiveLink|Visualization")
	FVector PropSize = FVector(1.0f, 1.0f, 1.0f);

	UFUNCTION(BlueprintCallable, Category = "MoA LiveLink")
	bool IsReceivingData() const;

	UFUNCTION(BlueprintCallable, Category = "MoA LiveLink")
	int32 GetPropType() const { return LastPropType; }

	UFUNCTION(BlueprintCallable, Category = "MoA LiveLink")
	void SetSubjectByNameAndNum(const FString& PropName, int32 PropNum);

	UFUNCTION(BlueprintCallable, Category = "MoA LiveLink")
	void CalibrateVisualization(int32 PropType, float Width, float Height, float Depth);

	UFUNCTION(BlueprintCallable, Category = "MoA LiveLink")
	void UpdateVisualizationMesh();

	UFUNCTION()
	TArray<FString> GetAvailableSubjectNames() const;

	UFUNCTION(BlueprintCallable, Category = "MoA LiveLink")
	void RefreshSubjectList();

protected:
	virtual void BeginPlay() override;
	virtual void EndPlay(const EEndPlayReason::Type EndPlayReason) override;

#if WITH_EDITOR
	virtual void PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent) override;
#endif

private:
	FVector ConvertPosition(const FVector& SourcePosition) const;
	FQuat ConvertRotation(const FQuat& SourceRotation) const;

	double LastDataReceivedTime = 0.0;
	int32 LastPropType = 0;
	ILiveLinkClient* LiveLinkClient = nullptr;

	UPROPERTY()
	AActor* VisualizationActor = nullptr;

	UPROPERTY()
	class UStaticMesh* CubeMeshAsset = nullptr;

	UPROPERTY()
	class UStaticMesh* SphereMeshAsset = nullptr;

	void CreateCubeMesh();
	void CreateSphereMesh();
};

