/*
* 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 "RadioStation.h"
#include "Boombox.generated.h"

/// <summary>
/// The Boombox class is responsible for playing "Radio Stations" which are simply
/// collections of music files sorted by genre. I decided to call it a Boombox instead
/// of a "Radio" because that term can be too genric (for example, radio buttons or 
/// using a radio to communicate).
/// </summary>
UCLASS(Blueprintable, BlueprintType)
class UBoombox : public UObject
{
	GENERATED_BODY()

protected:
	/// <summary>
	/// True if the boombox is on and is playing music, false otherwise.
	/// </summary>
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "General")
	bool myIsOn;

	/// <summary>
	/// The current volume level of the boombox (lowest is 1.0).
	/// </summary>
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "General")
	float myVolume;

	/// <summary>
	/// The array index of the current station playing.
	/// </summary>
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Internal")
	int myCurrentStationIndex;

	/// <summary>
	/// A pointer to the current station being played.
	/// </summary>
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Internal")
	URadioStation* myCurrentStation;

	/// <summary>
	/// A pointer to the Boombox GUI.
	/// </summary>
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "UI")
	UUserWidget* myBoomboxWidget;

	/// <summary>
	/// A pointer to the Player HUD GUI.
	/// </summary>
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "UI")
	UUserWidget* myPlayerHUDWidget;

	/// <summary>
	/// A collection of radio station objects that can be played by this boombox.
	/// </summary>
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Internal")
	TArray<URadioStation*> myStations;

	/// <summary>
	/// A collection of radio station blueprints to load.
	/// </summary>
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "General")
	TArray<TSubclassOf<URadioStation>> myStationBlueprints;

public:
	/// <summary>
	/// Default constructor for the boombox.
	/// </summary>
	UBoombox();

	/// <summary>
	/// Creates the radio stations from the blueprints and adds them to the myStations collection.
	/// </summary>
	UFUNCTION(BlueprintCallable)
	void Initialize();

	/// <summary>
	/// Implemented in the blueprint of <c>UBoombox</c> to handle updating the GUI
	/// such as song title(s) and volume.
	/// </summary>
	UFUNCTION(BlueprintImplementableEvent)
	void UpdateBoomboxUI();

	/// <summary>
	/// Implemented in the blueprint of <c>UBoombox</c> to handle hiding or showing
	/// the Boombox GUI.
	/// </summary>
	UFUNCTION(BlueprintImplementableEvent)
	void ToggleBoomboxUI();

	/// <summary>
	/// Turns on the boombox and starts by playing a random station.
	/// </summary>
	UFUNCTION(BlueprintCallable)
	void TurnOn();

	/// <summary>
	/// Turns off the boombox and stops playing music.
	/// </summary>
	UFUNCTION(BlueprintCallable)
	void TurnOff();

	/// <summary>
	/// Turns the boombox on if it is off, and turns the boombox off 
	/// if it is on.
	/// </summary>
	UFUNCTION(BlueprintCallable)
	void ToggleOnOff();

	/// <summary>
	/// Increments the station index and starts playing the next station
	/// in the radio stations collection.
	/// </summary>
	UFUNCTION(BlueprintCallable)
	void TuneToNextStation();

	/// <summary>
	/// Decrements the station index and starts playing the previous 
	/// station in the radio stations collection.
	/// </summary>
	UFUNCTION(BlueprintCallable)
	void TuneToPreviousStation();

	/// <summary>
	/// Updates the volume to myVolume for all of the radio stations 
	/// in the collection.
	/// </summary>
	UFUNCTION(BlueprintCallable)
	void UpdateVolume();

	/// <summary>
	/// Increments myVolume by 1.0 for all stations (including the one currently playing).
	/// </summary>
	UFUNCTION(BlueprintCallable)
	void IncreaseVolume();

	/// <summary>
	/// Decrements myVolume by 1.0 for all stations (including the one currently playing).
	/// </summary>
	UFUNCTION(BlueprintCallable)
	void DecreaseVolume();

	/// <summary>
	/// Returns the current station being played.
	/// </summary>
	/// <returns>The currently selected station being played.</returns>
	UFUNCTION(BlueprintCallable)
	URadioStation* GetCurrentStation() const;
};