#pragma once

#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "GroundTargetPlacement.h"
#include "Engine/NetSerialization.h"
#include "K38GroundTarget.generated.h"

class USceneComponent;
class UStaticMeshComponent;
class UDBDOutlineComponent;
class UK38GroundTargetOutlineUpdateStrategy;
class UCurveFloat;

UCLASS(Blueprintable)
class AK38GroundTarget : public AActor
{
	GENERATED_BODY()

protected:
	UPROPERTY(EditAnywhere, BlueprintReadWrite)
	bool _growDeployDistanceBasedOnCharge;

	UPROPERTY(EditAnywhere, BlueprintReadWrite)
	float _minimumIndicatorVelocity;

	UPROPERTY(EditAnywhere, BlueprintReadWrite)
	float _indicatorVelocityEasingFactor;

	UPROPERTY(EditAnywhere, BlueprintReadWrite)
	FGroundTargetPlacement _targetPlacement;

	UPROPERTY(EditAnywhere, BlueprintReadWrite)
	TArray<float> _distancePercentLocations;

	UPROPERTY(EditAnywhere, BlueprintReadWrite)
	float _pitchLevelChangeAngleThreshold;

	UPROPERTY(EditAnywhere, BlueprintReadWrite)
	float _maximumCameraPitchOrientationAngle;

	UPROPERTY(EditAnywhere, BlueprintReadWrite)
	float _minimumCameraPitchOrientationAngle;

	UPROPERTY(EditAnywhere, BlueprintReadWrite)
	float _targetSlopeChangeThreshold;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Instanced)
	USceneComponent* _rootComponent;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Instanced)
	UStaticMeshComponent* _staticMeshComponent;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, NoClear, Instanced)
	UDBDOutlineComponent* _outlineComponent;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, NoClear, Instanced)
	UK38GroundTargetOutlineUpdateStrategy* _outlineUpdateStrategy;

private:
	UPROPERTY(EditAnywhere, BlueprintReadWrite, meta=(AllowPrivateAccess=true))
	UCurveFloat* _distancePercentScalingCurveFromPitch;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, meta=(AllowPrivateAccess=true))
	float _minimumTimeBeforeTargetLocationServerCall;

	UPROPERTY(EditInstanceOnly, BlueprintReadWrite, ReplicatedUsing=OnRep_Activated, Transient, meta=(AllowPrivateAccess=true))
	bool _isActivated;

	UPROPERTY(EditInstanceOnly, BlueprintReadWrite, ReplicatedUsing=OnRep_InMarkerVisibleToAllMode, Transient, meta=(AllowPrivateAccess=true))
	bool _isInMarkerVisibleToAllMode;

	UPROPERTY(EditInstanceOnly, BlueprintReadWrite, ReplicatedUsing=OnRep_HiddenWhileAimAssistArrowVisible, Transient, meta=(AllowPrivateAccess=true))
	bool _isHiddenWhileAimAssistArrowVisible;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, meta=(AllowPrivateAccess=true))
	float _groundTargetHideDelay;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, meta=(AllowPrivateAccess=true))
	float _largestMeshScale;

private:
	UFUNCTION(BlueprintCallable, Server, Unreliable)
	void Server_SetTargetLocation(FVector_NetQuantize targetLocation, bool isValidLocation);

	UFUNCTION(BlueprintCallable)
	void OnRep_InMarkerVisibleToAllMode();

	UFUNCTION(BlueprintCallable)
	void OnRep_HiddenWhileAimAssistArrowVisible();

	UFUNCTION(BlueprintCallable)
	void OnRep_Activated();

	UFUNCTION(BlueprintCallable)
	void OnLocallyObservedChanged(const bool isPlayerLocallyObserved);

	UFUNCTION(BlueprintCallable, NetMulticast, Unreliable)
	void Multicast_SetTargetLocation(FVector_NetQuantize targetLocation, bool isValidLocation);

public:
	UFUNCTION(BlueprintPure)
	float GetGroundTargetDistanceToKiller() const;

	UFUNCTION(BlueprintPure)
	float GetGroundTargetDistancePercentToKiller() const;

protected:
	UFUNCTION(BlueprintCallable, BlueprintImplementableEvent, BlueprintCosmetic)
	void Cosmetic_SetIsGroundTargetPositionValid(bool isGroundTargetPlacementValid);

	UFUNCTION(BlueprintCallable, BlueprintImplementableEvent, BlueprintCosmetic)
	void Cosmetic_OnGroundTargetVisibilityChanged(bool visible);

	UFUNCTION(BlueprintCallable, BlueprintImplementableEvent, BlueprintCosmetic)
	void Cosmetic_OnGroundTargetTooCloseToKillerToDeployChanged(bool tooCloseToKillerToDeploy);

public:
	virtual void GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const override;

public:
	AK38GroundTarget();
};

FORCEINLINE uint32 GetTypeHash(const AK38GroundTarget) { return 0; }
