abstract class CoverActionTransition extends LocomotionTransition
{
	protected var m_gameInstance : GameInstance;
	protected var m_locomotionStateCallbackID : CallbackHandle;
	protected var m_lastSlidingTime : Float;
	protected var m_isSliding : Bool;

	protected export override function OnAttach( const stateContext : StateContext, const scriptInterface : StateGameScriptInterface )
	{
		var allBlackboardDef : AllBlackboardDefinitions;
		allBlackboardDef = GetAllBlackboardDefs();
		super.OnAttach( stateContext, scriptInterface );
		m_gameInstance = scriptInterface.GetGame();
		m_locomotionStateCallbackID = scriptInterface.localBlackboard.RegisterListenerInt( allBlackboardDef.PlayerStateMachine.Locomotion, this, 'OnLocomotionChanged', true );
	}

	protected export virtual function OnDetach( const stateContext : StateContext, const scriptInterface : StateGameScriptInterface )
	{
		m_locomotionStateCallbackID = NULL;
	}

	protected event OnLocomotionChanged( value : Int32 )
	{
		var isSliding : Bool;
		isSliding = ( value == ( ( Int32 )( gamePSMLocomotionStates.Slide ) ) ) || ( value == ( ( Int32 )( gamePSMLocomotionStates.SlideFall ) ) );
		if( isSliding != m_isSliding )
		{
			m_isSliding = isSliding;
			if( !( m_isSliding ) )
			{
				m_lastSlidingTime = EngineTime.ToFloat( GameInstance.GetTimeSystem( m_gameInstance ).GetSimTime() );
			}
		}
	}

	protected const function IsMeleeLeaningInputCorrect( const scriptInterface : StateGameScriptInterface ) : Bool
	{
		var meleeWeaponState : Int32;
		meleeWeaponState = scriptInterface.localBlackboard.GetInt( GetAllBlackboardDefs().PlayerStateMachine.MeleeWeapon );
		return ( meleeWeaponState == ( ( Int32 )( gamePSMMeleeWeapon.Block ) ) ) || ( meleeWeaponState == ( ( Int32 )( gamePSMMeleeWeapon.Targeting ) ) );
	}

	protected const function IsPlayerInCorrectStateToPeek( scriptInterface : StateGameScriptInterface, stateContext : StateContext ) : Bool
	{
		var leftHandCyberwareState : Int32;
		if( IsInSafeSceneTier( scriptInterface ) )
		{
			return false;
		}
		if( scriptInterface.localBlackboard.GetBool( GetAllBlackboardDefs().PlayerStateMachine.MountedToVehicle ) )
		{
			return false;
		}
		if( m_isSliding || ( ( EngineTime.ToFloat( GameInstance.GetTimeSystem( m_gameInstance ).GetSimTime() ) - m_lastSlidingTime ) < 0.40000001 ) )
		{
			return false;
		}
		if( scriptInterface.localBlackboard.GetInt( GetAllBlackboardDefs().PlayerStateMachine.Vision ) == ( ( Int32 )( gamePSMVision.Focus ) ) )
		{
			return true;
		}
		leftHandCyberwareState = scriptInterface.localBlackboard.GetInt( GetAllBlackboardDefs().PlayerStateMachine.LeftHandCyberware );
		if( ( ( leftHandCyberwareState == ( ( Int32 )( gamePSMLeftHandCyberware.Charge ) ) ) || ( leftHandCyberwareState == ( ( Int32 )( gamePSMLeftHandCyberware.ChargeAction ) ) ) ) || ( leftHandCyberwareState == ( ( Int32 )( gamePSMLeftHandCyberware.QuickAction ) ) ) )
		{
			return true;
		}
		if( scriptInterface.localBlackboard.GetInt( GetAllBlackboardDefs().PlayerStateMachine.CombatGadget ) == ( ( Int32 )( gamePSMCombatGadget.Charging ) ) )
		{
			return true;
		}
		if( scriptInterface.localBlackboard.GetInt( GetAllBlackboardDefs().PlayerStateMachine.UpperBody ) == ( ( Int32 )( gamePSMUpperBodyStates.Aim ) ) )
		{
			stateContext.RemovePermanentBoolParameter( 'QuickthrowHoldPeek' );
			return true;
		}
		if( scriptInterface.GetActionValue( 'CameraAim' ) == 0.0 )
		{
			stateContext.RemovePermanentBoolParameter( 'QuickthrowHoldPeek' );
		}
		if( stateContext.GetBoolParameter( 'QuickthrowHoldPeek', true ) )
		{
			return true;
		}
		if( stateContext.IsStateActive( 'UpperBody', 'aimingState' ) )
		{
			stateContext.RemovePermanentBoolParameter( 'QuickthrowHoldPeek' );
			return true;
		}
		return false;
	}

