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

#pragma once

#include "CoreMinimal.h"

#include "Toolkits/AssetEditorToolkit.h"

DECLARE_LOG_CATEGORY_EXTERN(LogAssetEditorComboActionGraph, Log, All);


class COMBOINPUTEDITOR_API FAssetEditor_ComboActionGraph : public FAssetEditorToolkit, public FNotifyHook, public FGCObject
{

public:
	FAssetEditor_ComboActionGraph();
	virtual ~FAssetEditor_ComboActionGraph() override;

	void OnPackageSaved(const FString &String, UPackage *Package, FObjectPostSaveContext ObjectPostSaveContext);
	
	void InitComboActionGraphAssetEditor(const EToolkitMode::Type Mode, const TSharedPtr<IToolkitHost> &InitToolkitHost, class UComboActionGraph *Graph);
	class UComboActionGraphEditorSettings *GetSettings() const;
	
#pragma region ToolkitInterface
	
public:
	// IToolkit interface
	virtual void RegisterTabSpawners(const TSharedRef<FTabManager> &InTabManager) override;
	virtual void UnregisterTabSpawners(const TSharedRef<FTabManager> &InTabManager) override;

	virtual bool CloseWindow(EAssetEditorCloseReason InCloseReason) override;
	// End of IToolkit interface

#pragma endregion

#pragma region AssetEditorToolkit

	virtual FName GetToolkitFName() const override;
	virtual FText GetBaseToolkitName() const override;
	virtual FText GetToolkitName() const override;
	virtual FText GetToolkitToolTipText() const override;
	virtual FLinearColor GetWorldCentricTabColorScale() const override;
	virtual FString GetWorldCentricTabPrefix() const override;
	virtual FString GetDocumentationLink() const override;
	virtual void SaveAsset_Execute() override;

#pragma endregion

#pragma region Toolbar

	void UpdateToolbar();
	TSharedPtr<class FAssetEditorToolbarComboActionGraph> GetToolbarBuilder() { return this->ToolbarBuilder; }
	void RegisterToolbarTab(const TSharedRef<class FTabManager> &InTabManager);

#pragma endregion

#pragma region SerializableObjectInterface

	virtual void AddReferencedObjects(FReferenceCollector &Collector) override;

#pragma endregion

#pragma region FGCObject

	virtual FString GetReferencerName() const override;

#pragma endregion 
	
	// Gets/Sets the dialogue being edited
	class UComboActionGraph *GetEditingGraphSafe()
	{
		check(EditingGraph);
		return EditingGraph;
	}
	void SetDialogueBeingEdited(class UComboActionGraph *NewDialogue);

	virtual void JumpToNode(const class UEdGraphNode *JumpToMe, bool bRequestRename = false, bool bSelectNode = true)
	{
		if (this->ViewportWidget.IsValid())
		{
			this->ViewportWidget->JumpToNode(JumpToMe, bRequestRename, bSelectNode);
		}
	}
	
private:
	void CreateInternalWidgets();
	TSharedRef<SGraphEditor> CreateViewportWidget();

	void BindCommands();
	void CreateEdGraph();
	void CreateCommandList();

	TSharedPtr<SGraphEditor> GetCurrentGraphEditor() const;

	FGraphPanelSelectionSet GetSelectedNodes() const;

	void RebuildComboActionGraph();

#pragma region GraphEditorCommands

	void SelectAllNodes();
	bool CanSelectAllNodes() const { return true; }
	void DeleteSelectedNodes();
	bool CanDeleteNodes() const;
	void DeleteSelectedDuplicatableNodes();
	void CutSelectedNodes();
	bool CanCutNodes() const { return this->CanCopyNodes() && this->CanDeleteNodes(); }
	void CopySelectedNodes();
	bool CanCopyNodes() const;
	void PasteNodes();
	void PasteNodesHere(const FVector2D &Location);
	bool CanPasteNodes() const;
	void DuplicateNodes() { this->CopySelectedNodes(); this->PasteNodes(); }
	bool CanDuplicateNodes() { return this->CanCopyNodes(); }

	void AutoArrange();
	bool CanAutoArrange() const;

	void ValidateGraph();
	bool CanValidateGraph() const { return true; }

	void OnRenameNode();
	bool CanRenameNodes() const;

#pragma endregion

#pragma region GraphEditorEvents

	void OnSelectedNodesChanged(const TSet<class UObject*> &NewSelection);

	void OnNodeDoubleClicked(UEdGraphNode *Node);

	void OnFinishedChangingProperties(const FPropertyChangedEvent &PropertyChangedEvent);

	void OnPackageSaved(const FString &PackageFileName, UObject *Outer);

#pragma endregion 

#pragma region Variables
	
private:

	TSharedRef<SDockTab> SpawnTab_Viewport(const FSpawnTabArgs &Args);
	TSharedRef<SDockTab> SpawnTab_Details(const FSpawnTabArgs &Args);
	TSharedRef<SDockTab> SpawnTab_Search(const FSpawnTabArgs &Args);

	class UComboActionGraphEditorSettings *ComboActionGraphEditorSettings;

	class UComboActionGraph *EditingGraph;

	//Toolbar
	TSharedPtr<FAssetEditorToolbarComboActionGraph> ToolbarBuilder;

	/** Handle to the registered OnPackageSave delegate */
	FDelegateHandle OnPackageSavedDelegateHandle;

	TSharedPtr<SGraphEditor> ViewportWidget;
	TSharedPtr<class IDetailsView> PropertyWidget;
	TSharedPtr<class SComboActionSearch> FindResultsView;

	/** The command list for this editor */
	TSharedPtr<FUICommandList> GraphEditorCommands;

	TSharedPtr<SWindow> ValidationWindow;

#pragma endregion 
};
