struct AIActionLookatParams
{
	var useLookat : Bool;
	var useLeftHand : Bool;
	var useRightHand : Bool;
	var attachRightHandtoLeftHand : Bool;
	var attachLeftHandtoRightHand : Bool;
	var slotName : CName;
	var lookatStyle : animLookAtStyle;
	var hasOutTransition : Bool;
	var outTransitionStyle : animLookAtStyle;
	var softLimitDegrees : animLookAtLimitDegreesType;
	var hardLimitDegrees : animLookAtLimitDegreesType;
	var hardLimitDistance : animLookAtLimitDistanceType;
	var backLimitDegrees : animLookAtLimitDegreesType;
	var additionalParts : array< LookAtPartRequest >;
}

struct AIActionTargetStates
{
	var npcStates : AIActionNPCStates;
	var playerStates : AIActionPlayerStates;
}

struct AIActionNPCStates
{
	var highLevelStates : array< gamedataNPCHighLevelState >;
	var upperBodyStates : array< gamedataNPCUpperBodyState >;
	var stanceStates : array< gamedataNPCStanceState >;
	var behaviorStates : array< gamedataNPCBehaviorState >;
	var defenseMode : array< gamedataDefenseMode >;
	var locomotionMode : array< gamedataLocomotionMode >;
}

struct AIActionPlayerStates
{
	var locomotionStates : array< gamePSMLocomotionStates >;
	var upperBodyStates : array< gamePSMUpperBodyStates >;
	var meleeStates : array< gamePSMMelee >;
	var zoneStates : array< gamePSMZones >;
	var bodyCarryStates : array< gamePSMBodyCarrying >;
	var combatStates : array< gamePSMCombat >;
}

struct AIActionSlideParams
{
	var distance : Float;
	var directionAngle : Float;
	var duration : Float;
	var offset : Float;
	var slideToTarget : Bool;
	var debugDrawSlideLines : Bool;
}

class AIActionParams
{

	public static function CreateActionID( context : ScriptExecutionContext, puppet : ScriptedPuppet, const actionStringName : ref< String >, actionPackageType : AIactionParamsPackageTypes, out actionName : CName ) : TweakDBID
	{
		actionName = StringToName( actionStringName );
		return ScriptExecutionContext.CreateActionID( context, actionStringName, actionPackageType );
	}

	public static function TempGetIsValid( actionID : TweakDBID ) : Bool
	{
		return AITweakParams.GetBoolFromTweak( actionID, "tempIsValid" );
	}

	public static function GetOwnerStatesFromArray( const ownerStates : ref< array< CName > > ) : AIActionNPCStates
	{
		var i : Int32;
		var result : AIActionNPCStates;
		for( i = 0; i < ownerStates.Size(); i += 1 )
		{
			PushBackNPCState( result, ownerStates[ i ] );
		}
		return result;
	}

	public static function GetTargetStatesFromArray( const targetStates : ref< array< CName > > ) : AIActionTargetStates
	{
		var i : Int32;
		var result : AIActionTargetStates;
		for( i = 0; i < targetStates.Size(); i += 1 )
		{
			PushBackNPCState( result.npcStates, targetStates[ i ] );
			PushBackPlayerState( result.playerStates, targetStates[ i ] );
		}
		return result;
	}

	public static function GetTargetStatesFromArray( const targetStates : ref< array< CName > >, target : weak< GameObject > ) : AIActionTargetStates
	{
		var i : Int32;
		var result : AIActionTargetStates;
		if( target.IsPlayer() )
		{
			for( i = 0; i < targetStates.Size(); i += 1 )
			{
				PushBackPlayerState( result.playerStates, targetStates[ i ] );
			}
		}
		else if( target.IsNPC() )
		{
			PushBackNPCState( result.npcStates, targetStates[ i ] );
		}
		return result;
	}

