#pragma once

#include "CoreMinimal.h"
#include "GameFramework/CharacterMovementComponent.h"
#include "PerPlatformProperties.h"
#include "UObject/NoExportTypes.h"
#include "StateStackContainer.h"
#include "EMovementCurveType.h"
#include "Engine/NetSerialization.h"
#include "YawAndPitchRotator_NetQuantize32.h"
#include "DBDCharacterMovementComponent.generated.h"

class UCurveFloat;
class UBaseCharacterVelocityCalculationStrategy;
class UBaseInputAccelerationConstraintStrategy;
class UBaseCharacterRotationStrategy;
class AActor;

UCLASS(Blueprintable, meta=(BlueprintSpawnableComponent))
class DEADBYDAYLIGHT_API UDBDCharacterMovementComponent : public UCharacterMovementComponent
{
	GENERATED_BODY()

public:
	UPROPERTY(EditAnywhere, BlueprintReadWrite)
	float ProjectedWallSlidingFactor;

	UPROPERTY(EditAnywhere, BlueprintReadWrite)
	float RandomInputFrontMultiplier;

	UPROPERTY(EditAnywhere, BlueprintReadWrite)
	float RandomInputSideMultiplier;

	UPROPERTY(EditAnywhere, BlueprintReadWrite)
	float RandomInputBackMultiplier;

protected:
	UPROPERTY(EditAnywhere, BlueprintReadWrite)
	float _lowHeightDropStaggerThreshold;

	UPROPERTY(EditAnywhere, BlueprintReadWrite)
	float _minDropStaggerDurationTime;

	UPROPERTY(EditAnywhere, BlueprintReadWrite)
	float _highHeightDropStaggerThreshold;

	UPROPERTY(EditAnywhere, BlueprintReadWrite)
	float _maxDropStaggerDurationTime;

private:
	UPROPERTY(EditAnywhere)
	FPerPlatformFloat _significanceThresholdForSmoothUpdateVisualOptimization;

	UPROPERTY(EditAnywhere)
	FPerPlatformFloat _significanceThresholdForSimulatedMovementPrediction;

	UPROPERTY(EditAnywhere)
	FPerPlatformInt _significanceMaxRefreshRateForSmoothUpdateVisualOptimization;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, meta=(AllowPrivateAccess=true))
	bool _forceUseDropStaggerFix;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Transient, meta=(AllowPrivateAccess=true))
	TArray<UCurveFloat*> _maxSpeedMultiplierCurvesToRemoveOnTheServer;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Transient, Export, meta=(AllowPrivateAccess=true))
	UBaseCharacterVelocityCalculationStrategy* _velocityAdditiveStrategy;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Transient, Export, meta=(AllowPrivateAccess=true))
	UBaseInputAccelerationConstraintStrategy* _inputAccelerationConstraintStrategy;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Transient, Export, meta=(AllowPrivateAccess=true))
	UBaseCharacterRotationStrategy* _rotationStrategy;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Transient, meta=(AllowPrivateAccess=true))
	AActor* _lookAtTarget;

private:
	UFUNCTION(BlueprintCallable, Server, Reliable)
	void Server_UpdateCameraRotation(float timestamp, const FRotator& cameraRotation, int32 updateCameraRotationCallCount);

	UFUNCTION(BlueprintCallable, Server, Reliable)
	void Server_SetStateStack(float timestamp, const TArray<FStateStackContainer>& stateStackContainers, int32 stateStackCallCount);

	UFUNCTION(BlueprintCallable, Server, Reliable)
	void Server_SetMaxAcceleration(float timestamp, float value);

protected:
	UFUNCTION(Server, Reliable)
	void Server_ReplicateControlRotation(uint8 clientRoll, uint32 view);

private:
	UFUNCTION(Server, Reliable)
	void Server_RemoveMaxSpeedMovementCurve(float timestamp, const uint32 curveNetId, const EMovementCurveType movementCurveType);

	UFUNCTION(Server, Reliable, WithValidation)
	void Server_MovementTimeSync(uint64 clientTimeSync, uint32 minStackDepth, bool isInGameThreadOnly);

	UFUNCTION(BlueprintCallable, Server, Reliable)
	void Server_Launch(float timestamp, FVector launchVelocity, int32 launchCallCount);

	UFUNCTION(Server, Reliable)
	void Server_AddMaxSpeedMovementCurve(float timestamp, const uint32 curveNetId, float duration, float startOffset, const EMovementCurveType movementCurveType, bool isAutoRemoveOnExpiration);

protected:
	UFUNCTION(BlueprintCallable, Client, Reliable)
	void Client_TeleportTo(FVector_NetQuantize100 location, FYawAndPitchRotator_NetQuantize32 rotation);

	UFUNCTION(BlueprintCallable, Client, Reliable)
	void Client_Stop();

	UFUNCTION(BlueprintCallable, Client, Reliable)
	void Client_PreventMovement(const bool value);

public:
	UFUNCTION(BlueprintCallable, Client, Reliable)
	void Client_Cheat_SetMaxSpeedMultiplier(const float maxSpeedMultiplier);

public:
	UDBDCharacterMovementComponent();
};

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