class RelicPerkSystem extends ScriptableSystem
{
	private persistent var m_registeredPerkDevices : array< PerkDeviceMappinData >;

	private override function OnRestored( saveVersion : Int32, gameVersion : Int32 )
	{
		RegisterMappins();
	}

	private function RegisterMappins()
	{
		var i : Int32;
		for( i = 0; i < m_registeredPerkDevices.Size(); i += 1 )
		{
			if( !( m_registeredPerkDevices[ i ].IsUsed() ) )
			{
				RegisterMappinInMappinSystem( m_registeredPerkDevices[ i ] );
			}
		}
	}

	protected export function OnRegisterPerkDeviceMappinRequest( request : RegisterPerkDeviceMappinRequest )
	{
		var perkDeviceMappinData : PerkDeviceMappinData;
		if( !( TryGetPerkDeviceMappinData( request.m_ownerID, perkDeviceMappinData ) ) )
		{
			perkDeviceMappinData = CreatePerkDeviceMappinData( request );
			RegisterMappinInMappinSystem( perkDeviceMappinData );
		}
		else if( perkDeviceMappinData.GetPosition() != request.m_position )
		{
			perkDeviceMappinData.SetPosition( request.m_position );
			GameInstance.GetMappinSystem( GetGameInstance() ).SetMappinPosition( perkDeviceMappinData.GetMappinID(), request.m_position );
		}
	}

	private function CreatePerkDeviceMappinData( request : RegisterPerkDeviceMappinRequest ) : PerkDeviceMappinData
	{
		var perkDeviceMappinData : PerkDeviceMappinData;
		perkDeviceMappinData = new PerkDeviceMappinData;
		perkDeviceMappinData.SetOwnerID( request.m_ownerID );
		perkDeviceMappinData.SetPosition( request.m_position );
		m_registeredPerkDevices.PushBack( perkDeviceMappinData );
		return perkDeviceMappinData;
	}

	private function IsOwnerRegistered( ownerID : EntityID ) : Bool
	{
		var i : Int32;
		for( i = 0; i < m_registeredPerkDevices.Size(); i += 1 )
		{
			if( m_registeredPerkDevices[ i ].GetOwnerID() == ownerID )
			{
				return true;
			}
		}
		return false;
	}

	private function IsMappinRegistered( perkDeviceMappinData : PerkDeviceMappinData ) : Bool
	{
		var mappinID : NewMappinID;
		return perkDeviceMappinData.GetMappinID() != mappinID;
	}

	private function RegisterMappinInMappinSystem( perkDeviceMappinData : PerkDeviceMappinData )
	{
		var mappinID : NewMappinID;
		mappinID = GameInstance.GetMappinSystem( GetGameInstance() ).RegisterMappin( GetMappinData(), perkDeviceMappinData.GetPosition() );
		perkDeviceMappinData.SetMappinID( mappinID );
	}

	private constexpr function GetMappinData() : MappinData
	{
		var mappinData : MappinData;
		mappinData.mappinType = T"Mappins.PerkDeviceMappinDefinition";
		mappinData.variant = gamedataMappinVariant.Zzz16_RelicDeviceBasicVariant;
		mappinData.active = true;
		mappinData.visibleThroughWalls = true;
		return mappinData;
	}

	protected export function OnSetPerkDeviceAsUsedRequest( request : SetPerkDeviceAsUsedRequest )
	{
		var perkDeviceMappinData : PerkDeviceMappinData;
		if( ( TryGetPerkDeviceMappinData( request.m_ownerID, perkDeviceMappinData ) && !( perkDeviceMappinData.IsUsed() ) ) && IsMappinRegistered( perkDeviceMappinData ) )
		{
			perkDeviceMappinData.SetAsUsed();
			GameInstance.GetMappinSystem( GetGameInstance() ).UnregisterMappin( perkDeviceMappinData.GetMappinID() );
		}
	}

	private function TryGetPerkDeviceMappinData( ownerID : EntityID, out perkDeviceMappinData : PerkDeviceMappinData ) : Bool
	{
		var i : Int32;
		for( i = 0; i < m_registeredPerkDevices.Size(); i += 1 )
		{
			if( m_registeredPerkDevices[ i ].GetOwnerID() == ownerID )
			{
				perkDeviceMappinData = m_registeredPerkDevices[ i ];
				return true;
			}
		}
		return false;
	}

}

class PerkDeviceMappinData extends IScriptable
{
	private persistent var m_ownerID : EntityID;
	private persistent var m_isUsed : Bool;
	default m_isUsed = false;
	private persistent var m_position : Vector4;
	private var m_mappinID : NewMappinID;

	public function SetOwnerID( ownerID : EntityID )
	{
		m_ownerID = ownerID;
	}

	public function GetOwnerID() : EntityID
	{
		return m_ownerID;
	}

	public function SetPosition( position : Vector4 )
	{
		m_position = position;
	}

	public function GetPosition() : Vector4
	{
		return m_position;
	}

	public function SetMappinID( mappinID : NewMappinID )
	{
		m_mappinID = mappinID;
	}

	public function GetMappinID() : NewMappinID
	{
		return m_mappinID;
	}

	public function IsUsed() : Bool
	{
		return m_isUsed;
	}

	public function SetAsUsed()
	{
		m_isUsed = true;
	}

}

class RegisterPerkDeviceMappinRequest extends ScriptableSystemRequest
{
	var m_ownerID : EntityID;
	var m_position : Vector4;
}

class SetPerkDeviceAsUsedRequest extends ScriptableSystemRequest
{
	var m_ownerID : EntityID;
}