	public static function PushBackNPCState( npcStates : ref< AIActionNPCStates >, stateName : CName )
	{
		var highLevelState : gamedataNPCHighLevelState;
		var upperBodyState : gamedataNPCUpperBodyState;
		var stanceState : gamedataNPCStanceState;
		var behaviorState : gamedataNPCBehaviorState;
		var defenseMode : gamedataDefenseMode;
		var locomotionMode : gamedataLocomotionMode;
		highLevelState = GetHighLevelStateFromName( stateName );
		if( highLevelState != gamedataNPCHighLevelState.Invalid )
		{
			npcStates.highLevelStates.PushBack( highLevelState );
			return;
		}
		upperBodyState = GetUpperBodyStateFromName( stateName );
		if( upperBodyState != gamedataNPCUpperBodyState.Invalid )
		{
			npcStates.upperBodyStates.PushBack( upperBodyState );
			return;
		}
		stanceState = GetStanceStateFromName( stateName );
		if( stanceState != gamedataNPCStanceState.Invalid )
		{
			npcStates.stanceStates.PushBack( stanceState );
			return;
		}
		behaviorState = GetBehaviorStateFromName( stateName );
		if( behaviorState != gamedataNPCBehaviorState.Invalid )
		{
			npcStates.behaviorStates.PushBack( behaviorState );
			return;
		}
		locomotionMode = GetLocomotionModeFromName( stateName );
		if( locomotionMode != gamedataLocomotionMode.Invalid )
		{
			npcStates.locomotionMode.PushBack( locomotionMode );
			return;
		}
		defenseMode = GetDefenseModeFromName( stateName );
		if( defenseMode != gamedataDefenseMode.Invalid )
		{
			npcStates.defenseMode.PushBack( defenseMode );
			return;
		}
	}

	public static function PushBackPlayerState( playerStates : ref< AIActionPlayerStates >, stateName : CName )
	{
		var locomotionState : gamePSMLocomotionStates;
		var upperBodyState : gamePSMUpperBodyStates;
		var meleeState : gamePSMMelee;
		var zoneState : gamePSMZones;
		var bodyCarryState : gamePSMBodyCarrying;
		var combatState : gamePSMCombat;
		if( GetPSMLocomotionStateFromName( stateName, locomotionState ) )
		{
			playerStates.locomotionStates.PushBack( locomotionState );
		}
		if( GetPSMUpperBodyStateFromName( stateName, upperBodyState ) )
		{
			playerStates.upperBodyStates.PushBack( upperBodyState );
		}
		if( GetPSMMeleeStateFromName( stateName, meleeState ) )
		{
			playerStates.meleeStates.PushBack( meleeState );
		}
		if( GetPSMZoneStateFromName( stateName, zoneState ) )
		{
			playerStates.zoneStates.PushBack( zoneState );
		}
		if( GetPSMBodyCarryStateFromName( stateName, bodyCarryState ) )
		{
			playerStates.bodyCarryStates.PushBack( bodyCarryState );
		}
		if( GetPSMCombatStateFromName( stateName, combatState ) )
		{
			playerStates.combatStates.PushBack( combatState );
		}
	}

	public static function GetUpperBodyStateFromName( nameParam : CName ) : gamedataNPCUpperBodyState
	{
		var result : Int32;
		result = ( ( Int32 )( EnumValueFromName( 'gamedataNPCUpperBodyState', nameParam ) ) );
		if( result >= 0 )
		{
			return ( ( gamedataNPCUpperBodyState )( result ) );
		}
		return gamedataNPCUpperBodyState.Invalid;
	}

	public static function GetBehaviorStateFromName( nameParam : CName ) : gamedataNPCBehaviorState
	{
		var result : Int32;
		result = ( ( Int32 )( EnumValueFromName( 'gamedataNPCBehaviorState', nameParam ) ) );
		if( result >= 0 )
		{
			return ( ( gamedataNPCBehaviorState )( result ) );
		}
		return gamedataNPCBehaviorState.Invalid;
	}

