// Copyright (c) 2024 Codemongous LLC. All Rights Reserved.

#include "SCW_UEdGraphNode.h"
#include "SCW_UEdGraphPin.h"
#include "EdGraph/EdGraphNode.h"
#include "SourcifyCoreUEWrapperModule.h"

using namespace Sourcify;

SCW_UEdGraphNode::SCW_UEdGraphNode(UEdGraphNode* InEdGraphNode) : SCW_UObject(InEdGraphNode), EdGraphNode(InEdGraphNode)
{

}

void SCW_UEdGraphNode::ClearCompilerMessage()
{
	EdGraphNode->ClearCompilerMessage();
}

void SCW_UEdGraphNode::DestroyNode()
{
	EdGraphNode->DestroyNode();
}

ISCW_UEdGraphPinPtr SCW_UEdGraphNode::FindPin(const wstring PinName, const SCW_EEdGraphPinDirection Direction/* = SCW_EEdGraphPinDirection::EGPD_MAX*/) const
{
	UEdGraphPin* Pin = EdGraphNode->FindPin(WCHAR_TO_TCHAR(PinName.c_str()), static_cast<EEdGraphPinDirection>(Direction));
	return Pin ? FSourcifyCoreUEWrapper::Get().Wrap(*Pin) : nullptr;
}

ISCW_UEdGraphPinPtr SCW_UEdGraphNode::FindPinChecked(const wstring PinName, const SCW_EEdGraphPinDirection Direction/* = SCW_EEdGraphPinDirection::EGPD_MAX*/) const
{
	ISCW_UEdGraphPinPtr Pin = FindPin(PinName, Direction);
	check(Pin);
	return Pin;
}

ISCW_UEdGraphPinPtr SCW_UEdGraphNode::FindPinByPredicate(const function<bool(ISCW_UEdGraphPinPtr)>& Predicate) const
{
	for (UEdGraphPin* Pin : EdGraphNode->Pins)
	{
		ISCW_UEdGraphPinPtr WrappedPin = FSourcifyCoreUEWrapper::Get().Wrap(*Pin);
		if (Predicate(WrappedPin))
		{
			return WrappedPin;
		}
	}
	return nullptr;
}

ISCW_UEdGraphPtr SCW_UEdGraphNode::GetGraph() const
{
	return FSourcifyCoreUEWrapper::Get().Wrap(*EdGraphNode->GetGraph());
}

bool SCW_UEdGraphNode::GetCommentBubblePinned() const
{
	return EdGraphNode->bCommentBubblePinned;
}

bool SCW_UEdGraphNode::GetCommentBubbleVisible() const
{
	return EdGraphNode->bCommentBubbleVisible;
}

wstring SCW_UEdGraphNode::GetNodeComment() const
{
	return TCHAR_TO_WCHAR(*EdGraphNode->NodeComment);
}

int32_t SCW_UEdGraphNode::GetNodeHeight() const
{
	return static_cast<int32_t>(EdGraphNode->NodeHeight);
}

int32_t SCW_UEdGraphNode::GetNodePosX() const
{
	return static_cast<int32_t>(EdGraphNode->NodePosX);
}

int32_t SCW_UEdGraphNode::GetNodePosY() const
{
	return static_cast<int32_t>(EdGraphNode->NodePosY);
}

vector<ISCW_UEdGraphPinPtr> SCW_UEdGraphNode::GetPins() const
{
	vector<ISCW_UEdGraphPinPtr> WrappedPins;
	for (UEdGraphPin* Pin : EdGraphNode->Pins)
	{
		WrappedPins.push_back(FSourcifyCoreUEWrapper::Get().Wrap(*Pin));
	}
	return WrappedPins;
}

void SCW_UEdGraphNode::PinConnectionListChanged(ISCW_UEdGraphPinPtr Pin)
{
	EdGraphNode->PinConnectionListChanged(dynamic_cast<SCW_UEdGraphPin*>(Pin.get())->ToUEdGraphPin());
}

void SCW_UEdGraphNode::PinTypeChanged(ISCW_UEdGraphPinPtr Pin)
{
	EdGraphNode->PinTypeChanged(dynamic_cast<SCW_UEdGraphPin*>(Pin.get())->ToUEdGraphPin());
}

void SCW_UEdGraphNode::ReconstructNode() const
{
	EdGraphNode->ReconstructNode();
}

bool SCW_UEdGraphNode::RemovePin(ISCW_UEdGraphPinPtr Pin) const
{
	return EdGraphNode->RemovePin(dynamic_cast<SCW_UEdGraphPin*>(Pin.get())->ToUEdGraphPin());
}

void SCW_UEdGraphNode::SetCommentBubblePinned(bool InPinned)
{
	EdGraphNode->bCommentBubblePinned = InPinned;
}

void SCW_UEdGraphNode::SetCommentBubbleVisible(bool InVisible)
{
	EdGraphNode->bCommentBubbleVisible = InVisible;
}
		
void SCW_UEdGraphNode::SetDisableOrphanPinSaving(bool InOrphanPinSaving)
{
	EdGraphNode->bDisableOrphanPinSaving = InOrphanPinSaving;
}

void SCW_UEdGraphNode::SetNodeComment(const wstring InNodeComment)
{
	EdGraphNode->NodeComment = WCHAR_TO_TCHAR(InNodeComment.c_str());
}

void SCW_UEdGraphNode::SetNodeHeight(int32_t InHeight)
{
	EdGraphNode->NodeHeight = static_cast<int32>(InHeight);
}

void SCW_UEdGraphNode::SetNodePosX(int32_t InNodePosX)
{
	EdGraphNode->NodePosX = static_cast<int32>(InNodePosX);
}

void SCW_UEdGraphNode::SetNodePosY(int32_t InNodePosY)
{
	EdGraphNode->NodePosY = static_cast<int32>(InNodePosY);
}

UEdGraphNode* SCW_UEdGraphNode::ToUEdGraphNode() const
{
	return EdGraphNode;
}

ISCW_UEdGraphNodePtr SCW_UEdGraphNode::ToUEdGraphNodePtr()
{
	return GetSharedThisAs<SCW_UEdGraphNode>();
}

ISCW_UEdGraphNodeConstPtr SCW_UEdGraphNode::ToUEdGraphNodePtr() const
{
	return GetSharedThisAs<SCW_UEdGraphNode>();
}
