Editor/ChitChat/ChitChatEditorWindow.cs
using Sandbox;
using Editor;

namespace ChitChat.Editor;

[EditorForAssetType("chit")]
public class ChitChatEditorWindow : DockWindow, IAssetEditor
{
	public const int WINDOW_SIZE_X = 1280;
	public const int WINDOW_SIZE_Y = 720;

	public bool CanOpenMultipleAssets => true;

	private DialogueInspector _inspector;
	private DialogueSelector _selector;
	private TemplateWindow _template;

	private DialogueData _currentData;
	private GameResource _resource;
	private Asset _asset;

	private Color _menuBarColor = Color.Black;

	public ChitChatEditorWindow()
	{
		Title = "ChitChat Editor";
		Size = new Vector2(WINDOW_SIZE_X, WINDOW_SIZE_Y);
		MenuWidget.OnPaintOverride = OnMenuBarPaint;

		Show();
	}

	public void AssetOpen(Asset asset)
	{
		if(ResourceLibrary.TryGet(asset.Path, out GameResource resource))
		{
			_resource = resource;
			_currentData = resource as DialogueData;
			_asset = asset;

			OpenData(_currentData);
		}
	}

	public override void OnDestroyed()
	{
		if (_asset != null)
			_asset.SaveToDisk(_resource);
	}

	public void OpenData(DialogueData data)
	{
		//Menubar
		MenuBar.Clear();

		{
			Menu fileMenu = MenuBar.AddMenu("File");
			fileMenu.AddOption(new Option("Save", "save") { ShortcutName = "editor.save", Triggered = SaveAsset });
			fileMenu.AddSeparator();
			fileMenu.AddOption(new Option("Quit", "disabled_by_default") { ShortcutName = "editor.quit", Triggered = Quit });
		}

		{
			Menu viewMenu = MenuBar.AddMenu("View");
			viewMenu.AddOption(new Option("Selector", "list_alt")
			{
				Triggered = OnViewButtonSelector
			});
			viewMenu.AddSeparator();
			viewMenu.AddOption(new Option("Inspector", "tune")
			{
				Triggered = OnViewButtonInspector
			});
			viewMenu.AddSeparator();
			viewMenu.AddOption(new Option("Template", "save_as") 
			{
				Triggered = OnViewButtonTemplate
			});
		}

		//Inspector
		if (!TryAddInspector())
		{
			_inspector.Clear();
		}

		//Selector
		if (!TryAddSelector())
		{
			_selector.SetData(_currentData);
			_selector.Rebuild();
		}

		//Template
		if (TryAddTemplate())
		{
			DockManager.RaiseDock(_inspector);
		}

		Focus();
	}

	/// <returns>Returns true if an selector was added.</returns>
	private bool TryAddSelector()
	{
		if (!_selector.IsValid())
		{
			_selector = new DialogueSelector(this, _currentData);

			if (_inspector.IsValid())
			{
				_selector.onDialogueActionSelected = _inspector.OnDialogueSelected;
				_selector.onSelectedDialogueRemoved = _inspector.Clear;
			}

			DockManager.AddDock(null, _selector, DockArea.RightOuter, split: 0.5f);
			DockManager.Update();
			return true;
		}

		return false;
	}

	/// <returns>Returns true if an inspector was added.</returns>
	public bool TryAddInspector()
	{
		if (!_inspector.IsValid())
		{
			_inspector = new DialogueInspector(this);

			if (_selector.IsValid())
			{
				_selector.onDialogueActionSelected = _inspector.OnDialogueSelected;
				_selector.onSelectedDialogueRemoved = _inspector.Clear;
			}

			DockManager.AddDock(null, _inspector, DockArea.LeftOuter, split: 0.5f);
			DockManager.Update();
			return true;
		}

		return false;
	}

	/// <returns>Returns true if template was added.</returns>
	public bool TryAddTemplate()
	{
		if (!_template.IsValid())
		{
			_template = new TemplateWindow(this);

			DockManager.AddDock(null, _template, DockArea.Inside, split: 0.5f);
			DockManager.Update();
			return true;
		}

		return false;
	}

	private void OnViewButtonInspector()
	{
		if (!TryAddInspector())
		{
			_inspector.Focus();
			DockManager.RaiseDock(_inspector);
		}
	}

	private void OnViewButtonSelector()
	{
		if (!TryAddSelector())
		{
			_selector.Focus();
			DockManager.RaiseDock(_selector);
		}
	}

	private void OnViewButtonTemplate()
	{
		if(!TryAddTemplate())
		{
			_template.Focus();
			DockManager.RaiseDock(_template);
		}
	}

	[Shortcut("editor.quit", "CTRL+Q", ShortcutType.Window)]
	private void Quit()
	{
		Close();
	}

	[Shortcut("editor.save", "Ctrl+S", ShortcutType.Window)]
	public async void SaveAsset()
	{
		if (_asset != null)
		{
			await _asset.CompileIfNeededAsync();

			if (_selector.IsValid())
			{
				_selector.Rebuild();
			}
		}
		else
			return;
	}

	private bool OnMenuBarPaint()
	{
		Paint.SetBrushAndPen(_menuBarColor);
		Paint.DrawRect(MenuWidget.LocalRect);

		return false;
	}

	public void SelectMember(string memberName) { }
}