	public static function GetStanceStateFromName( nameParam : CName ) : gamedataNPCStanceState
	{
		var result : Int32;
		result = ( ( Int32 )( EnumValueFromName( 'gamedataNPCStanceState', nameParam ) ) );
		if( result >= 0 )
		{
			return ( ( gamedataNPCStanceState )( result ) );
		}
		return gamedataNPCStanceState.Invalid;
	}

	public static function GetHighLevelStateFromName( nameParam : CName ) : gamedataNPCHighLevelState
	{
		var result : Int32;
		result = ( ( Int32 )( EnumValueFromName( 'gamedataNPCHighLevelState', nameParam ) ) );
		if( result >= 0 )
		{
			return ( ( gamedataNPCHighLevelState )( result ) );
		}
		return gamedataNPCHighLevelState.Invalid;
	}

	public static function GetDefenseModeFromName( nameParam : CName ) : gamedataDefenseMode
	{
		var result : Int32;
		result = ( ( Int32 )( EnumValueFromName( 'gamedataDefenseMode', nameParam ) ) );
		if( result >= 0 )
		{
			return ( ( gamedataDefenseMode )( result ) );
		}
		return gamedataDefenseMode.Invalid;
	}

	public static function GetLocomotionModeFromName( nameParam : CName ) : gamedataLocomotionMode
	{
		var result : Int32;
		result = ( ( Int32 )( EnumValueFromName( 'gamedataLocomotionMode', nameParam ) ) );
		if( result >= 0 )
		{
			return ( ( gamedataLocomotionMode )( result ) );
		}
		return gamedataLocomotionMode.Invalid;
	}

	public static function GetPSMLocomotionStateFromName( nameParam : CName, out locomotionState : gamePSMLocomotionStates ) : Bool
	{
		var result : Int32;
		result = ( ( Int32 )( EnumValueFromName( 'gamePSMLocomotionStates', nameParam ) ) );
		if( result >= 0 )
		{
			locomotionState = ( ( gamePSMLocomotionStates )( result ) );
			return true;
		}
		return false;
	}

	public static function GetPSMUpperBodyStateFromName( nameParam : CName, out upperBodyState : gamePSMUpperBodyStates ) : Bool
	{
		var result : Int32;
		result = ( ( Int32 )( EnumValueFromName( 'gamePSMUpperBodyStates', nameParam ) ) );
		if( result >= 0 )
		{
			upperBodyState = ( ( gamePSMUpperBodyStates )( result ) );
			return true;
		}
		return false;
	}

	public static function GetPSMMeleeStateFromName( nameParam : CName, out meleeState : gamePSMMelee ) : Bool
	{
		var result : Int32;
		result = ( ( Int32 )( EnumValueFromName( 'gamePSMMelee', nameParam ) ) );
		if( result >= 0 )
		{
			meleeState = ( ( gamePSMMelee )( result ) );
			return true;
		}
		return false;
	}

	public static function GetPSMZoneStateFromName( nameParam : CName, out zoneState : gamePSMZones ) : Bool
	{
		var result : Int32;
		result = ( ( Int32 )( EnumValueFromName( 'gamePSMZones', nameParam ) ) );
		if( result >= 0 )
		{
			zoneState = ( ( gamePSMZones )( result ) );
			return true;
		}
		return false;
	}

	public static function GetPSMBodyCarryStateFromName( nameParam : CName, out bodyCarryState : gamePSMBodyCarrying ) : Bool
	{
		var result : Int32;
		result = ( ( Int32 )( EnumValueFromName( 'gamePSMBodyCarrying', nameParam ) ) );
		if( result >= 0 )
		{
			bodyCarryState = ( ( gamePSMBodyCarrying )( result ) );
			return true;
		}
		return false;
	}

	public static function GetPSMCombatStateFromName( nameParam : CName, out combatState : gamePSMCombat ) : Bool
	{
		var result : Int32;
		result = ( ( Int32 )( EnumValueFromName( 'gamePSMCombat', nameParam ) ) );
		if( result >= 0 )
		{
			combatState = ( ( gamePSMCombat )( result ) );
			return true;
		}
		return false;
	}

}

