// Project Sword & Gun Copyright © 2021 Kevin Poretti

#pragma once

#include "CoreMinimal.h"

#include "Camera/CameraComponent.h"
#include "Characters/SNGCharacterBase.h"
#include "Components/SNGWeaponInventoryComponent.h"
#include "GameFramework/SpringArmComponent.h"

#include "SNGProtagonist.generated.h"

USTRUCT(BlueprintType)
struct FMeleeAttackData
{
	GENERATED_BODY()

	UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category="Animation")
	UAnimMontage* AttackMontage;

	UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category="Motion")
	UCurveVector* RootMotionCurve;
};

/**
 * 
 */
UCLASS()
class SWORDNGUN_API ASNGProtagonist : public ASNGCharacterBase
{
	GENERATED_BODY()

public:
	ASNGProtagonist();

	void MoveForward(float Value);

	void MoveRight(float Value);

	UFUNCTION(BlueprintCallable)
	void DoJump();

	UFUNCTION(BlueprintCallable)
	float MeleeAttack(FMeleeAttackData MeleeAttackData);

	UFUNCTION(BlueprintGetter)
	bool IsMeleeAttackComboReset();

	UFUNCTION(BlueprintCallable)
	void SetMeleeAttackCombo(bool IsComboReset);

	UFUNCTION(BlueprintGetter)
	bool DoesMovementInputCancelAnimMontage();

	UFUNCTION(BlueprintCallable)
	void SetDoesMovementInputCancelAnimMontage(bool DoesMovementCancelMontage);

	UFUNCTION(BlueprintCallable)
	void CycleRangedWeapon();

	UFUNCTION(BlueprintCallable)
    void CycleMeleeWeapon();
	
	void EquipWeapon(ASNGWeaponBase* WeaponToEquip, FName HandSocket);
	
	virtual ASNGWeaponBase* GetCurrentWeapon_Implementation() override;
	
protected:
	UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category="Components")
	UCameraComponent* CameraComponent;

	UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category="Components")
	USpringArmComponent* SpringArmComponent;
	
	UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category="Components")
	USNGWeaponInventoryComponent* WeaponInventoryComponent;

	UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category="Sockets")
	FName GunHandSocket;

	UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category="Sockets")
	FName SwordHandSocket;

	UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category="Soft Lock")
	float SoftLockHalfAngle;

	UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category="Soft Lock")
	float SoftLockRange;

	UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category="Soft Lock")
	int NumSoftLockLineTraces;

	UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category="Rotate Towards Target")
	float DegreesPerSecond;
	
	UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category="Rotate Towards Target")
	float MaxRotation;
	
	TArray<AActor*> SoftLockedActors;

	AActor* ClosestActor;
	float DistFromClosestActor;
	float AngleFromClosestActor;
	
	/**
	 * NOTE(kevin): Are these still being used anymore?
	 */
	float LastForwardAxis;
	float LastRightAxis;
	
	UPROPERTY(BlueprintReadWrite)
	bool bIsMeleeAttackComboReset;

	UPROPERTY(BlueprintReadWrite)
	bool bDoesMovementInputCancelAnimMontage;

	//UFUNCTION(BlueprintCallable)
	//FVector GetInputAsWorldDirection(float ForwardAxisValue, float RightAxisValue);

	void GetClosestSoftLockedActor();
	
	virtual FVector GetPawnViewLocation() const override;
	
	virtual void BeginPlay() override;
	
	virtual void Tick(float DeltaSeconds) override;
};