	protected const function GetManualLeanIdleTime( const scriptInterface : StateGameScriptInterface, const stateContext : StateContext ) : Float
	{
		var parameter : StateResultFloat;
		parameter = stateContext.GetPermanentFloatParameter( 'ManualLeanIdleStartTime' );
		if( !( parameter.valid ) )
		{
			return 0.0;
		}
		return EngineTime.ToFloat( scriptInterface.GetTimeSystem().GetSimTime() ) - parameter.value;
	}

	protected const function IsManualLeanInputPressed( const stateContext : StateContext, const scriptInterface : StateGameScriptInterface, const actionName : CName ) : Bool
	{
		return scriptInterface.IsActionJustPressed( actionName ) || ( ( scriptInterface.GetActionValue( actionName ) > 0.0 ) && ( GetManualLeanIdleTime( scriptInterface, stateContext ) > 0.2 ) );
	}

	protected const function IsManualLeanLeftInputPressed( const stateContext : StateContext, const scriptInterface : StateGameScriptInterface ) : Bool
	{
		return false;
		return IsManualLeanInputPressed( stateContext, scriptInterface, 'LeanLeft' );
	}

	protected const function IsManualLeanRightInputPressed( const stateContext : StateContext, const scriptInterface : StateGameScriptInterface ) : Bool
	{
		return false;
		return IsManualLeanInputPressed( stateContext, scriptInterface, 'LeanRight' );
	}

}

abstract class CoverActionEventsTransition extends CoverActionTransition
{

	protected function SetCoverStateAnimFeature( scriptInterface : StateGameScriptInterface, newState : Int32 )
	{
		var animFeature : AnimFeature_PlayerCoverActionState;
		animFeature = new AnimFeature_PlayerCoverActionState;
		animFeature.state = newState;
		scriptInterface.SetAnimationParameterFeature( 'PlayerCoverActionState', animFeature );
		SetCoverActionStateBlacboardVal( scriptInterface, newState );
	}

	protected function SetCoverActionStateBlacboardVal( scriptInterface : StateGameScriptInterface, newVal : Int32 )
	{
		SetBlackboardIntVariable( scriptInterface, GetAllBlackboardDefs().CoverAction.coverActionStateId, newVal );
	}

}

class InactiveCoverDecisions extends CoverActionTransition
{

	protected export const function EnterCondition( stateContext : StateContext, scriptInterface : StateGameScriptInterface ) : Bool
	{
		return !( IsPlayerInCorrectStateToPeek( scriptInterface, stateContext ) ) && ( scriptInterface.localBlackboard.GetInt( GetAllBlackboardDefs().PlayerStateMachine.CombatGadget ) != ( ( Int32 )( gamePSMCombatGadget.Throwing ) ) );
	}

}

class InactiveCoverEvents extends CoverActionEventsTransition
{

	public export function OnEnter( stateContext : StateContext, scriptInterface : StateGameScriptInterface )
	{
		SetCoverStateAnimFeature( scriptInterface, ( ( Int32 )( gamePlayerCoverMode.None ) ) );
		scriptInterface.GetSpatialQueriesSystem().GetPlayerObstacleSystem().OnCoverDeactivation( scriptInterface.owner );
		stateContext.RemovePermanentBoolParameter( 'QuickthrowHoldPeek' );
	}

}

class ActivateCoverDecisions extends CoverActionTransition
{

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

}

class ActivateCoverEvents extends CoverActionEventsTransition
{
	var m_usingCover : Bool;

	public export function OnEnter( stateContext : StateContext, scriptInterface : StateGameScriptInterface )
	{
		scriptInterface.GetSpatialQueriesSystem().GetPlayerObstacleSystem().OnAutoCoverActivation( scriptInterface.owner );
		SetCoverStateAnimFeature( scriptInterface, ( ( Int32 )( gamePlayerCoverMode.Auto ) ) );
		m_usingCover = false;
	}

	public export function OnExit( stateContext : StateContext, scriptInterface : StateGameScriptInterface )
	{
		SetBlackboardBoolVariable( scriptInterface, GetAllBlackboardDefs().PlayerStateMachine.UsingCover, false );
	}

	public export override function OnForcedExit( stateContext : StateContext, scriptInterface : StateGameScriptInterface )
	{
		SetBlackboardBoolVariable( scriptInterface, GetAllBlackboardDefs().PlayerStateMachine.UsingCover, false );
	}

	public export function OnUpdate( timeDelta : Float, stateContext : StateContext, scriptInterface : StateGameScriptInterface )
	{
		var usingCover : Bool;
		usingCover = scriptInterface.GetSpatialQueriesSystem().GetPlayerObstacleSystem().GetCoverDirection( scriptInterface.executionOwner ) != gamePlayerCoverDirection.None;
		if( usingCover != m_usingCover )
		{
			m_usingCover = usingCover;
			SetBlackboardBoolVariable( scriptInterface, GetAllBlackboardDefs().PlayerStateMachine.UsingCover, m_usingCover );
		}
	}

}

