// ©2023 Batty Bovine Productions, LLC. All Rights Reserved.

#pragma once

#include "CoreMinimal.h"
#include "Engine/DeveloperSettings.h"

#include "ComboActionGraphEditorSettings.generated.h"


#pragma region Enums

UENUM(BlueprintType)
enum class EComboActionAutoLayoutStrategyType : uint8
{
	Tree			UMETA(DisplayName="Tree"),
	ForceDirected	UMETA(DisplayName="Force Directed"),

	Default			UMETA(Hidden)
};

UENUM(BlueprintType)
enum class EComboActionWiringStyle : uint8
{
	Vanilla			UMETA(DisplayName="Vanilla"),
	Simple			UMETA(DisplayName="90° Angle"),
	Complex			UMETA(DisplayName="45° Angle"),

	Default			UMETA(Hidden)
};

UENUM(BlueprintType)
enum class EComboActionBubbleDrawRule : uint8
{
	Always			UMETA(DisplayName="Always"),
	OnSelected		UMETA(DisplayName="When Selected")
};

UENUM(BlueprintType)
enum class EComboActionNodeTheme : uint8
{
	DarkTheme		UMETA(DisplayName="Dark Theme"),
	LightTheme		UMETA(DisplayName="Light Theme")
};

UENUM(BlueprintType)
enum class EComboActionDecoratorsInfoStyle : uint8
{
	Stack			UMETA(DisplayName="Stack"),
	Unified			UMETA(DisplayName="Unified")
};

UENUM(BlueprintType)
enum class EComboActionNodeType : uint8
{
	SoftCorners		UMETA(DisplayName="Soft Corners"),
	HardCorners		UMETA(DisplayName="Hard Corners")
};

UENUM(BlueprintType)
enum class EComboActionArrowType : uint8
{
	SimpleArrow		UMETA(DisplayName="Simple Arrow"),
	HollowArrow		UMETA(DisplayName="Hollow Arrow"),
	FancyArrow		UMETA(DisplayName="Fancy Arrow"),
	Bubble			UMETA(DisplayName="Bubble"),
	None			UMETA(DisplayName="Nothing")
};

#pragma endregion 


/**
 * Combo Action Graph global settings.
 */
UCLASS(config = ComboActionSettings)
class COMBOINPUTEDITOR_API UComboActionGraphEditorSettings : public UDeveloperSettings
{
	GENERATED_BODY()

public:
	UComboActionGraphEditorSettings();

private:

#pragma region GraphNodes

	UPROPERTY(config, EditDefaultsOnly, Category = "NodesSettings")
		EComboActionNodeType NodeType;

	UPROPERTY(config, EditDefaultsOnly, Category = "NodesSettings")
		EComboActionNodeTheme NodeTheme;

	UPROPERTY(config, EditDefaultsOnly, Category = "NodesSettings|DecoratorsInfo")
		uint8 bShowDetailedInfo_NumDecorators : 1;

	UPROPERTY(config, EditDefaultsOnly, Category = "NodesSettings|DecoratorsInfo")
		uint8 bShowDetailedInfo_InheritsDecorators : 1;

	UPROPERTY(config, EditDefaultsOnly, Category = "NodesSettings")
		EComboActionDecoratorsInfoStyle DecoratorsInfoStyle;
	
	UPROPERTY(config, EditDefaultsOnly, Category = "NodesSettings")
		bool bDisplayAutomaticNames;

	UPROPERTY(config, EditDefaultsOnly, Category = "NodesSettings")
		bool bAllowRenameNodes;

	/**
	 * Select a Node Class and specify Override Colour for this Node type.
	 * Only non-abstract classes are allowed!
	 */
	UPROPERTY(config, EditDefaultsOnly, Category = "NodesSettings", meta=(ShowTreeView))
		TMap<TSoftClassPtr<class UComboActionGraphNode>, FLinearColor> OverrideNodeBackgroundColours;

#pragma endregion

#pragma region GraphDecorators

