using System.Collections.Generic;
using System.IO;
using System.Linq;
using AppleHills.Data.CardSystem;
using UI.CardSystem;
using UnityEditor;
using UnityEngine;
using UnityEngine.UI;
namespace Editor.CardSystem
{
///
/// Editor utility for managing card definitions with live preview using the same UI as in-game.
///
public class CardEditorWindow : EditorWindow
{
// Paths
private const string CardDefinitionsPath = "Assets/Data/Cards";
private const string MenuPath = "AppleHills/Card Editor";
private const string CardUIPrefabPath = "Assets/Prefabs/UI/Cards/Card.prefab";
private const string CardVisualConfigPath = CardDefinitionsPath + "/CardVisualConfig.asset";
// Preview settings
private static readonly Vector2 PreviewCardSize = new Vector2(200f, 300f);
private const float CameraPaddingFactor = 1.2f;
// Editor state
private List _cards = new List();
private CardDefinition _selectedCard;
private CardDefinition _editingCard;
private Vector2 _cardListScrollPosition;
private Vector2 _cardEditScrollPosition;
private string _searchQuery = "";
private bool _showPreview = true;
private bool _isDirty = false;
// Preview state
private PreviewRenderUtility _previewUtility;
private GameObject _previewRoot;
private CardDisplay _previewCardDisplay;
private GameObject _cardUIPrefab;
private CardVisualConfig _cardVisualConfig;
private float _zoomLevel = 1.0f;
[MenuItem(MenuPath)]
public static void ShowWindow()
{
var window = GetWindow("Card Editor");
window.minSize = new Vector2(1000, 700);
window.Show();
}
private void OnEnable()
{
LoadCardDefinitions();
InitializePreview();
Undo.undoRedoPerformed += OnUndoRedo;
}
private void OnDisable()
{
CleanupPreview();
Undo.undoRedoPerformed -= OnUndoRedo;
}
private void OnUndoRedo()
{
LoadCardDefinitions();
Repaint();
}
private void LoadCardDefinitions()
{
_cards.Clear();
// Ensure directory exists
if (!Directory.Exists(CardDefinitionsPath))
{
Directory.CreateDirectory(CardDefinitionsPath);
AssetDatabase.Refresh();
}
// Find all card definitions
string[] guids = AssetDatabase.FindAssets("t:CardDefinition", new[] { CardDefinitionsPath });
foreach (string guid in guids)
{
string path = AssetDatabase.GUIDToAssetPath(guid);
CardDefinition card = AssetDatabase.LoadAssetAtPath(path);
if (card != null)
{
_cards.Add(card);
}
}
_cards = _cards.OrderBy(c => c.Name).ToList();
// Restore selection if possible
if (_selectedCard != null)
{
_selectedCard = _cards.FirstOrDefault(c => c.Id == _selectedCard.Id);
if (_selectedCard != null)
{
_editingCard = CloneCard(_selectedCard);
UpdatePreview();
}
}
}
private void InitializePreview()
{
if (_previewUtility == null)
{
_previewUtility = new PreviewRenderUtility();
var cam = _previewUtility.camera;
cam.clearFlags = CameraClearFlags.SolidColor;
cam.backgroundColor = new Color(0.2f, 0.2f, 0.2f);
cam.orthographic = true;
// Calculate ortho size based on card height with padding
float baseOrthoSize = (PreviewCardSize.y / 2f) * CameraPaddingFactor;
cam.orthographicSize = baseOrthoSize;
cam.nearClipPlane = 0.01f;
cam.farClipPlane = 100f;
cam.transform.position = new Vector3(0, 0, -10);
cam.transform.rotation = Quaternion.identity;
}
// Load prefab and config
_cardUIPrefab = AssetDatabase.LoadAssetAtPath(CardUIPrefabPath);
if (_cardUIPrefab == null)
{
Debug.LogError($"[CardEditorWindow] Card UI prefab not found at {CardUIPrefabPath}");
}
_cardVisualConfig = AssetDatabase.LoadAssetAtPath(CardVisualConfigPath);
if (_cardVisualConfig == null)
{
Debug.LogWarning($"[CardEditorWindow] Card visual config not found at {CardVisualConfigPath}");
}
CreatePreviewCardObject();
}
private void CreatePreviewCardObject()
{
CleanupPreviewInstance();
if (_cardUIPrefab == null || _previewUtility == null)
return;
try
{
// Create root and canvas
_previewRoot = new GameObject("PreviewRoot");
_previewRoot.hideFlags = HideFlags.HideAndDontSave;
GameObject canvasGO = new GameObject("PreviewCanvas");
canvasGO.transform.SetParent(_previewRoot.transform, false);
Canvas canvas = canvasGO.AddComponent