// Project Lab - NHTV Igad

#include "UnrealProject.h"
#include "AbilityButton.h"
#include "ButtonBarSwitcher.h"
#include "BaseSkillObject.h"
#include "AbilityState.h"
#include "NetworkPlayer.h"
#include "IngameSkillTree.h"
#include "AbilityInfo.h"

void UButtonBarSwitcher::NativeConstruct()
{
	Super::NativeConstruct();

	m_globalEnable = true;
	m_alternateSkillSet = false;
	m_FindAndAddButtonBar("ButtonBarMain");
	m_FindAndAddButtonBar("ButtonBarAlt");
}

bool UButtonBarSwitcher::AssignSkillButton(const FIngameSkillTreeSkill& skill, bool isAlt)
{
	if (m_mappedButtons.Find(skill.selectedEffect))
		return true;

	int32 bar = isAlt ? 1 : 0;
	if (bar >= m_buttonBars.Num())
		return false;

	UAbilityButton* targetButton;
	if(!m_buttonBars[bar]->AssignSkillButton(skill, targetButton, isAlt))
	{
		GERROR("Too many skills, can't assign " + skill.selectedEffect->GetName() + " to bar " + bar);
		return false;
	}

	m_mappedButtons.Add(skill.selectedEffect, targetButton);
	return true;
}

void UButtonBarSwitcher::UpdateCooldowns(TArray<class AAbilityState*> abilityStates, ANetworkPlayer* player)
{
	for (int32 i = 0; i < abilityStates.Num(); i++)
	{
		UAbilityButton** button = m_mappedButtons.Find(abilityStates[i]->info);
		if (button)
		{
			(*button)->UpdateState(abilityStates[i], player);
		}
	}
}

UButtonBar* UButtonBarSwitcher::m_FindAndAddButtonBar(const FName& name)
{
	UButtonBar* bar = Cast<UButtonBar>(WidgetTree->FindWidget(name));
	if (bar)
	{
		m_buttonBars.Add(bar);
	}
	return bar;
}

void UButtonBarSwitcher::SetSkillButtonEnabled(const FIngameSkillTreeSkill& skill, bool enabled)
{
	UAbilityButton** button = m_mappedButtons.Find(skill.selectedEffect);
	if (button)
	{
		(*button)->SetButtonEnabled(enabled);
	}
}

void UButtonBarSwitcher::SetGlobalEnable(bool enabled)
{
	for(UButtonBar* bb : m_buttonBars)
	{
		bb->SetGlobalEnable(enabled);
	}
}

class UAbilityInfo* UButtonBarSwitcher::GetAbilityMapping(int32 index)
{
	if(m_buttonBars.Num() != 2)
	{
		GERROR("m_buttonBars.Num() != 2");
		return nullptr;
	}
	UButtonBar* currentBar = m_buttonBars[m_alternateSkillSet ? 1 : 0];
	if(index < 0 || index >= currentBar->buttons.Num())
		return nullptr;
	return currentBar->buttons[index]->GetAbility();
}
class UAbilityInfo* UButtonBarSwitcher::GetAbilityMapping(int32 index, bool isAlt)
{
	if(m_buttonBars.Num() != 2)
	{
		GERROR("m_buttonBars.Num() != 2");
		return nullptr;
	}
	UButtonBar* currentBar = m_buttonBars[isAlt ? 1 : 0];
	if(index < 0 || index >= currentBar->buttons.Num())
		return nullptr;
	return currentBar->buttons[index]->GetAbility();
}

void UButtonBarSwitcher::TransitionToAlternateSkillSet_Implementation()
{
}
void UButtonBarSwitcher::TransitionToMainSkillSet_Implementation()
{
}
void UButtonBarSwitcher::ToggleSkillSet(bool useAlternateSkillSet)
{
	if (m_alternateSkillSet != useAlternateSkillSet)
	{
		if(useAlternateSkillSet)
			TransitionToAlternateSkillSet();
		else
			TransitionToMainSkillSet();
		m_alternateSkillSet = useAlternateSkillSet;
	}
}

void UButtonBar::NativeConstruct()
{
	TArray<UWidget*> widgets;
	WidgetTree->GetAllWidgets(widgets);
	for (int32 i = 0; i < widgets.Num(); i++)
	{
		UAbilityButton* button = Cast<UAbilityButton>(widgets[i]);
		if (button)
		{
			buttons.Add(button);
		}
	}
}

bool UButtonBar::AssignSkillButton(const FIngameSkillTreeSkill& skill, class UAbilityButton*& buttonOut, bool alt)
{
	for (int32 i = 0; i < buttons.Num(); i++)
	{
		if (buttons[i]->IsAssigned())
			continue;
		buttonOut = buttons[i];
		buttonOut->InitButton(skill.selectedEffect, i, alt);
		return true;
	}
	return false;
}

void UButtonBar::SetGlobalEnable(bool enabled)
{
	for(UAbilityButton* button : buttons)
	{
		if(button)
		{
			button->SetGlobalEnable(enabled);
		}
	}
}