	// Enables 'Edit' button for Native Code Decorators
	UPROPERTY(config, EditDefaultsOnly, Category = "NodesSettings")
		bool bAllowNativeDecoratorsEdit;

#pragma endregion 

#pragma region GraphWiring
	
	UPROPERTY(config, EditDefaultsOnly, Category = "NodeWiring", meta=(UIMin=0.1f, ClampMin=0.1f, UIMax=1.5f, ClampMax=1.5f))
		float WireWidth;

	UPROPERTY(config, EditDefaultsOnly, Category = "NodeWiring") //, meta=(ConfigRestartRequired=true))
		EComboActionArrowType ArrowType;

	/* Advanced Wiring doesn't work now
	
	UPROPERTY(config, EditDefaultsOnly, Category = "NodeWiring", AdvancedDisplay, meta=(ToolTip="Work in Progress!"))
	bool bUseAdvancedWiring;
	
	UPROPERTY(config, EditDefaultsOnly, Category = "NodeWiring", AdvancedDisplay, meta=(ToolTip="Work in Progress!", EditCondition="bUseAdvancedWiring"))
	EWiringStyle WireStyle;

	UPROPERTY(config, EditDefaultsOnly, Category = "NodeWiring", AdvancedDisplay, meta=(ToolTip="Work in Progress!", EditCondition="bUseAdvancedWiring"))
	uint32 HorizontalOffset = 16;

	UPROPERTY(config, EditDefaultsOnly, Category = "NodeWiring", AdvancedDisplay, meta=(ToolTip="Work in Progress!", EditCondition="bUseAdvancedWiring"))
	EBubbleDrawRule BubbleDrawRule;

	UPROPERTY(config, EditDefaultsOnly, Category = "NodeWiring", AdvancedDisplay, meta=(ToolTip="Work in Progress!", EditCondition="bUseAdvancedWiring"))
	int32 BubbleZoomThreshold;

	// Space between bubbles on the wires. Default: 20.0
	UPROPERTY(config, EditDefaultsOnly, Category = "NodeWiring", AdvancedDisplay, meta = (ClampMin = "10.0", ToolTip="Work in Progress!", EditCondition="bUseAdvancedWiring"))
	float BubbleSpace = 20.0f;

	UPROPERTY(config, EditDefaultsOnly, Category = "NodeWiring", AdvancedDisplay, meta = (ClampMin = "10.0", ToolTip="Work in Progress!", EditCondition="bUseAdvancedWiring"))
	float BubbleSize = 2.0f;

	UPROPERTY(config, EditDefaultsOnly, Category = "NodeWiring", AdvancedDisplay, meta = (ClampMin = "10.0", ToolTip="Work in Progress!", EditCondition="bUseAdvancedWiring"))
	float BubbleSpeed = 2.0f;
	
	// Disable the offset for pins. Default: false
	UPROPERTY(config, EditDefaultsOnly, Category = "NodeWiring", AdvancedDisplay, meta=(ToolTip="Work in Progress!", EditCondition="bUseAdvancedWiring"))
	bool DisablePinOffset = false;

	// Fix default zoomed-out wire displacement. Default: true
	UPROPERTY(config, EditDefaultsOnly, Category = "NodeWiring", AdvancedDisplay, meta=(ToolTip="Work in Progress!", EditCondition="bUseAdvancedWiring"))
	bool FixZoomDisplacement = true;

	*/

#pragma endregion

#pragma region GraphArrange
	
	UPROPERTY(config, EditDefaultsOnly, Category = "AutoArrange")
		float OptimalDistance;
	
	UPROPERTY(config, EditDefaultsOnly, AdvancedDisplay, Category = "AutoArrange")
		EComboActionAutoLayoutStrategyType AutoLayoutStrategy;

	UPROPERTY(config, EditDefaultsOnly, AdvancedDisplay, Category = "AutoArrange")
		int32 MaxIteration;

