// Project Lab - NHTV Igad

#pragma once

#include "SubMenu.h"
#include "SkillWidget.generated.h"

/**
 * 
 */
class UBaseSkillObject;
class UBorder;
class USkillTreeWidget;
class UHexagonTile;

UCLASS()
class UNREALPROJECT_API USkillWidget : public USubMenu
{
	GENERATED_BODY()
private:
	//Variables

	//Skill State
	bool m_dragable = false;
	bool m_dragging = false;
	bool m_selected = false;
	bool m_enabled = true;
	bool m_hovering = false;
	bool m_placed = false;
	bool m_controller = false;
	//SKill Widget pointers
	UCanvasPanelSlot* m_slot;
	UCanvasPanel* m_canvasPanel;
	//Positions
	FVector2D m_mousedownPos;
	FVector2D m_offset;
	FVector2D m_lastGridIndex;
	FVector2D m_lastGridPos;
	FVector2D m_hexSize;

	UPROPERTY()
	UTexture2D* m_skillIcon;

	//Hexagons
	TArray<UHexagonTile*> m_hexagons;
	float m_power;

	//Functions
	bool PointsCointainsRoot( TArray<FIntPoint>& points );
public:
	//Variables
	UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "UI" )
	UBaseSkillObject* skillAsset;

	UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "UI")
	USkillTreeWidget* parent;

	UPROPERTY(BlueprintReadOnly, Category = "UI")
	bool hovered;

	UPROPERTY(BlueprintReadOnly)
	int32 selectedEffect;

	UPROPERTY(BlueprintReadWrite, Category = "UI")
	FVector2D tooltipAreaPosition;
	UPROPERTY(BlueprintReadWrite, Category = "UI")
	FVector2D tooltipAreaSize;

	TArray<FIntPoint> placedPoints;

	UFUNCTION(BlueprintCallable, Category = "UI")
	bool IsUsingController() const { return m_controller; }

	void UpdateSkillColor();
	void UpdateSkillIcon();

	// Checks if a point is contained in on of the hexagons of this skill
	bool ContainsPoint(FVector2D screenPoint);
	// Checks if the mouse is contained within one of the hexagons
	bool ContainsMouse();

	// Updates the selected effect for this skill widget
	void SetSelectedEffect(int32 effect);
	// Return the ability info class selected by this skill widget
	class UAbilityInfo* GetSelectedEffectAbility() const;

	UFUNCTION(BlueprintImplementableEvent, Category = "UI")
	void OnRequireSkillEffect();
	UFUNCTION(BlueprintImplementableEvent, Category = "UI")
	void OnPlaceDone(bool successful);
	UFUNCTION(BlueprintImplementableEvent, Category = "UI")
	void OnStartDragging();
	UFUNCTION(BlueprintImplementableEvent, Category = "UI")
	void OnRotate();
	UFUNCTION(BlueprintImplementableEvent, Category = "UI")
	void OnMove();

	UFUNCTION( BlueprintCallable, Category = "UI" )
	void Select();
	UFUNCTION( BlueprintCallable, Category = "UI" )
	void Release()
	{
		m_selected = false;
	};
	void Deselect();
	void Enable()
	{
		m_enabled = true;
		ChangeColor( FLinearColor( 0.1216f, 0.9569f, 1.0f ) );
	}
	void Disable()
	{
		m_enabled = false;
		ChangeColor( FLinearColor::Gray );
	}
	UFUNCTION(BlueprintCallable, Category = "UI")
	void UpdateSkill();
	UFUNCTION(BlueprintCallable, Category = "UI")
	bool GetEnabled()
	{
		return m_enabled;
	}
	FVector2D GetSkillTreePos();
	FVector2D GetViewportPos();
	FVector4 GetGridPos( FVector2D in );
	FVector2D GetPositionFromIndex(FIntPoint in);
	bool CheckPosition( FVector2D in, TArray<FIntPoint>* points = NULL );
	UFUNCTION( BlueprintCallable, Category = "UI" )
	void StartDragging();
	UFUNCTION( BlueprintCallable, Category = "UI" )
	void StopDragging();

	FVector2D GetGridIndex() const
	{
		return m_lastGridIndex;
	}
	void PlaceOnGridIndex(FVector2D index);
	void SetPlaced();
	void NativeOnSkillMove();
	UFUNCTION(BlueprintCallable, Category = "UI")
	bool PlaceSkill();
	UFUNCTION(BlueprintCallable, Category = "UI")
	void Remove();
	UFUNCTION(BlueprintCallable, Category = "UI")
	bool RestartDragging();

	FLinearColor GetShapeTypeColor() const;

	UFUNCTION(BlueprintCallable, Category = "UI")
	void SetDragable( bool dragable, bool controller = false );
	UFUNCTION( BlueprintCallable, Category = "UI" )
	bool GetDragable()
	{
		return m_dragable;
	}
	UFUNCTION( BlueprintCallable, Category = "UI" )
	bool GetDragging()
	{
		return m_dragging;
	}
	UFUNCTION( BlueprintCallable, Category = "UI" )
	void SetSkillRotation( float angle );
	UFUNCTION( BlueprintCallable, Category = "UI" )
	float GetSkillRotation()
	{
		if ( m_canvasPanel ) return m_canvasPanel->RenderTransform.Angle;
		else YWARNING("No canvas panel found!");
		return 0;
	}
	UFUNCTION(BlueprintCallable, Category = "UI")
	void MoveSkill(FVector2D offset);
	UFUNCTION(BlueprintCallable, Category = "UI")
	void MoveSkillAbsolute(FVector2D gridIndex);

	float GetPower()
	{
		return m_power;
	}

	void ChangeColor( FLinearColor color );
	void UpdateLevel( float level );
	UFUNCTION(BlueprintCallable, Category = "UI")
	void UpdateInfo( float skilltreeHeight, float skilltreeOffset );
	bool ContainsRoot(TArray<FIntPoint>& points);
	TArray<USkillWidget*> ConnectedSkills(TArray<FIntPoint>& points);
	TArray<FIntPoint> GetPoints();

	virtual void NativeConstruct() override;
	virtual void NativeDestruct() override;
	virtual void NativeTick( const FGeometry& geometry,	float deltaTime ) override;
};
