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

#include "SCW_FProperty.h"
#include "SCW_UObject.h"
#include "SourcifyCoreUEWrapperModule.h"
#include "UObject/UnrealType.h"

using namespace Sourcify;

SCW_FProperty::SCW_FProperty(FProperty* InProperty) : SCW_FField(InProperty), Property(InProperty)
{

}

void SCW_FProperty::ExportTextItem_InContainer(wstring& ValueStr, ISCW_UObjectConstPtr ContainerPtr, SCW_EPropertyPortFlags PortFlags /*= SCW_EPropertyPortFlags::PPF_None*/) const
{
	FString ValueStrFString;
	Property->ExportTextItem_InContainer(ValueStrFString, dynamic_cast<const SCW_UObject*>(ContainerPtr.get())->ToUObjectRawPtr(), nullptr, nullptr, static_cast<int32>(PortFlags));
	ValueStr = *ValueStrFString;
}

wstring SCW_FProperty::GetAuthoredName() const
{
	return *Property->GetAuthoredName();
}

SCW_ELifetimeCondition SCW_FProperty::GetBlueprintReplicationCondition() const
{
	return static_cast<SCW_ELifetimeCondition>(Property->GetBlueprintReplicationCondition());
}

wstring SCW_FProperty::GetCPPType(wstring* ExtendedTypeText/* = nullptr*/, SCW_EPropertyExportCPPFlags CPPExportFlags/* = SCW_EPropertyExportCPPFlags::CPPF_None*/) const
{
	FString ExtendedTypeTextFString = ExtendedTypeText ? ExtendedTypeText->c_str() : TEXT("");
	return TCHAR_TO_WCHAR(*Property->GetCPPType(ExtendedTypeText ? &ExtendedTypeTextFString : nullptr, static_cast<uint32_t>(CPPExportFlags)));
}

wstring SCW_FProperty::GetName() const
{
	return *Property->GetName();
}

wstring SCW_FProperty::GetNameCPP() const 
{
	return *Property->GetNameCPP();
}

ISCW_UClassConstPtr SCW_FProperty::GetOwnerClass() const
{
	return FSourcifyCoreUEWrapper::Get().Wrap(*Property->GetOwnerClass());
}

ISCW_UClassPtr SCW_FProperty::GetOwnerClass()
{
	return FSourcifyCoreUEWrapper::Get().Wrap(*Property->GetOwnerClass());
}

ISCW_UObjectConstPtr SCW_FProperty::GetOwnerUObject() const
{
	return FSourcifyCoreUEWrapper::Get().Wrap(*Property->GetOwnerUObject());
}

ISCW_UObjectPtr SCW_FProperty::GetOwnerUObject()
{
	return FSourcifyCoreUEWrapper::Get().Wrap(*Property->GetOwnerUObject());
}

ISCW_UStructConstPtr SCW_FProperty::GetOwnerStruct() const
{
	return FSourcifyCoreUEWrapper::Get().Wrap(*Property->GetOwnerStruct());
}

ISCW_UStructPtr SCW_FProperty::GetOwnerStruct()
{
	return FSourcifyCoreUEWrapper::Get().Wrap(*Property->GetOwnerStruct());
}

ISCW_UPropertyWrapperPtr SCW_FProperty::GetUPropertyWrapper()
{
	return FSourcifyCoreUEWrapper::Get().Wrap(*Property->GetUPropertyWrapper());
}

SCW_EPropertyFlags SCW_FProperty::GetPropertyFlags() const
{
	return static_cast<SCW_EPropertyFlags>(Property->GetPropertyFlags());
}

wstring SCW_FProperty::GetRepNotifyFuncName() const
{
	return TCHAR_TO_WCHAR(*Property->RepNotifyFunc.ToString());
}

bool SCW_FProperty::HasAllPropertyFlags(SCW_EPropertyFlags FlagsToCheck) const
{
	return Property->HasAllPropertyFlags(static_cast<uint64_t>(FlagsToCheck));
}

bool SCW_FProperty::HasAnyPropertyFlags(SCW_EPropertyFlags FlagsToCheck) const
{
	return Property->HasAnyPropertyFlags(static_cast<uint64_t>(FlagsToCheck));
}

bool SCW_FProperty::Identical_InContainer(ISCW_UObjectConstPtr A, ISCW_UObjectConstPtr B, SCW_EPropertyPortFlags PortFlags /* = SCW_EPropertyPortFlags::PPF_None */) const
{
	return Property->Identical_InContainer(dynamic_cast<const SCW_UObject*>(A.get())->ToUObjectRawPtr(), dynamic_cast<const SCW_UObject*>(B.get())->ToUObjectRawPtr(), static_cast<uint32>(PortFlags));
}

const wchar_t* SCW_FProperty::ImportText_InContainer(const wchar_t* Buffer, ISCW_UObjectPtr Container, ISCW_UObjectPtr OwnerObject, SCW_EPropertyPortFlags PortFlags/*, FOutputDevice* ErrorText = (FOutputDevice*)GWarn*/) const
{
	return Property->ImportText_InContainer(Buffer, dynamic_cast<SCW_UObject*>(Container.get())->ToUObjectRawPtr(), OwnerObject ? dynamic_cast<SCW_UObject*>(OwnerObject.get())->ToUObjectRawPtr() : nullptr, static_cast<int32>(PortFlags));
}

void SCW_FProperty::SetPropertyFlags(SCW_EPropertyFlags InFlags)
{
	Property->SetPropertyFlags(static_cast<EPropertyFlags>(InFlags));
}

FProperty* SCW_FProperty::ToFProperty() const
{
	return Property;
}

ISCW_FPropertyPtr SCW_FProperty::ToFPropertyPtr()
{
	return GetSharedThisAs<SCW_FProperty>();
}

ISCW_FPropertyConstPtr SCW_FProperty::ToFPropertyPtr() const
{
	return GetSharedThisAs<SCW_FProperty>();
}