#include "UnrealProject.h"
#include "MenuSlider.h"
#include "SizeBorder.h"

void UMenuSliderButton::NativeConstruct()
{
	m_button = Cast<UButton>(WidgetTree->FindWidget("Button"));
	m_dragBorder = Cast<UBorder>(WidgetTree->FindWidget("DragBorder"));
	m_text = Cast<UTextBlock>(WidgetTree->FindWidget("Text"));
	m_button->OnPressed.AddDynamic(this, &UMenuSliderButton::m_OnPressed);
	m_panel = Cast<UCanvasPanel>(GetParent());

	m_dragging = false;

	Super::NativeConstruct();
	SetSelected(false);
}
void UMenuSliderButton::NativeTick(const FGeometry& MyGeometry, float InDeltaTime)
{
	UCanvasPanelSlot* canvasSlot = Cast<UCanvasPanelSlot>(Slot);
	canvasSlot->SetAlignment(FVector2D(0.0f, 0.0f));

	if(m_parent)
	{
		float totalPixelWidth = m_parent->m_sizeBorder->pixelSize.X;
		float totalWidth = m_parent->m_sizeBorder->viewportSize.X;
		float totalHeight = m_parent->m_sizeBorder->viewportSize.Y;

		float buttonSize = totalWidth * 0.2f;
		totalPixelWidth -= totalPixelWidth * 0.2f;
		totalWidth -= buttonSize;

		if(m_dragging)
		{
			float mouseX, mouseY;
			GetOwningPlayer()->GetMousePosition(mouseX, mouseY);
			float delta = (mouseX - m_dragStart.X) / (totalPixelWidth);
			m_parent->value = FMath::Clamp(m_dragStartValue + delta, 0.0f, 1.0f);

			if(!m_dragBorder->IsHovered() && !m_button->IsHovered())
			{
				m_EndDrag();
			}
			UpdateText();
		}

		canvasSlot->SetPosition(FVector2D(m_parent->value * totalWidth, 0.0f));
		canvasSlot->SetSize(FVector2D(buttonSize, totalHeight));
	}
	Super::NativeTick(MyGeometry, InDeltaTime);
}

void UMenuSliderButton::UpdateText()
{
	FString txt = FString::FromInt((int)(m_parent->value * 100)) + "%";
	m_text->SetText(FText::FromString(txt));
}

void UMenuSliderButton::SetSelected(bool selected)
{
	if(selected)
	{
		m_button->SetBackgroundColor(FLinearColor(0.3f, 0.3f, 1.0f, 0.8f));
	}
	else
	{
		m_button->SetBackgroundColor(FLinearColor(0.7f, 0.7f, 0.7f, 0.8f));
	}
}

void UMenuSliderButton::m_OnPressed()
{
	float mouseX, mouseY;
	if(m_parent)
	{
		GetOwningPlayer()->GetMousePosition(mouseX, mouseY);
		m_dragStart = FVector2D(mouseX, mouseY);
		m_dragStartValue = m_parent->value;
		m_dragging = true;
		m_dragBorder->SetVisibility(ESlateVisibility::Visible);
	}
}

void UMenuSliderButton::m_EndDrag()
{
	m_dragging = false;
	m_dragBorder->SetVisibility(ESlateVisibility::SelfHitTestInvisible);
}

FReply UMenuSliderButton::NativeOnMouseButtonUp(const FGeometry& InGeometry, const FPointerEvent& InMouseEvent)
{
	m_EndDrag();
	return FReply::Unhandled();
}

UMenuSlider::UMenuSlider(const FObjectInitializer& init)
	: Super(init)
{
	stepGranularity = 1.0f / 25;
	value = 0.5f;
}

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

	m_sizeBorder = Cast<USizeBorder>(WidgetTree->FindWidget("SizeBorder"));
	m_sliderButton = Cast<UMenuSliderButton>(WidgetTree->FindWidget("SliderButton"));
	m_sliderButton->m_parent = this;
}

void UMenuSlider::SetValue(float _value)
{
	value = FMath::Clamp(_value, 0.0f, 1.0f);
	m_sliderButton->UpdateText();
}

void UMenuSlider::NativeOnMenuAction(EMenuActionBinding binding)
{
	switch(binding)
	{
	case EMenuActionBinding::Left:
	case EMenuActionBinding::Repeat_Left:
		SetValue(value - stepGranularity);
		break;
	case EMenuActionBinding::Right:
	case EMenuActionBinding::Repeat_Right:
		SetValue(value + stepGranularity);
		break;
	}
	Super::NativeOnMenuAction(binding);
}

void UMenuSlider::NativeOnSelectionChanged(bool selected, bool controller)
{
	Super::NativeOnSelectionChanged(selected, controller);
	if(m_sliderButton)
		m_sliderButton->SetSelected(selected);
}
