// Project Lab - NHTV Igad

#pragma once

#include "DealDamageProxy.h"
#include "ProjectileBase.generated.h"

/**
 * 
 */
UCLASS()
class UNREALPROJECT_API AProjectileBase : public ADealDamageProxy
{
	GENERATED_BODY()

public:
	AProjectileBase();
	virtual void BeginPlay() override;
	virtual void Tick(float DeltaSeconds) override;

	UFUNCTION(BlueprintNativeEvent, Category = "Projectile")
	void FixedProjectileTick(float DeltaTime);
	virtual void NativeFixedProjectileTick(float DeltaTime);

	UFUNCTION(BlueprintCallable, Category = "Projectile")
	void Move(float DeltaTime);
	virtual void NativeMove(float DeltaTime);

	UFUNCTION(BlueprintCallable, Category = "Projectile")
	bool IsFinished() const { return m_finished; }

	UFUNCTION(BlueprintNativeEvent, Category = "Projectile")
	void OnProjectileFinished();
	virtual void NativeOnProjectileFinished();

	UFUNCTION(BlueprintNativeEvent, Category = "Projectile")
	void OnProjectileHit(ANetworkCharacter* hitCharacter);
	virtual void NativeOnProjectileHit(ANetworkCharacter* hitCharacter);

	virtual void NativeServerOnFinish();
	UFUNCTION(BlueprintImplementableEvent, Category = "Project")
	void ServerOnFinish();

	// Transfers projectile to the finished state, disabling collision, but still updating ticks
	UFUNCTION(BlueprintCallable, NetMulticast, Reliable, Category = "Projectile")
	void Finish();

	UPROPERTY(VisibleAnywhere, BlueprintReadWrite, Replicated, Category = "Projectile", meta = (ExposeOnSpawn))
	float speed;
	UPROPERTY(VisibleAnywhere, BlueprintReadWrite, Replicated, Category = "Projectile", meta = (ExposeOnSpawn))
	EAbilityFilter filter;
	UPROPERTY(VisibleAnywhere, BlueprintReadWrite, Replicated, Category = "Projectile", meta = (ExposeOnSpawn))
	float maxDistance;
	UPROPERTY(VisibleAnywhere, BlueprintReadWrite, Replicated, Category = "Projectile", meta = (ExposeOnSpawn))
	bool autoMove = true;
	UPROPERTY(VisibleAnywhere, BlueprintReadWrite, Replicated, Category = "Projectile", meta = (ExposeOnSpawn))
	bool autoDestroy = true;

	UPROPERTY(VisibleAnywhere, BlueprintReadWrite, Category = "Projectile")
	float distanceTraveled;

	UPROPERTY(BlueprintReadOnly, EditDefaultsOnly, Category = "Projectile")
	float keepAliveAfterFinish;

	UPROPERTY(BlueprintReadOnly, Category = "Projectile")
	UPrimitiveComponent* collider;

protected:
	// Internal event handlers
	UFUNCTION()
	void m_OnOverlapBegin(class AActor* OtherActor, class UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult);
	UFUNCTION()
	void m_OnHit(class AActor* OtherActor, class UPrimitiveComponent* OtherComp, FVector NormalImpulse, const FHitResult& Hit);

	bool m_finished;
	float m_finishTimer;
	float m_fixedTimer;
};
