#pragma once

#include "CoreMinimal.h"
#include "LockedFeatureElementViewInterface.h"
#include "CoreBaseUserWidget.h"
#include "EAnalogCursorStickiness.h"
#include "Framework/Text/TextLayout.h"
#include "DBDFeatureLockProgress.h"
#include "EDBDFeatureType.h"
#include "EButtonWidgetVisibility.h"
#include "UObject/SoftObjectPtr.h"
#include "Layout/Geometry.h"
#include "CoreButtonWidget.generated.h"

class UDBDImage;
class UDBDButton;
class UDBDTextBlock;
class UAkAudioEvent;
class UCurveFloat;
class UMaterialInstance;
class UTexture2D;
class UCoreButtonWidget;

UCLASS(Blueprintable, EditInlineNew)
class DBDUIVIEWSCORE_API UCoreButtonWidget : public UCoreBaseUserWidget, public ILockedFeatureElementViewInterface
{
	GENERATED_BODY()

public:
	DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnUnhoveredDelegate, UCoreButtonWidget*, buttonTarget);

	DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnReleasedDelegate, UCoreButtonWidget*, buttonTarget);

	DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnPressedDelegate, UCoreButtonWidget*, buttonTarget);

	DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnHoveredDelegate, UCoreButtonWidget*, buttonTarget);

	DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnClickedDelegate, UCoreButtonWidget*, buttonTarget);

	DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FOnButtonVisibilityChangedDelegate, const EButtonWidgetVisibility, previousVisibility, const EButtonWidgetVisibility, newVisibility);

public:
	UPROPERTY(BlueprintReadWrite, meta=(BindWidgetOptional))
	UDBDImage* BackgroundIMG;

	UPROPERTY(BlueprintReadWrite, meta=(BindWidgetOptional))
	UDBDImage* AdditionalIconIMG;

	UPROPERTY(BlueprintReadWrite, BlueprintAssignable)
	FOnHoveredDelegate OnHoveredDelegate;

	UPROPERTY(BlueprintReadWrite, BlueprintAssignable)
	FOnUnhoveredDelegate OnUnhoveredDelegate;

	UPROPERTY(BlueprintReadWrite, BlueprintAssignable)
	FOnPressedDelegate OnPressedDelegate;

	UPROPERTY(BlueprintReadWrite, BlueprintAssignable)
	FOnReleasedDelegate OnReleasedDelegate;

	UPROPERTY(BlueprintReadWrite, BlueprintAssignable)
	FOnClickedDelegate OnClickedDelegate;

	UPROPERTY(BlueprintReadWrite, BlueprintAssignable)
	FOnButtonVisibilityChangedDelegate OnButtonVisibilityChangedDelegate;

	UPROPERTY(EditAnywhere, BlueprintReadWrite)
	EAnalogCursorStickiness AnalogCursorStickiness;

protected:
	UPROPERTY(BlueprintReadWrite, meta=(BindWidgetOptional))
	UDBDButton* HitzoneButton;

	UPROPERTY(BlueprintReadWrite, meta=(BindWidgetOptional))
	UDBDTextBlock* LabelTB;

	UPROPERTY(EditAnywhere, BlueprintReadWrite)
	TEnumAsByte<ETextJustify::Type> _alignment;

	UPROPERTY(EditAnywhere, BlueprintReadWrite)
	FString HoveredSfxName;

	UPROPERTY(EditAnywhere, BlueprintReadWrite)
	UAkAudioEvent* HoveredSfx;

	UPROPERTY(EditAnywhere, BlueprintReadWrite)
	FString PressedSfxName;

	UPROPERTY(EditAnywhere, BlueprintReadWrite)
	UAkAudioEvent* PressedSfx;

	UPROPERTY(EditAnywhere, BlueprintReadWrite)
	FString StartedChargingSfxName;

	UPROPERTY(EditAnywhere, BlueprintReadWrite)
	UAkAudioEvent* StartedChargingSfx;

	UPROPERTY(EditAnywhere, BlueprintReadWrite)
	FString CancelledChargingSfxName;

	UPROPERTY(EditAnywhere, BlueprintReadWrite)
	UAkAudioEvent* CancelledChargingSfx;

	UPROPERTY(EditAnywhere, BlueprintReadWrite)
	FString CompletedChargingSfxName;

	UPROPERTY(EditAnywhere, BlueprintReadWrite)
	UAkAudioEvent* CompletedChargingSfx;

	UPROPERTY(EditAnywhere, BlueprintReadWrite)
	FString ClickedSfxName;

	UPROPERTY(EditAnywhere, BlueprintReadWrite)
	UAkAudioEvent* ClickedSfx;

	UPROPERTY(EditAnywhere, BlueprintReadWrite)
	FDBDFeatureLockProgress _lockedFeatureData;

	UPROPERTY(EditAnywhere, BlueprintReadWrite)
	bool _isFeatureGatingEnabled;

	UPROPERTY(EditAnywhere, BlueprintReadWrite)
	EDBDFeatureType _lockedFeatureType;

