using System.Collections; using CardSystem.Controllers; using Core; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.UI; using Utils; namespace CardSystem.UI.Component { /// /// Photo display slot for the album book pages. /// Pre-placed prefab that displays photos from a specific minigame category. /// Supports click-to-enlarge functionality. /// public class AlbumPhotoSlot : MonoBehaviour, IPointerClickHandler { [Header("Configuration")] [Tooltip("Which minigame category this slot displays photos from")] [SerializeField] private CaptureType captureType = CaptureType.StatueMinigame; [Header("References")] [SerializeField] private Image photoImage; [SerializeField] private GameObject loadingIndicator; [SerializeField] private GameObject emptyPlaceholder; [Header("Visual Settings")] [SerializeField] private int thumbnailSize = 256; private string _photoId; private Texture2D _currentTexture; private Texture2D _fullSizeTexture; private AlbumPhotoPageController _controller; private bool _isPopulated; public CaptureType CaptureType => captureType; public bool IsPopulated => _isPopulated; public string PhotoId => _photoId; /// /// Initialize the slot with controller reference /// public void Initialize(AlbumPhotoPageController controller) { _controller = controller; Logging.Debug($"[AlbumPhotoSlot] {gameObject.name} initialized with controller"); } /// /// When slot becomes active, request and load assigned photo from controller /// private void OnEnable() { // Only auto-load if we have a controller and haven't already populated if (_controller != null && !_isPopulated && string.IsNullOrEmpty(_photoId)) { Logging.Debug($"[AlbumPhotoSlot] {gameObject.name} became active, requesting assigned photo"); // Request our assigned photo ID from controller string assignedPhotoId = _controller.GetAssignedPhotoId(this); if (!string.IsNullOrEmpty(assignedPhotoId)) { Logging.Debug($"[AlbumPhotoSlot] {gameObject.name} assigned photoId: {assignedPhotoId}"); PopulateWithPhoto(assignedPhotoId); } else { Logging.Debug($"[AlbumPhotoSlot] {gameObject.name} has no assigned photo, showing empty state"); ShowEmptyState(); } } } /// /// Populate this slot with a photo from the minigame /// /// Photo ID to load public void PopulateWithPhoto(string photoId) { Logging.Debug($"[AlbumPhotoSlot] PopulateWithPhoto called: photoId='{photoId}', captureType={captureType}"); if (string.IsNullOrEmpty(photoId)) { Logging.Debug($"[AlbumPhotoSlot] Photo ID is null or empty, showing empty state"); ShowEmptyState(); return; } _photoId = photoId; StartCoroutine(LoadPhotoAsync(photoId)); } /// /// Load photo asynchronously to avoid frame hitches /// private IEnumerator LoadPhotoAsync(string photoId) { ShowLoadingState(); Logging.Debug($"[AlbumPhotoSlot] LoadPhotoAsync started for photoId: {photoId}, captureType: {captureType}"); // Yield to avoid loading all photos in one frame yield return null; // Load full photo Logging.Debug($"[AlbumPhotoSlot] Calling PhotoManager.LoadPhoto({captureType}, {photoId})"); Texture2D fullPhoto = PhotoManager.LoadPhoto(captureType, photoId); if (fullPhoto == null) { Logging.Warning($"[AlbumPhotoSlot] Failed to load photo: {photoId} for {captureType}"); ShowEmptyState(); yield break; } Logging.Debug($"[AlbumPhotoSlot] Photo loaded successfully! Size: {fullPhoto.width}x{fullPhoto.height}"); // Create thumbnail for display Texture2D thumbnail = PhotoManager.CreateThumbnail(fullPhoto, thumbnailSize); Logging.Debug($"[AlbumPhotoSlot] Thumbnail created: {thumbnail.width}x{thumbnail.height}"); // Store full size for enlargement _fullSizeTexture = fullPhoto; _currentTexture = thumbnail; // Display thumbnail DisplayPhoto(thumbnail); _isPopulated = true; Logging.Debug($"[AlbumPhotoSlot] Photo display complete for {photoId}"); } /// /// Display photo texture on the image component /// private void DisplayPhoto(Texture2D texture) { if (texture == null || photoImage == null) return; // Create sprite from texture Sprite photoSprite = Sprite.Create( texture, new Rect(0, 0, texture.width, texture.height), new Vector2(0.5f, 0.5f) ); photoImage.sprite = photoSprite; photoImage.enabled = true; HideLoadingState(); HideEmptyState(); } /// /// Handle click to enlarge photo /// public void OnPointerClick(PointerEventData eventData) { if (!_isPopulated || string.IsNullOrEmpty(_photoId) || _controller == null) { return; } Logging.Debug($"[AlbumPhotoSlot] Clicked photo: {_photoId} from {captureType}"); // Request enlargement from controller _controller.EnlargePhoto(this, _fullSizeTexture); } /// /// Clear the slot /// public void Clear() { _photoId = null; _isPopulated = false; if (_currentTexture != null) { Destroy(_currentTexture); _currentTexture = null; } if (_fullSizeTexture != null) { Destroy(_fullSizeTexture); _fullSizeTexture = null; } if (photoImage != null) { photoImage.sprite = null; photoImage.enabled = false; } ShowEmptyState(); } #region Visual States private void ShowLoadingState() { if (loadingIndicator != null) loadingIndicator.SetActive(true); if (photoImage != null) photoImage.enabled = false; if (emptyPlaceholder != null) emptyPlaceholder.SetActive(false); } private void HideLoadingState() { if (loadingIndicator != null) loadingIndicator.SetActive(false); } private void ShowEmptyState() { if (emptyPlaceholder != null) emptyPlaceholder.SetActive(true); if (loadingIndicator != null) loadingIndicator.SetActive(false); if (photoImage != null) photoImage.enabled = false; _isPopulated = false; } private void HideEmptyState() { if (emptyPlaceholder != null) emptyPlaceholder.SetActive(false); } #endregion private void OnDestroy() { // Cleanup textures if (_currentTexture != null) { Destroy(_currentTexture); } if (_fullSizeTexture != null) { Destroy(_fullSizeTexture); } } } }