abstract class MineDispenserTransition extends DefaultTransition
{
}

abstract class MineDispenserEventsTransition extends MineDispenserTransition
{

	protected virtual function OnEnter( stateContext : StateContext, scriptInterface : StateGameScriptInterface ) {}
}

class MineDispenserIdleDecisions extends MineDispenserTransition
{

	protected constexpr const function ToMineDispenserCycleItem( const stateContext : StateContext, const scriptInterface : StateGameScriptInterface ) : Bool
	{
		return false;
	}

	protected const function ToMineDispenserUnequip( const stateContext : StateContext, const scriptInterface : StateGameScriptInterface ) : Bool
	{
		if( scriptInterface.IsActionJustPressed( 'VisionPush' ) )
		{
			return true;
		}
		return false;
	}

}

class MineDispenserIdleEvents extends MineDispenserEventsTransition
{

	protected override function OnEnter( stateContext : StateContext, scriptInterface : StateGameScriptInterface )
	{
		var unequipRequest : ItemUnequipRequest;
		super.OnEnter( stateContext, scriptInterface );
		unequipRequest = new ItemUnequipRequest;
		unequipRequest.slotId = T"AttachmentSlots.WeaponRight";
		stateContext.SetTemporaryScriptableParameter( 'itemUnequipRequest', unequipRequest, true );
	}

}

class MineDispenserCycleItemDecisions extends MineDispenserTransition
{

	protected const function ToMineDispenserIdle( const stateContext : StateContext, const scriptInterface : StateGameScriptInterface ) : Bool
	{
		if( GetInStateTime() >= GetStaticFloatParameterDefault( "stateDuration", 0.5 ) )
		{
			return true;
		}
		return false;
	}

}

class MineDispenserCycleItemEvents extends MineDispenserEventsTransition
{

	protected override function OnEnter( stateContext : StateContext, scriptInterface : StateGameScriptInterface )
	{
		super.OnEnter( stateContext, scriptInterface );
	}

}

class MineDispenserPlaceDecisions extends MineDispenserTransition
{
	private var m_spawnPosition : Vector4;
	private var m_spawnNormal : Vector4;

	protected constexpr const function EnterCondition( const stateContext : StateContext, const scriptInterface : StateGameScriptInterface ) : Bool
	{
		return false;
	}

	private const function CanBePlaced( const stateContext : StateContext, const scriptInterface : StateGameScriptInterface ) : Bool
	{
		var raycastResult : TraceResult;
		raycastResult = FindPlaceForMine( scriptInterface );
		return TraceResult.IsValid( raycastResult );
	}

	protected const function ToMineDispenserUnequip( const stateContext : StateContext, const scriptInterface : StateGameScriptInterface ) : Bool
	{
		if( GetInStateTime() >= 0.5 )
		{
			return true;
		}
		return false;
	}

	private const function FindPlaceForMine( const scriptInterface : StateGameScriptInterface ) : TraceResult
	{
		var cameraTransform : Transform;
		var playerPosition : Vector4;
		var playerForward : Vector4;
		var endPosition : Vector4;
		cameraTransform = scriptInterface.GetCameraWorldTransform();
		playerPosition = Transform.GetPosition( cameraTransform );
		playerForward = Transform.GetForward( cameraTransform );
		endPosition = playerPosition + ( playerForward * 10.0 );
		return scriptInterface.RaycastWithASingleGroup( playerPosition, endPosition, 'Static' );
	}

}

class MineDispenserPlaceEvents extends MineDispenserEventsTransition
{
	private var m_spawnPosition : Vector4;
	private var m_spawnNormal : Vector4;

	protected override function OnEnter( stateContext : StateContext, scriptInterface : StateGameScriptInterface )
	{
		super.OnEnter( stateContext, scriptInterface );
		SetupSpawnParams( scriptInterface );
		PlaceMine( scriptInterface );
	}

	private function SetupSpawnParams( scriptInterface : StateGameScriptInterface )
	{
		var raycastResult : TraceResult;
		raycastResult = FindPlaceForMine( scriptInterface );
		m_spawnPosition = ( ( Vector4 )( raycastResult.position ) );
		m_spawnNormal = ( ( Vector4 )( raycastResult.normal ) );
	}

	private function PlaceMine( scriptInterface : StateGameScriptInterface )
	{
		var equippedMine : EntityID;
		var placeEvent : PlaceMineEvent;
		equippedMine = scriptInterface.GetTransactionSystem().GetItemInSlot( GetPlayerPuppet( scriptInterface ), T"AttachmentSlots.WeaponLeft" ).GetEntityID();
		placeEvent = new PlaceMineEvent;
		placeEvent.m_position = m_spawnPosition;
		placeEvent.m_normal = m_spawnNormal;
		GetPlayerPuppet( scriptInterface ).QueueEventForEntityID( equippedMine, placeEvent );
	}

	private const function FindPlaceForMine( const scriptInterface : StateGameScriptInterface ) : TraceResult
	{
		var cameraTransform : Transform;
		var playerPosition : Vector4;
		var playerForward : Vector4;
		var endPosition : Vector4;
		cameraTransform = scriptInterface.GetCameraWorldTransform();
		playerPosition = Transform.GetPosition( cameraTransform );
		playerForward = Transform.GetForward( cameraTransform );
		endPosition = playerPosition + ( playerForward * 10.0 );
		return scriptInterface.RaycastWithASingleGroup( playerPosition, endPosition, 'Static' );
	}

}

class MineDispenserUnequipEvents extends MineDispenserEventsTransition
{

	protected override function OnEnter( stateContext : StateContext, scriptInterface : StateGameScriptInterface )
	{
		var unequipRequest : ItemUnequipRequest;
		stateContext.SetTemporaryBoolParameter( 'FinishLeftHandAction', true, true );
		unequipRequest = new ItemUnequipRequest;
		unequipRequest.slotId = T"AttachmentSlots.WeaponLeft";
		stateContext.SetTemporaryScriptableParameter( 'itemUnequipRequest', unequipRequest, true );
		stateContext.SetTemporaryBoolParameter( 'FinishLeftHandAction', true, true );
	}

}

