// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "CoreMinimal.h"
#include "Engine/TargetPoint.h"
#include "Lane.generated.h"

UCLASS()
class GAMEJAMTEMPLATE_API ALane : public ATargetPoint
{
	GENERATED_BODY()
	
public:

	ALane();

	void Tick(float DeltaTime) override;

	/**
	* Gets the ID of the lane.
	* @return The ID of the lane.
	*/
	int GetLaneID();

	/**
	* Sets the target's spawner.
	* @param NewTargetSpawner The target's spawner.
	*/
	void SetTargetSpawner(class ATargetSpawner* NewTargetSpawner);

	/**
	* Sets the direction the spawned targets should be moving in.
	* @param bNewLeftToRight True if the targets should be moving from left to right.
	*/
	void SetSpawningDirection(bool bNewLeftToRight);

	/**
	* Spawns a single target at one end of the lane
	* using the specified parameters.
	* @param Heads The type of the first face of the target.
	* @param Tails The type of the second face of the target.
	* @param MovementSpeed The target's movement speed.
	*/
	void Spawn(uint8 Heads, uint8 Tails, float MovementSpeed);

	/**
	* Removes a target from the lane.
	* @param Target The target to be removed.
	*/
	void Remove(class ATarget* Target);

	/**
	* Destroys all of the targets in the lane.
	*/
	void Empty();

	/**
	* Finds all targets within a blast radius and returns them.
	* @param TargetsInRange The targets within the blast radius.
	* @param CenterOfBlast The world space location of the center of the blast.
	* @param BlastRadius The radius of the blast.
	*/
	void FindTargets(TArray<class ATarget*>* TargetsInRange, FVector CenterOfBlast, float BlastRadius);

protected:
	
	void BeginPlay() override;

private:

	// The name of the object fetched by the UObjectBaseUtility::GetName method
	const FString ObjectName;

	// The marker which signifies the left side of the level when observed by the player.
	UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Components", meta = (AllowPrivateAccess = "true"))
	class UStaticMeshComponent* LeftMarker;

	// The marker which signifies the right side of the level when observed by the player.
	UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Components", meta = (AllowPrivateAccess = "true"))
	class UStaticMeshComponent* RightMarker;

	// A kill box which destroys all targets which enter it.
	UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Components", meta = (AllowPrivateAccess = "true"))
	class UBoxComponent* KillBox;

	// The UClass of the target being spawned.
	UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Variables", meta = (AllowPrivateAccess = "true"))
	class UClass* TargetUClass;

	// The ID of the lane.
	UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Variables", meta = (AllowPrivateAccess = "true"))
	int LaneID;

	// A reference to the target's spawner.
	class ATargetSpawner* TargetSpawner;

	// The list of spawned targets in the lane.
	TArray<class ATarget*> Targets;

	// Determines if the spawned targets should be moving from left to right when observed by the player.
	bool bLeftToRight;

	// The world space location of the left marker.
	FVector LeftMarkerLocation;

	// The world space location of the right marker.
	FVector RightMarkerLocation;

	/*
	* Triggered when a target enters the lane's kill box.
	*/
	UFUNCTION()
	void OnKillBoxBeginOverlap(
		class UPrimitiveComponent* HitComp,
		class AActor* OtherActor,
		class UPrimitiveComponent* OtherComp,
		int32 OtherBodyIndex,
		bool bFromSweep,
		const FHitResult& Hit);

};
