// Copyright (c) 2023 Codemongous LLC. All Rights Reserved.

#pragma once

#include "Engine/DeveloperSettings.h"
#include "ISourcifyCoreSettings.h"
#include "SourcifySettings.generated.h"

UENUM()
enum class SourcifySettingsEmittedCodeIndentType : uint8
{
	Tab,
	Spaces
};

UENUM()
enum class SourcifySettingsToolTipCommentStyle : uint8
{
	DoNotComment,
	CommentWithSlashes,
	CommentWithSlashesAndStars,
	CommentWithSlashesAndStarsMultiline
};

UCLASS(config=Editor, defaultconfig)
class USourcifySettings : public UDeveloperSettings
{
	GENERATED_BODY()
	
public:
	USourcifySettings();

	// UDeveloperSettings overrides
	FName GetContainerName() const override { return FName("Project"); }
	FName GetCategoryName() const override { return FName("Plugins"); }
	FName GetSectionName() const override { return FName("Sourcify"); }

	FText GetSectionText() const override;
	FText GetSectionDescription() const override;

	UPROPERTY(Config, EditAnywhere, BlueprintReadOnly, Category="Delegates")
	bool DeclareDelegatesInsideClass = false;
	
	UPROPERTY(Config, EditAnywhere, BlueprintReadOnly, Category="Indentation")
	SourcifySettingsEmittedCodeIndentType IndentType = SourcifySettingsEmittedCodeIndentType::Tab;
	
	UPROPERTY(Config, EditAnywhere, BlueprintReadOnly, Category="Indentation", meta=(UIMin=0, ClampMin=0, EditCondition="IndentType==SourcifySettingsEmittedCodeIndentType::Spaces"))
	int32 NumIndentSpaces = 4;
	
	UPROPERTY(Config, EditAnywhere, BlueprintReadOnly, Category="Spacing", meta = (UIMin = 0, ClampMin=0))
	int32 NumLinesBetweenTypeDeclarations = 1;
	
	UPROPERTY(Config, EditAnywhere, BlueprintReadOnly, Category="Spacing", meta = (UIMin = 0, ClampMin=0))
	int32 NumLinesBetweenFunctionAndPropertyDeclarationBlocks = 1;
	
	UPROPERTY(Config, EditAnywhere, BlueprintReadOnly, Category="Spacing", meta = (UIMin = 0, ClampMin=0))
	int32 NumLinesBetweenPropertyDeclarations = 1;
	
	UPROPERTY(Config, EditAnywhere, BlueprintReadOnly, Category="Spacing", meta = (UIMin = 0, ClampMin=0))
	int32 NumLinesBetweenFunctionDeclarations = 1;
	
	UPROPERTY(Config, EditAnywhere, BlueprintReadOnly, Category="Spacing", meta = (UIMin = 0, ClampMin=0))
	int32 NumLinesBetweenClassAccessBlocks = 1;
	
	UPROPERTY(Config, EditAnywhere, BlueprintReadOnly, Category="Properties and Fields", meta = (UIMin = 0, ClampMin=0))
	int32 NumSpacesAroundEqualSignInMetaTags = 1;
	
	UPROPERTY(Config, EditAnywhere, BlueprintReadOnly, Category="Properties and Fields")
	bool EnsurePropertiesHaveDefaultValues = true;
	
	UPROPERTY(VisibleDefaultsOnly, Category="Properties and Fields", meta=(ToolTip="Read-only default list of UStruct types that should have default values formatted in generated C++ code. This list is hardcoded and cannot be modified."))
	TArray<TSoftObjectPtr<UScriptStruct>> DefaultStructTypesToInitialize;
	
	UPROPERTY(Config, EditAnywhere, BlueprintReadOnly, Category="Properties and Fields", meta=(DisplayName="Additional Struct Types to Initialize", ToolTip="User-defined list of additional UStruct types to include when formatting default values in generated code"))
	TArray<TSoftObjectPtr<UScriptStruct>> UserStructTypesToInitialize;

	UPROPERTY(Config, EditAnywhere, BlueprintReadOnly, Category="Properties and Fields", meta=(ToolTip="List of asset prefixes to ignore when generating code. These will be removed from the asset name before generating a C++ class name"))
	TArray<FString> AssetPrefixesToIgnore;
	
	UPROPERTY(Config, EditAnywhere, BlueprintReadOnly, Category="Tool Tips", meta=(ToolTip="Tooltip comment style"))
	SourcifySettingsToolTipCommentStyle ToolTipCommentStyle = SourcifySettingsToolTipCommentStyle::CommentWithSlashesAndStars;
	
	UPROPERTY(Config, EditAnywhere, BlueprintReadOnly, Category="Meta Tags", meta=(ToolTip="The current meta tag value used when emitting or generating new Sourcified code"))
	FString CurrentSourcifyMetaTag = TEXT("SOURCIFIED");
	
	UPROPERTY(Config, EditAnywhere, BlueprintReadOnly, Category="Meta Tags", meta=(ToolTip="List of previously used meta tag values for backward compatibility when parsing or detecting Sourcified files"))
	TArray<FString> PreviousSourcifyMetaTags;
	
	UPROPERTY(Config, EditAnywhere, BlueprintReadOnly, Category="Output", meta=(ToolTip="Default folder path for exporting Sourcified code", RelativePath))
	FDirectoryPath DefaultCodeExportPath;
	
	UPROPERTY(Config, EditAnywhere, BlueprintReadOnly, Category="Output", meta=(ToolTip="If true, project files will be generated after code generation"))
	bool GenerateProjectFiles = true;
	
	void PostEditChangeProperty(struct FPropertyChangedEvent& PropertyChangedEvent) override;

	void ToSourcifyCore(struct Sourcify::ISourcifyCoreSettings* CoreSettings) const;
};
