// Oleg Petruny staff

#pragma once

#include "GenericPlatform/GenericApplication.h"
#include "Kismet/KismetSystemLibrary.h"
#include "Engine/Engine.h"
#include "GenericPlatform/GenericWindow.h"
#include "Kismet/BlueprintFunctionLibrary.h"
#include "VideoSettings.generated.h"

USTRUCT(BlueprintType, Category = "Settings Video|Structs")
struct FPlatformRectangle {
	GENERATED_USTRUCT_BODY()

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Settings Video|Structs|PlatformRect")
		int32 Left;
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Settings Video|Structs|PlatformRect")
		int32 Top;
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Settings Video|Structs|PlatformRect")
		int32 Right;
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Settings Video|Structs|PlatformRect")
		int32 Bottom;
	FPlatformRectangle() {
		Left = Top = Right = Bottom = 0;
	}
	FPlatformRectangle(int32 left, int32 top, int32 right, int32 bottom) {
		Left = left;
		Top = top;
		Right = right;
		Bottom = bottom;
	}
};

USTRUCT(BlueprintType, Category = "Settings Video|Structs")
struct FMonitorInformation {
	GENERATED_USTRUCT_BODY()
		
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Settings Video|Structs|MonitorInfo")
		FString Name;
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Settings Video|Structs|MonitorInfo")
		FString ID;
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Settings Video|Structs|MonitorInfo")
		int32 NativeWidth;
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Settings Video|Structs|MonitorInfo")
		int32 NativeHeight;
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Settings Video|Structs|MonitorInfo")
		FPlatformRectangle DisplayRect;
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Settings Video|Structs|MonitorInfo")
		FPlatformRectangle WorkArea;
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Settings Video|Structs|MonitorInfo")
		bool IsPrimary;
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Settings Video|Structs|MonitorInfo")
		int32 DPI = 0;
	FMonitorInformation() {
		Name = ID = "";
		NativeWidth = NativeHeight = DPI = 0;
		DisplayRect = WorkArea = FPlatformRectangle();
		IsPrimary = false;
	}
	FMonitorInformation(FString name, FString id, int32 nativeWidth, int32 nativeHeight, FPlatformRectangle displayRect, FPlatformRectangle workArea, bool isPrimary, int32 dpi) {
		Name = name;
		ID = id;
		NativeWidth = nativeWidth;
		NativeHeight = nativeHeight;
		DisplayRect = displayRect;
		WorkArea = workArea;
		IsPrimary = isPrimary;
		DPI = dpi;
	}
};

USTRUCT(BlueprintType, Category = "Settings Video|Structs")
struct FResolutionAndRefreshRate {
	GENERATED_USTRUCT_BODY()

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Settings Video|Structs|ResolutionAndRefreshRate")
		int32 Width;
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Settings Video|Structs|ResolutionAndRefreshRate")
		int32 Height;
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Settings Video|Structs|ResolutionAndRefreshRate")
		int32 RefreshRate;
	FResolutionAndRefreshRate() {
		Width = Height = RefreshRate = 0;
	}
	FResolutionAndRefreshRate(int32 width, int32 height, int32 refreshRate) {
		Width = width;
		Height = height;
		RefreshRate = refreshRate;
	}
};

UENUM(BlueprintType, Category = "Settings Video|Enums")
enum class EDisplayMode : uint8{
	Fullscreen = 0 UMETA(DisplayName = "Fullscreen"),
	Borderless = 1 UMETA(DisplayName = "Borderless"),
	Windowed = 2 UMETA(DisplayName = "Windowed")
};

UCLASS()
class LOST_EDGE_API UVideoSettings : public UBlueprintFunctionLibrary {
	GENERATED_BODY()

public:
	UFUNCTION(BlueprintPure, Category = "Settings Video|Monitor")
		static void GetPrimaryMonitorId(int &monitorId);
	UFUNCTION(BlueprintPure, Category = "Settings Video|Monitor")
		static void GetCurrentMonitorId(int &monitorId);
	UFUNCTION(BlueprintPure, Category = "Settings Video|Monitor")
		static void GetAvailableMonitors(TArray<FMonitorInformation> &monitors);
	UFUNCTION(BlueprintCallable, Category = "Settings Video|Monitor")
		static void SetMonitor(int monitorId);

	UFUNCTION(BlueprintPure, Category = "Settings Video|Other")
		static void IntPointToString(FIntPoint in, FString &out);
	UFUNCTION(BlueprintPure, Category = "Settings Video|Other")
		static void StringToIntPoint(FString in, FIntPoint &out);
	UFUNCTION(BlueprintPure, Category = "Settings Video|Other")
		static void StringAnyToInt(FString in, int32 &out);

