using System;
using System.Collections.Generic;
using System.Linq;
using Jovian.EncounterSystem;
using UnityEditor;
using UnityEditor.UIElements;
using UnityEngine;
using UnityEngine.UIElements;
namespace Jovian.EncounterSystem.Editor {
/// Browser for every encounter across all tables. Search + kind filter + detail pane. Quest chains render as a tree rooted at the first step.
public class EncounterBrowserWindow : EditorWindow {
private const string AllKinds = "All";
private class Record {
public EncounterTable table;
public int index;
public IEncounter encounter;
public int depth;
public bool IsTableHeader => encounter == null;
}
private static readonly Color[] DepthColors = {
new(0.35f, 0.55f, 0.85f), // depth 0 — table headers (blue)
new(0.90f, 0.90f, 0.90f), // depth 1 — encounters under table (neutral)
new(0.70f, 0.90f, 0.55f), // depth 2 — chain step 1 (green)
new(0.95f, 0.80f, 0.45f), // depth 3 — chain step 2 (amber)
new(0.85f, 0.65f, 0.90f) // depth 4+ — deeper chain (violet)
};
private readonly List allRecords = new();
private string searchText = string.Empty;
private string kindFilter = AllKinds;
private readonly Dictionary> issuesByEncounter = new();
private TreeView treeView;
private VisualElement detailPane;
private ToolbarMenu kindDropdown;
private VisualElement statusBanner;
[MenuItem("Jovian/Encounters/Encounter Browser")]
public static void Open() {
var window = GetWindow("Encounters");
window.minSize = new Vector2(640, 360);
}
private void CreateGUI() {
BuildToolbar();
BuildSplit();
Refresh();
}
private void BuildToolbar() {
var toolbar = new Toolbar();
var search = new ToolbarSearchField();
search.style.flexGrow = 1f;
search.RegisterValueChangedCallback(evt => {
searchText = evt.newValue ?? string.Empty;
ApplyFilter();
});
toolbar.Add(search);
kindDropdown = new ToolbarMenu { text = $"Kind: {AllKinds}" };
foreach(var choice in GetKindChoices()) {
var captured = choice;
kindDropdown.menu.AppendAction(captured, _ => {
kindFilter = captured;
kindDropdown.text = $"Kind: {captured}";
ApplyFilter();
});
}
toolbar.Add(kindDropdown);
var refreshButton = new ToolbarButton(Refresh) { text = "Refresh" };
toolbar.Add(refreshButton);
rootVisualElement.Add(toolbar);
}
private void BuildSplit() {
statusBanner = new VisualElement {
style = {
paddingLeft = 10,
paddingRight = 10,
paddingTop = 8,
paddingBottom = 8,
marginBottom = 2,
flexDirection = FlexDirection.Column,
backgroundColor = new StyleColor(new Color(0.85f, 0.4f, 0.15f, 0.35f)),
display = DisplayStyle.None
}
};
rootVisualElement.Add(statusBanner);
var split = new VisualElement {
style = {
flexDirection = FlexDirection.Row,
flexGrow = 1f
}
};
rootVisualElement.Add(split);
treeView = new TreeView {
makeItem = MakeRow,
bindItem = BindRow,
fixedItemHeight = 22,
selectionType = SelectionType.Single
};
treeView.selectionChanged += OnSelectionChanged;
treeView.style.width = 280;
treeView.style.flexShrink = 0f;
treeView.style.borderRightWidth = 1;
treeView.style.borderRightColor = new StyleColor(new Color(0f, 0f, 0f, 0.4f));
split.Add(treeView);
detailPane = new ScrollView(ScrollViewMode.Vertical) {
style = { paddingLeft = 8, paddingTop = 8, paddingRight = 8, flexGrow = 1f }
};
ShowEmptyDetail();
split.Add(detailPane);
}
private static VisualElement MakeRow() {
var row = new VisualElement {
style = {
flexDirection = FlexDirection.Row,
alignItems = Align.Center,
paddingLeft = 6,
paddingRight = 6,
height = 22,
flexGrow = 1f,
flexShrink = 0f
}
};
var badge = new VisualElement {
name = "issue-badge",
style = {
width = 8,
height = 8,
marginRight = 6,
borderTopLeftRadius = 4,
borderTopRightRadius = 4,
borderBottomLeftRadius = 4,
borderBottomRightRadius = 4,
visibility = Visibility.Hidden
}
};
row.Add(badge);
var label = new Label {
name = "row-label",
style = {
flexGrow = 1f,
unityTextAlign = TextAnchor.MiddleLeft
}
};
row.Add(label);
var selectButton = new Button {
name = "select-button",
text = "Select",
style = {
marginLeft = 4,
marginRight = 0,
paddingLeft = 6,
paddingRight = 6,
display = DisplayStyle.None
}
};
row.Add(selectButton);
return row;
}
private void BindRow(VisualElement element, int index) {
var record = treeView.GetItemDataForIndex(index);
var label = element.Q