#pragma once

// OpenPLX includes.
#include "BeginAGXIncludes.h"
#include "agxOpenPLX/AgxCache.h"
#include "agxOpenPLX/InputSignalListener.h"
#include "agxOpenPLX/OutputSignalListener.h"
#include "agxOpenPLX/AgxObjectMap.h"
#include "openplx/Physics3D/System.h"
#include "EndAGXIncludes.h"

// AGX Dynamics includes.
#include "BeginAGXIncludes.h"
#include <agx/ref_ptr.h>
#include <agxSDK/Assembly.h>
#include "EndAGXIncludes.h"

// Standard library includes.
#include <memory>
#include <vector>
#include <unordered_map>

struct FInputSignalListenerRef
{
	agx::ref_ptr<agxopenplx::InputSignalListener> Native;

	FInputSignalListenerRef() = default;
	FInputSignalListenerRef(
		std::shared_ptr<agxopenplx::InputSignalQueue> InputQueue,
		std::shared_ptr<agxopenplx::AgxObjectMap>& Mapper)
		: Native(new agxopenplx::InputSignalListener(
			  InputQueue, Mapper, std::make_shared<agxopenplx::AgxMetadata>()))
	{
	}
};

struct FOutputSignalListenerRef
{
	agx::ref_ptr<agxopenplx::OutputSignalListener> Native;

	FOutputSignalListenerRef() = default;
	FOutputSignalListenerRef(
		const std::shared_ptr<openplx::Core::Object>& PlxModel,
		std::shared_ptr<agxopenplx::OutputSignalQueue> OutputQueue,
		std::shared_ptr<agxopenplx::AgxObjectMap> Mapper)
		: Native(new agxopenplx::OutputSignalListener(
			  PlxModel, OutputQueue, Mapper, std::make_shared<agxopenplx::AgxMetadata>()))
	{
	}
};

struct FOpenPLXModelData
{
	openplx::Core::ObjectPtr OpenPLXModel;
	std::unordered_map<std::string, std::shared_ptr<openplx::Physics::Signals::Input>> Inputs;
};

struct FOpenPLXModelDataArray
{
	std::vector<FOpenPLXModelData> ModelData;
};
