class OnWorkspotAvailabilityEvent extends Event
{
	var workspotRef : NodeRef;
}

class OnReserveWorkspotEvent extends OnWorkspotAvailabilityEvent
{
	var action : gamedataWorkspotActionType;
}

class OnReleaseWorkspotEvent extends OnWorkspotAvailabilityEvent
{
}

class WorkspotEntryData extends IScriptable
{
	instanceeditable var workspotRef : NodeRef;
	instanceeditable var isEnabled : Bool;
	var isAvailable : Bool;
	default isAvailable = true;
}

class WorkspotMapData extends IScriptable
{
	instanceeditable var action : gamedataWorkspotActionType;
	const instanceeditable inlined var workspots : array< WorkspotEntryData >;

	public const function FindFreeWorkspotRef() : NodeRef
	{
		var i : Int32;
		var workspotRef : NodeRef;
		for( i = 0; i < workspots.Size(); i += 1 )
		{
			if( workspots[ i ] == NULL )
			{
				continue;
			}
			if( workspots[ i ].isEnabled && workspots[ i ].isAvailable )
			{
				workspotRef = workspots[ i ].workspotRef;
				break;
			}
		}
		return workspotRef;
	}

	public const function FindFreeWorkspotData() : WorkspotEntryData
	{
		var i : Int32;
		var workspotData : WorkspotEntryData;
		for( i = 0; i < workspots.Size(); i += 1 )
		{
			if( workspots[ i ] == NULL )
			{
				continue;
			}
			if( workspots[ i ].isEnabled && workspots[ i ].isAvailable )
			{
				workspotData = workspots[ i ];
				break;
			}
		}
		return workspotData;
	}

	public const function GetFreeWorkspotsCount() : Int32
	{
		var i : Int32;
		var count : Int32;
		for( i = 0; i < workspots.Size(); i += 1 )
		{
			if( workspots[ i ] == NULL )
			{
				continue;
			}
			if( workspots[ i ].isEnabled && workspots[ i ].isAvailable )
			{
				count += 1;
				break;
			}
		}
		return count;
	}

	public function ReleaseWorkspot( workspotRef : NodeRef )
	{
		var i : Int32;
		for( i = 0; i < workspots.Size(); i += 1 )
		{
			if( workspots[ i ] == NULL )
			{
				continue;
			}
			if( workspots[ i ].workspotRef == workspotRef )
			{
				workspots[ i ].isAvailable = true;
			}
		}
	}

	public function ReserveWorkspot( workspotRef : NodeRef )
	{
		var i : Int32;
		for( i = 0; i < workspots.Size(); i += 1 )
		{
			if( workspots[ i ] == NULL )
			{
				continue;
			}
			if( workspots[ i ].workspotRef == workspotRef )
			{
				workspots[ i ].isAvailable = false;
			}
		}
	}

}

class WorkspotMapperComponent extends ScriptableComponent
{
	const instanceeditable inlined var m_workspotsMap : array< WorkspotMapData >;

	protected export function OnGameAttach() {}

	protected export function OnGameDetach() {}

	public const function GetFreeWorkspotsCountForAIAction( aiAction : gamedataWorkspotActionType ) : Int32
	{
		var count : Int32;
		var mapEntryIndex : Int32;
		mapEntryIndex = GetWorkspotMapEntryIdexForAIaction( aiAction );
		if( mapEntryIndex >= 0 )
		{
			count = GetFreeWorkspotsCount( mapEntryIndex );
		}
		return count;
	}

	public const function GetFreeWorkspotRefForAIAction( aiAction : gamedataWorkspotActionType ) : NodeRef
	{
		var workspotRef : NodeRef;
		var mapEntryIndex : Int32;
		mapEntryIndex = GetWorkspotMapEntryIdexForAIaction( aiAction );
		if( mapEntryIndex >= 0 )
		{
			workspotRef = FindFreeWorkspotRef( mapEntryIndex );
		}
		return workspotRef;
	}

	public const function GetFreeWorkspotDataForAIAction( aiAction : gamedataWorkspotActionType ) : WorkspotEntryData
	{
		var workspotData : WorkspotEntryData;
		var mapEntryIndex : Int32;
		mapEntryIndex = GetWorkspotMapEntryIdexForAIaction( aiAction );
		if( mapEntryIndex >= 0 )
		{
			workspotData = FindFreeWorkspotData( mapEntryIndex );
		}
		return workspotData;
	}

	public const function GetNumberOfWorkpotsForAIAction( aiAction : gamedataWorkspotActionType ) : Int32
	{
		var mapEntryIndex : Int32;
		mapEntryIndex = GetWorkspotMapEntryIdexForAIaction( aiAction );
		if( mapEntryIndex < 0 )
		{
			return 0;
		}
		return m_workspotsMap[ mapEntryIndex ].workspots.Size();
	}

	private const function GetWorkspotMapEntryIdexForAIaction( aiAction : gamedataWorkspotActionType ) : Int32
	{
		var i : Int32;
		for( i = 0; i < m_workspotsMap.Size(); i += 1 )
		{
			if( m_workspotsMap[ i ] == NULL )
			{
				continue;
			}
			if( m_workspotsMap[ i ].action == aiAction )
			{
				return i;
			}
		}
		return -1;
	}

	private const function GetFreeWorkspotsCount( mapEntryIndex : Int32 ) : Int32
	{
		var count : Int32;
		if( m_workspotsMap[ mapEntryIndex ] == NULL )
		{
			count = 0;
		}
		if( mapEntryIndex >= 0 )
		{
			count = m_workspotsMap[ mapEntryIndex ].GetFreeWorkspotsCount();
		}
		return count;
	}

	private const function FindFreeWorkspotRef( mapEntryIndex : Int32 ) : NodeRef
	{
		var workspotRef : NodeRef;
		if( m_workspotsMap[ mapEntryIndex ] == NULL )
		{
			return workspotRef;
		}
		if( mapEntryIndex >= 0 )
		{
			workspotRef = m_workspotsMap[ mapEntryIndex ].FindFreeWorkspotRef();
		}
		return workspotRef;
	}

	private const function FindFreeWorkspotData( mapEntryIndex : Int32 ) : WorkspotEntryData
	{
		var workspotData : WorkspotEntryData;
		if( m_workspotsMap[ mapEntryIndex ] == NULL )
		{
			return workspotData;
		}
		if( mapEntryIndex >= 0 )
		{
			workspotData = m_workspotsMap[ mapEntryIndex ].FindFreeWorkspotData();
		}
		return workspotData;
	}

	private function ReleaseWorkspot( workspotRef : NodeRef )
	{
		var i : Int32;
		for( i = 0; i < m_workspotsMap.Size(); i += 1 )
		{
			if( m_workspotsMap[ i ] == NULL )
			{
				continue;
			}
			m_workspotsMap[ i ].ReleaseWorkspot( workspotRef );
		}
	}

	private function ReserveWorkspot( workspotRef : NodeRef )
	{
		var i : Int32;
		for( i = 0; i < m_workspotsMap.Size(); i += 1 )
		{
			if( m_workspotsMap[ i ] == NULL )
			{
				continue;
			}
			m_workspotsMap[ i ].ReserveWorkspot( workspotRef );
		}
	}

	protected event OnReserveWorkspot( evt : OnReserveWorkspotEvent )
	{
		ReserveWorkspot( evt.workspotRef );
	}

	protected event OnReleaseWorkspot( evt : OnReleaseWorkspotEvent )
	{
		ReleaseWorkspot( evt.workspotRef );
	}

}