	UFUNCTION(BlueprintPure, Category = "Settings Video|Resolution")
		static void GetNativeResolutionByMonitorId(int monitorId, FIntPoint &nativeResolution);
	UFUNCTION(BlueprintPure, Category = "Settings Video|Resolution And Refresh Rate")
		static void GetAllAvailableResolutionsAndRefreshRates(TArray<FResolutionAndRefreshRate> &availableResolutionsAndRefreshRatess);
	UFUNCTION(BlueprintPure, Category = "Settings Video|Resolution")
		static void GetAvailableResolutionsByMonitorId(int monitorId, TArray<FIntPoint> &availableResolutions);
	UFUNCTION(BlueprintPure, Category = "Settings Video|Resolution")
		static void FilterResolutionsViaAspectRatio(TArray<FIntPoint> resolutionsIn, FIntPoint aspectRatio, TArray <FIntPoint> &resolutionsOut);
	UFUNCTION(BlueprintPure, Category = "Settings Video|Resolution")
		static void GetCurrentResolution(FIntPoint &currentResolution);
	UFUNCTION(BlueprintCallable, Category = "Settings Video|Resolution")
		static void SetResolution(FIntPoint resolution);
	UFUNCTION(BlueprintCallable, Category = "Settings Video|Resolution")
		static void SetResolutionScale(float resolutionScale);

	UFUNCTION(BlueprintPure, Category = "Settings Video|Refresh Rate")
		static void GetAvailableRefreshRates(FIntPoint resolution, TArray<int32> &availableRefreshRates);
	UFUNCTION(BlueprintPure, Category = "Settings Video|Refresh Rate")
		static void GetCurrentRefreshRate(int32 &currentRefreshRate);
	UFUNCTION(BlueprintCallable, Category = "Settings Video|Refresh Rate")
		static void SetRefreshRate(int32 refreshRate);

	UFUNCTION(BlueprintPure, Category = "Settings Video|Other")
		static void AspectRatioParse(FIntPoint resolution, FIntPoint &aspectRatio);
	UFUNCTION(BlueprintPure, Category = "Settings Video|Aspect Ratio")
		static void GetNativeAspectRatioByMonitorId(int monitorId, FIntPoint &nativeAspectRatio);
	UFUNCTION(BlueprintPure, Category = "Settings Video|Aspect Ratio")
		static void GetAvailableAspectRatiousByMonitorId(int monitorId, TArray<FIntPoint> &availableAspectRatious);
	UFUNCTION(BlueprintPure, Category = "Settings Video|Aspect Ratio")
		static void GetCurrentAspectRatio(FIntPoint &currentAspectRatio);
	UFUNCTION(BlueprintCallable, Category = "Settings Video|Aspect Ratio")
		static void SetAspectRatio(FIntPoint aspectRatio);

	UFUNCTION(BlueprintPure, Category = "Settings Video|Display Mode")
		static void StringToDisplayMode(FString in, EDisplayMode &mode);
	UFUNCTION(BlueprintPure, Category = "Settings Video|Display Mode")
		static void DisplayModeToString(EDisplayMode mode, FString &out);
	UFUNCTION(BlueprintPure, Category = "Settings Video|Display Mode")
		static void IntToDisplayMode(int in, EDisplayMode &mode);
	UFUNCTION(BlueprintPure, Category = "Settings Video|Display Mode")
		static void DisplayModeToInt(EDisplayMode mode, int &out);
	UFUNCTION(BlueprintPure, Category = "Settings Video|Display Mode")
		static void GetCurrentDisplayMode(EDisplayMode &mode);
	UFUNCTION(BlueprintCallable, Category = "Settings Video|Display Mode")
		static void SetDisplayMode(EDisplayMode mode);

	UFUNCTION(BlueprintCallable, Category = "Settings Video|Other")
		static void WindowToCenter();

	UFUNCTION(BlueprintCallable, Category = "Settings Video|Other")
		static void ApplyVideoSettings();
	UFUNCTION(BlueprintCallable, Category = "Settings Video|Other")
		static void GetDefaultVideoSettings(FIntPoint &resolution, EDisplayMode &mode);
	UFUNCTION(BlueprintCallable, Category = "Settings Video|Other")
		static void GetLastVideoSettings(FIntPoint &resolution, EDisplayMode &mode);
	UFUNCTION(BlueprintCallable, Category = "Settings Video|Other")
		static void SetLastVideoSettings(FIntPoint resolution, EDisplayMode mode);

	UFUNCTION(BlueprintPure, Category = "Settings Video|Display Mode")
		static void GetGamma(float &gamma);
	UFUNCTION(BlueprintCallable, Category = "Settings Video|Display Mode")
		static void SetGamma(float gamma);
};