	UPROPERTY(config, EditDefaultsOnly, AdvancedDisplay, Category = "AutoArrange")
		bool bFirstPassOnly;

	UPROPERTY(config, EditDefaultsOnly, AdvancedDisplay, Category = "AutoArrange")
		bool bRandomInit;

	UPROPERTY(config, EditDefaultsOnly, AdvancedDisplay, Category = "AutoArrange")
		float InitTemperature;

	UPROPERTY(config, EditDefaultsOnly, AdvancedDisplay, Category = "AutoArrange")
		float CoolDownRate;

#pragma endregion 

#if WITH_EDITOR
	virtual FText GetSectionText() const override
	{
		return NSLOCTEXT("ComboActionGraphEditorSystem", "ComboActionGraphEditorSection", "Combo Action Graph (Editor)");
	}

	virtual FText GetSectionDescription() const override
	{
		return NSLOCTEXT("ComboActionGraphEditorSystem", "ComboActionGraphEditorDescription", "Default values for Mountea Plugins (Editor).");
	}

	virtual FName GetContainerName() const override
	{
		return "Project";
	}
#endif

public:

#pragma region GraphNodes_Getters
	
	EComboActionNodeTheme GetNodeTheme() const { return NodeTheme; }
	EComboActionNodeType GetNodeType() const { return NodeType; }
	bool ShowDetailedInfo_NumDecorators() const { return bShowDetailedInfo_NumDecorators; }
	bool ShowDetailedInfo_InheritsDecorators() const { return bShowDetailedInfo_InheritsDecorators; }
	bool ShowAutomaticNames() const { return bDisplayAutomaticNames; }
	EComboActionDecoratorsInfoStyle GetDecoratorsStyle() const { return DecoratorsInfoStyle; }
	bool AllowRenameNodes() const { return bAllowRenameNodes; }

	bool FindNodeBackgroundColourOverride(const TSoftClassPtr<class UComboActionGraphNode> NodeClass, FLinearColor& BackgroundColour)
	{
		if (OverrideNodeBackgroundColours.Contains(NodeClass))
		{
			BackgroundColour = *OverrideNodeBackgroundColours.Find(NodeClass);
			return true;
		}

		return false;
	}

#pragma endregion 

#pragma region GraphDecorators_Getters

	bool IsNativeDecoratorsEditAllowed() const { return bAllowNativeDecoratorsEdit; }

#pragma endregion 
	

#pragma region GraphWiring_Getters

	float GetWireWidth() const { return this->WireWidth; }

	EComboActionArrowType GetArrowType() const { return this->ArrowType; }
	
	/*
	bool AllowAdvancedWiring() const
	{ return bUseAdvancedWiring; };
	
	EWiringStyle GetWireStyle() const
	{ return WireStyle; };

	int32 GetHorizontalOffset() const
	{ return HorizontalOffset; };

	EBubbleDrawRule GetBubbleDrawRule() const
	{ return  BubbleDrawRule; };

	int32 GetBubbleZoomThreshold() const
	{ return BubbleZoomThreshold; };

	float GetBubbleSpace() const
	{ return BubbleSpace; };

	float GetBubbleSpeed() const
	{ return BubbleSpeed; };

	float GetBubbleSize() const
	{ return BubbleSize; };
	*/
#pragma endregion 

	
#pragma region GraphArrange_Getters
	
	EComboActionAutoLayoutStrategyType GetAutoLayoutStrategy() const { return this->AutoLayoutStrategy; }
	float GetOptimalDistance() const { return this->OptimalDistance; }
	int32 GetMaxIteration() const { return this->MaxIteration; }
	bool IsFirstPassOnly() const { return this->bFirstPassOnly; }
	bool IsRandomInit() const { return this->bRandomInit; }
	float GetInitTemperature() const { return this->InitTemperature; }
	float GetCoolDownRate() const { return this->CoolDownRate; }

#pragma endregion 
};