private:
	UPROPERTY(EditInstanceOnly, BlueprintReadWrite, Transient, meta=(AllowPrivateAccess=true))
	UCurveFloat* _chargingAnimCurve;

	UPROPERTY(EditInstanceOnly, BlueprintReadWrite, Transient, meta=(AllowPrivateAccess=true))
	UCurveFloat* _repetitionDelayCurve;

	UPROPERTY(EditInstanceOnly, BlueprintReadWrite, Transient, Instanced, meta=(AllowPrivateAccess=true))
	UDBDTextBlock* _debugAnalyticsTB;

protected:
	UPROPERTY(EditAnywhere, BlueprintReadWrite)
	bool _sendAnalyticsData;

	UPROPERTY(EditAnywhere, BlueprintReadWrite)
	FString _analyticsName;

	UPROPERTY(EditAnywhere, BlueprintReadWrite)
	bool _prependCurrentTabNameToAnalyticsName;

public:
	UFUNCTION(BlueprintCallable, BlueprintNativeEvent)
	void UpdateLockedFeatureVisuals(bool isLockedFeature);

	UFUNCTION(BlueprintCallable)
	void StopRepeatInput();

	UFUNCTION(BlueprintCallable)
	void SetVisible(EButtonWidgetVisibility visible);

	UFUNCTION(BlueprintCallable)
	void SetRepeatable(bool isRepeatable, UCurveFloat* repetitionDelayCurve);

	UFUNCTION(BlueprintCallable)
	void SetPressable(bool isPressable);

	UFUNCTION(BlueprintCallable)
	void SetLabel(const FText& label);

	UFUNCTION(BlueprintCallable)
	void SetHoverable(bool isHoverable);

	UFUNCTION(BlueprintCallable)
	void SetHoldable(bool isHoldable);

	UFUNCTION(BlueprintCallable)
	void SetEnabled(bool isEnabled);

	UFUNCTION(BlueprintCallable)
	void SetClickable(bool isClickable);

	UFUNCTION(BlueprintCallable)
	void SetChargeable(bool isChargeable, UCurveFloat* holdingAnimCurve, float duration);

	UFUNCTION(BlueprintCallable)
	void SetBackground(TSoftObjectPtr<UMaterialInstance> backgroundMaterial);

	UFUNCTION(BlueprintCallable)
	void SetAlignment(ETextJustify::Type newAlignment);

	UFUNCTION(BlueprintCallable)
	void SetAdditionalIcon(TSoftObjectPtr<UTexture2D> iconTexture);

protected:
	UFUNCTION(BlueprintCallable, BlueprintImplementableEvent)
	void OnUnhovered();

	UFUNCTION(BlueprintCallable, BlueprintImplementableEvent)
	void OnReleased();

	UFUNCTION(BlueprintCallable, BlueprintImplementableEvent)
	void OnPressed();

	UFUNCTION(BlueprintCallable, BlueprintImplementableEvent)
	void OnLongPressed();

	UFUNCTION(BlueprintCallable)
	void OnInternalUnhovered();

	UFUNCTION(BlueprintCallable)
	void OnInternalReleased();

	UFUNCTION(BlueprintCallable)
	void OnInternalPressed();

	UFUNCTION(BlueprintCallable)
	void OnInternalLongPressed();

	UFUNCTION(BlueprintCallable)
	void OnInternalHovered();

	UFUNCTION(BlueprintCallable)
	void OnInternalClicked();

	UFUNCTION(BlueprintCallable, BlueprintImplementableEvent)
	void OnHovered();

	UFUNCTION(BlueprintCallable, BlueprintImplementableEvent)
	void OnEnabledChanged(bool isEnabled);

	UFUNCTION(BlueprintCallable, BlueprintImplementableEvent)
	void OnClicked();

	UFUNCTION(BlueprintCallable, BlueprintImplementableEvent)
	void OnClickableChanged(bool isClickable);

	UFUNCTION(BlueprintCallable, BlueprintImplementableEvent)
	void OnChargingTick(float progress);

	UFUNCTION(BlueprintCallable, BlueprintImplementableEvent)
	void OnChargingComplete();

	UFUNCTION(BlueprintCallable, BlueprintImplementableEvent)
	void OnButtonVisibilityChanged(const EButtonWidgetVisibility previousVisibility, const EButtonWidgetVisibility newVisibility);

	UFUNCTION(BlueprintCallable, BlueprintImplementableEvent)
	void OnAlignmentChanged(ETextJustify::Type newAlignment);

public:
	UFUNCTION(BlueprintPure)
	bool IsRepeatInputActive() const;

	UFUNCTION(BlueprintPure)
	bool IsPressed() const;

	UFUNCTION(BlueprintPure)
	bool IsEnabled() const;

	UFUNCTION(BlueprintPure)
	bool IsClickable() const;

	UFUNCTION(BlueprintPure)
	bool HasValidLockedFeatureData() const;

	UFUNCTION(BlueprintPure)
	FGeometry GetHitzonePaintSpaceGeometry() const;

public:
	UCoreButtonWidget();
};

FORCEINLINE uint32 GetTypeHash(const UCoreButtonWidget) { return 0; }
