/*
* Neural Tanks is a game created by Eddie O'Hagan that leverages Neural Networking
* to use for AI. This was created in Unreal Engine 4 which is developed by Epic Games.
* (Copyright Epic Games, Inc. All Rights Reserved.)
*
* Smart Tanks was originally developed by Mat Buckland in 2002 as an example
* on how Neural Networking can be used to train a set of minesweepers
* to collect mines. I (Eddie O'Hagan) updated this project in 2024 to use more
* Object Oriented Programming and modern practices. To see the original tutorial;
* visit <see href="http://www.ai-junkie.com/ann/evolved/nnt1.html">Neural Networking Tutorial</see>
* and <see href="http://www.ai-junkie.com/ga/intro/gat1.html">Genetic Algorithm Tutorial</see>
*/
#pragma once
#include <Sound/SoundWave.h>
#include <Components/AudioComponent.h>
#include "RadioStation.generated.h"

class UBoombox;

/// <summary>
/// Manages and contains a collection of songs from a single genre. This is
/// used with the <c>UBoombox</c> class.
/// </summary>
UCLASS(Blueprintable, BlueprintType)
class URadioStation : public UObject
{
	GENERATED_BODY()

protected:
	/// <summary>
	/// The name of the current song.
	/// </summary>
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Internal")
	FString myCurrentSongName;

	/// <summary>
	/// The current song playing.
	/// </summary>
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Internal")
	UAudioComponent* myCurrentSong;

	/// <summary>
	/// The name of the radio station.
	/// </summary>
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "General")
	FText myStationName;

	/// <summary>
	/// The logo to use on the boombox to represent the current station.
	/// </summary>
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "General")
	UTexture2D* myStationLogo;

	/// <summary>
	/// The boombox that controls and plays the boombox.
	/// </summary>
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "General")
	UBoombox* myOwningBoombox;

	/// <summary>
	/// The collection of song names (Artist-Song-Genre) with corresponding song files for this station.
	/// </summary>
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "General")
	TMap<FString, USoundWave*> mySongs;

public:
	/// <summary>
	/// Default constructor for the Radio Station.
	/// </summary>
	URadioStation();

	/// <summary>
	/// Initializes this radio station by setting it's parent and setting the volume
	/// for all the songs in this station.
	/// </summary>
	/// <param name="boomboxVolume">The volume set by the player for the Boombox.</param>
	/// <param name="theOwningBoombox">The owning Boombox for this Radio Station.</param>
	void Initialize(const float boomboxVolume, UBoombox* theOwningBoombox);

	/// <summary>
	/// Starts the next song when one finishes.
	/// </summary>
	/// <param name="thePlayState">The state of the song.</param>
	UFUNCTION()
	void OnPlayStateChanged(EAudioComponentPlayState thePlayState);

	/// <summary>
	/// Randomly chooses a song from the collection and starts playing it.
	/// Also registers the handler for OnPlayStateChanged.
	/// </summary>
	void StartPlayingStation();

	/// <summary>
	/// Stops playing the current song and unregisters the handler 
	/// for OnPlayStateChanged.
	/// </summary>
	void StopPlayingStation();

	/// <summary>
	/// Sets the volume for all of the songs in the collection with
	/// the provided boomboxVolume.
	/// </summary>
	/// <param name="boomboxVolume">The volume to use for all the songs in this station.</param>
	void UpdateVolume(const float boomboxVolume);

	/// <summary>
	/// Returns the name of the station (typically describes the genre).
	/// </summary>
	/// <returns>The name of the station.</returns>
	FText GetStationName() const;

	/// <summary>
	/// Returns the currently playing song name.
	/// </summary>
	/// <returns>The name of song currently playing.</returns>
	FString GetCurrentSongDetails() const;

	/// <summary>
	/// Returns the image used for this station in the Boombox GUI.
	/// </summary>
	/// <returns>The image used for this station in the Boombox GUI.</returns>
	UTexture2D* GetStationLogo() const;

};