using Anazir.UI.MainMenu;
using UnityEngine;
using UnityEngine.Assertions;
using UnityEngine.UI;
using TMPro;
using DG.Tweening;
using System.Collections;
using System;
using Anazir.UI.HeroInventory;
using System.Collections.Generic;
using BrainFailProductions.PolyFew;
namespace Anazir.UI
{
public class DeckEditorSection : UISection
{
public static CardController SelectedCard { private set; get; }
public readonly Deck EditorDeck = new();
[SerializeField] GameObject m_leaveWithoutSavingPopup;
[SerializeField] GameObject m_golemsSection, m_heroesSection;
[SerializeField] private Transform m_deck;
[SerializeField] private Transform m_ownedHeroesParent;
[SerializeField] Button m_save;
[SerializeField] Button m_golems, m_heros;
[SerializeField] Button m_modifyGolems;
[SerializeField] Button m_modifyHeroes;
[SerializeField] private RectTransform m_headerMenu;
[SerializeField] private RectTransform m_headerBackground;
[SerializeField] private GameObject[] m_hideWhenModifyGolems;
[SerializeField] private GameObject[] m_showWhenModifyGolems;
[SerializeField] private GameObject[] m_hideWhenModifyHeroes;
[SerializeField] private GameObject[] m_showWhenModifyHeroes;
[SerializeField] private UIGolemDesc m_golemDesc;
[SerializeField] private HeroItemController m_selectedHero;
[SerializeField] private HeroItemController heroItem;
[SerializeField] private HeroViewerController m_heroViewerController;
[SerializeField] private TextMeshProUGUI m_golemsCount, m_heroesCount;
[SerializeField] private VerticalLayoutGroup m_golemContent;
private bool isModifyingGolems;
private bool isModifyingHeroes;
private Hero.ID m_heroID;
private List<HeroItemController> m_listHeroes = new List<HeroItemController>();
private int m_deckParentIndex;
private Transform m_deckParentTransform;
private Button lastButtonClicked;
private CardController cardSelectedToSwap;
private Button m_golemDescButton => m_golemDesc.gameObject.GetComponent<Button>();
private CanvasGroup m_golemDescCanvasGroup => m_golemDesc.gameObject.GetComponent<CanvasGroup>();
private VerticalLayoutGroup m_heroesSectionLayout => m_heroesSection.GetComponent<VerticalLayoutGroup>();
private VerticalLayoutGroup m_headerMenuLayout => m_headerMenu.GetComponent<VerticalLayoutGroup>();
private RectTransform m_golemsSectionRectTransform => m_golemsSection.GetComponent<RectTransform>();
private RectTransform m_heroesSectionRectTransform => m_heroesSection.GetComponent<RectTransform>();
void OnEnable()
{
EditorDeck.Changed += OnEditorDeckChanged;
CardController.OnClick += OnCardClick;
CardController.OnSelfHoldRelease += ShowCardDescription;
m_save.onClick.AddListener(Save);
m_golems.onClick.AddListener(LoadGolemSection);
m_heros.onClick.AddListener(LoadHerosSection);
m_modifyGolems.onClick.AddListener(ModifyGolems);
m_modifyHeroes.onClick.AddListener(ModifyHeroes);
m_golemDescButton.onClick.AddListener(HideCardDescription);
LoadGolemSection();
m_golemsCount.text = "(" + (PlayerData.Singleton.Golems.Count - 8) + ")";
m_heroesCount.text = "(" + (PlayerData.Singleton.Heroes.Count - 1) + ")";
}
void OnDisable()
{
EditorDeck.Changed -= OnEditorDeckChanged;
CardController.OnClick -= OnCardClick;
CardController.OnSelfHoldRelease -= ShowCardDescription;
m_save.onClick.RemoveListener(Save);
m_golems.onClick.RemoveListener(LoadGolemSection);
m_heros.onClick.RemoveListener(LoadHerosSection);
m_modifyGolems.onClick.RemoveListener(ModifyGolems);
m_modifyHeroes.onClick.RemoveListener(ModifyHeroes);
m_golemDescButton.onClick.RemoveListener(HideCardDescription);
}
void OnEditorDeckChanged()
{
m_save.interactable = EditorDeck.IsValid;
}
void OnValidate() => CanHide = true;
public override void Hide()
{
if (EditorDeck.IsValid)
{
EditorDeck.CopyTo(PlayerData.Singleton.Deck);
Leave();
}
else
{
m_leaveWithoutSavingPopup.SetActive(true);
}
}
public void LeaveWithoutSaving()
{
m_leaveWithoutSavingPopup.SetActive(false);
Leave();
}
private void Save()
{
if (isModifyingGolems)
{
Assert.IsTrue(EditorDeck.IsValid,"Save button shouldn't be interactible if deck is not valid");
EditorDeck.CopyTo(PlayerData.Singleton.Deck);
UnityCloudManager.SetDeck();
if (cardSelectedToSwap is not null)
{
cardSelectedToSwap.ToggleHighlight(false);
cardSelectedToSwap = null;
}
RemoveModifyGolems();
}
else if (isModifyingHeroes)
{
m_selectedHero.ChangePlayerHero();
RemoveModifyHeroes();
UpdateHeroesSection();
}
}
void Leave()
{
gameObject.SetActive(false);
if(ParentSection != null)
{
CurrentSection = ParentSection;
ParentSection.Show();
}
if (SelectedCard is not null) HideCardDescription();
ExitCallback?.Invoke();
}
private void ModifyGolems()
{
isModifyingGolems = true;
HideElements(m_hideWhenModifyGolems);
ShowElements(m_showWhenModifyGolems);
m_headerMenuLayout.spacing += 80;
m_headerBackground.sizeDelta += new Vector2(0, 700);
m_headerBackground.localPosition -= new Vector3(0, 350, 0);
m_golemContent.padding.top += 460;
RebuildLayout(m_golemsSectionRectTransform);
m_deckParentTransform = m_deck.parent;
m_deckParentIndex = m_deck.GetSiblingIndex();
m_deck.parent = m_headerMenu;
}
private void RemoveModifyGolems()
{
isModifyingGolems = false;
HideElements(m_showWhenModifyGolems);
ShowElements(m_hideWhenModifyGolems);
m_headerMenuLayout.spacing -= 80;
m_headerBackground.sizeDelta -= new Vector2(0, 700);
m_headerBackground.localPosition += new Vector3(0, 350, 0);
m_golemContent.padding.top -= 460;
RebuildLayout(m_golemsSectionRectTransform);
m_deck.parent = m_deckParentTransform;
m_deck.SetSiblingIndex(m_deckParentIndex);
}
private void ModifyHeroes()
{
isModifyingHeroes = true;
m_selectedHero.IsModifying(true);
HideElements(m_hideWhenModifyHeroes);
ShowElements(m_showWhenModifyHeroes);
m_headerMenu.sizeDelta -= new Vector2(0, 200);
m_headerMenu.localPosition += new Vector3(0, 100, 0);
m_heroesSectionLayout.padding.top -= 160;
RebuildLayout(m_heroesSectionRectTransform);
}
private void RemoveModifyHeroes()
{
isModifyingHeroes = false;
m_selectedHero.IsModifying(false);
HideElements(m_showWhenModifyHeroes);
ShowElements(m_hideWhenModifyHeroes);
m_headerMenu.sizeDelta += new Vector2(0, 200);
m_headerMenu.localPosition -= new Vector3(0, 100, 0);
m_heroesSectionLayout.padding.top += 160;
RebuildLayout(m_heroesSectionRectTransform);
}
private void HideElements(GameObject[] _gos)
{
foreach (GameObject go in _gos)
{
go.SetActive(false);
}
}
private void ShowElements(GameObject[] _gos)
{
foreach (GameObject go in _gos)
{
go.SetActive(true);
}
}
public void RebuildLayout(RectTransform _rectTransform)
{
StartCoroutine(DelayedRebuildLayout(_rectTransform));
}
private IEnumerator DelayedRebuildLayout(RectTransform _rectTransform)
{
yield return null;
LayoutRebuilder.MarkLayoutForRebuild(_rectTransform);
}
private void LoadGolemSection()
{
if (lastButtonClicked == m_golems) return;
lastButtonClicked = m_golems;
UnloadAllSections();
m_golems.targetGraphic.DOFade(1f, 0.5f);
m_golemsSection.SetActive(true);
PlayerData.Singleton.Deck.CopyTo(EditorDeck);
}
public void LoadHerosSection()
{
if (lastButtonClicked == m_heros) return;
lastButtonClicked = m_heros;
UnloadAllSections();
m_heros.targetGraphic.DOFade(1f, 0.5f);
m_heroesSection.SetActive(true);
UpdateHeroesSection();
}
private void UnloadAllSections()
{
m_golems.targetGraphic.DOFade(0.2f, 0.5f);
m_heros.targetGraphic.DOFade(0.2f, 0.5f);
m_golemsSection.SetActive(false);
m_heroesSection.SetActive(false);
}
private void OnCardClick(CardController _card)
{
if (isModifyingGolems)
{
SwapCard(_card);
}
else
{
GolemViewer.View(_card.GolemID);
}
}
private void SwapCard(CardController _card)
{
if (!cardSelectedToSwap)
{
cardSelectedToSwap = _card;
cardSelectedToSwap.ToggleHighlight(true);
}
else
{
if (cardSelectedToSwap.Container != _card.Container)
{
SwapCardAnimation(_card, cardSelectedToSwap);
}
cardSelectedToSwap.ToggleHighlight(false);
cardSelectedToSwap = null;
}
}
private void SwapCardAnimation(CardController _card1, CardController _card2)
{
Vector3 position1 = _card1.transform.position;
Vector3 position2 = _card2.transform.position;
float arcHeight = 0.5f;
float swapDuration = 0.5f;
Vector3 arcDirection = Vector3.Cross((position1 - position2).normalized, Vector3.forward);
Vector3 midpoint = (position1 + position2) / 2;
Vector3 arcOffset = arcDirection * arcHeight;
// Create the paths for the arc
Vector3[] pathA = new Vector3[] { position1, midpoint - arcOffset, position2 };
Vector3[] pathB = new Vector3[] { position2, midpoint + arcOffset, position1 };
_card1.transform.DOPath(pathA, swapDuration, PathType.CatmullRom)
.OnComplete(() => ResetCardPosition(_card1, position1, _card2));
_card2.transform.DOPath(pathB, swapDuration, PathType.CatmullRom)
.OnComplete(() => ResetCardPosition(_card2, position2, _card1));
}
private void ResetCardPosition(CardController _card, Vector3 _position, CardController _otherCard)
{
_card.transform.position = _position;
if (_card.Container == CardController.ContainerType.Deck)
{
EditorDeck.ReplaceOne(_card.GolemID, _otherCard.GolemID);
}
}
private void ShowCardDescription(CardController _card)
{
if (!SettingsManager.InGameCardDescription)
return;
SelectedCard = _card;
m_golemDesc.Init(_card.GolemID);
m_golemDesc.Show();
m_golemDescCanvasGroup.blocksRaycasts = true;
}
public void HideCardDescription()
{
m_golemDesc.Hide();
SelectedCard = null;
m_golemDescCanvasGroup.blocksRaycasts = false;
}
private void UpdateHeroesSection()
{
m_heroID = (Hero.ID)PlayerData.Singleton.Hero;
m_selectedHero.HeroID = m_heroID;
m_selectedHero.SetHeroViewer(m_heroViewerController);
m_listHeroes.Clear();
m_listHeroes.Add(m_selectedHero);
//Replace owned heroes
foreach (Transform _child in m_ownedHeroesParent)
{
Destroy(_child.gameObject);
}
foreach (Hero.ID _heroID in PlayerData.Singleton.Heroes)
{
// Ignore selected hero
if (_heroID == m_heroID) continue;
var item = Instantiate(heroItem, m_ownedHeroesParent);
item.HeroID = _heroID;
m_listHeroes.Add(item);
}
m_selectedHero.UpdateList(m_listHeroes);
}
}
}