using System; using AppleHills.Data.CardSystem; using Core.SaveLoad; using UnityEngine; namespace UI.CardSystem.StateMachine { /// /// Shared context for card states. /// Provides access to common components and data that states need. /// public class CardContext : MonoBehaviour { [Header("Core Components")] [SerializeField] private CardDisplay cardDisplay; [SerializeField] private CardAnimator cardAnimator; private AppleMachine stateMachine; [Header("Card Data")] private CardData cardData; // Public accessors public CardDisplay CardDisplay => cardDisplay; public CardAnimator Animator => cardAnimator; public AppleMachine StateMachine => stateMachine; public Transform RootTransform => transform; public CardData CardData => cardData; // Runtime state public bool IsClickable { get; set; } = true; public bool SuppressRevealBadges { get; set; } = false; // Set by states to suppress NEW/REPEAT badges in revealed state // Original transform data (captured on spawn for shrink animations) public Vector3 OriginalScale { get; private set; } public Vector3 OriginalPosition { get; private set; } public Quaternion OriginalRotation { get; private set; } // Single event for reveal flow completion public event Action OnRevealFlowComplete; // Generic drag event - fired when drag starts, consumers decide how to handle based on current state public event Action OnDragStarted; // Generic drag end event - fired when drag ends, consumers decide how to handle based on current state public event Action OnDragEnded; private bool _hasCompletedReveal = false; public bool HasCompletedReveal => _hasCompletedReveal; // Helper method for states to signal completion public void NotifyRevealComplete() { if (!_hasCompletedReveal) { _hasCompletedReveal = true; OnRevealFlowComplete?.Invoke(this); } } // Helper method for states/card to signal drag started public void NotifyDragStarted() { OnDragStarted?.Invoke(this); } // Helper method for states/card to signal drag ended public void NotifyDragEnded() { OnDragEnded?.Invoke(this); } private void Awake() { // Auto-find components if not assigned if (cardDisplay == null) cardDisplay = GetComponentInChildren(); if (cardAnimator == null) cardAnimator = GetComponent(); if (stateMachine == null) stateMachine = GetComponentInChildren(); } private void OnEnable() { // Subscribe to CardDisplay click and route to active state if (cardDisplay != null) { cardDisplay.OnCardClicked += HandleCardDisplayClicked; } } private void OnDisable() { if (cardDisplay != null) { cardDisplay.OnCardClicked -= HandleCardDisplayClicked; } } private void HandleCardDisplayClicked(CardDisplay _) { // Gate by clickability if (!IsClickable) return; if (stateMachine == null || stateMachine.currentState == null) return; var handler = stateMachine.currentState.GetComponent(); if (handler != null) { handler.OnCardClicked(this); } } /// /// Setup the card with data /// public void SetupCard(CardData data) { cardData = data; _hasCompletedReveal = false; // Reset completion flag // Capture original transform for shrink animations. // If current scale is ~0 (pop-in staging), default to Vector3.one. var currentScale = transform.localScale; if (currentScale.x < 0.01f && currentScale.y < 0.01f && currentScale.z < 0.01f) { OriginalScale = Vector3.one; } else { OriginalScale = currentScale; } OriginalPosition = transform.localPosition; OriginalRotation = transform.localRotation; if (cardDisplay != null) { cardDisplay.SetupCard(data); } } /// /// Get the card display component /// public CardDisplay GetCardDisplay() => cardDisplay; } }