importonly class gamePlayerControlledComponent extends IComponent
{
}

import class gamestateMachineComponent extends gamePlayerControlledComponent
{
	public import final function AddStateMachine( stateMachineName : CName, instanceData : StateMachineInstanceData, owner : weak< Entity >, optional tryHotSwap : Bool );
	public import final function RemoveStateMachine( stateMachineIdentifier : StateMachineIdentifier );
	public import final function IsStateMachinePresent( stateMachineIdentifier : StateMachineIdentifier ) : Bool;
	public import testonly final function GetSnapshotContainer() : StateSnapshotsContainer;

	protected event OnStartTakedownEvent( startTakedownEvent : StartTakedownEvent )
	{
		var owner : weak< Entity >;
		var addEvent : PSMAddOnDemandStateMachine;
		var initData : LocomotionTakedownInitData;
		var instanceData : StateMachineInstanceData;
		var record1HitDamage : Record1DamageInHistoryEvent;
		initData = new LocomotionTakedownInitData;
		addEvent = new PSMAddOnDemandStateMachine;
		record1HitDamage = new Record1DamageInHistoryEvent;
		initData.target = startTakedownEvent.target;
		initData.slideTime = startTakedownEvent.slideTime;
		initData.actionName = startTakedownEvent.actionName;
		instanceData.initData = initData;
		addEvent.stateMachineName = 'LocomotionTakedown';
		addEvent.instanceData = instanceData;
		owner = GetEntity();
		owner.QueueEvent( addEvent );
		if( startTakedownEvent.target )
		{
			record1HitDamage.source = ( ( GameObject )( owner ) );
			startTakedownEvent.target.QueueEvent( record1HitDamage );
		}
	}

	protected event OnStartFinisherEvent( evt : StartFinisherEvent )
	{
		var owner : weak< GameObject >;
		var addEvent : PSMAddOnDemandStateMachine;
		var initData : FinisherInitData;
		var instanceData : StateMachineInstanceData;
		addEvent = new PSMAddOnDemandStateMachine;
		initData = new FinisherInitData;
		initData.target = evt.target;
		initData.actionName = evt.actionName;
		initData.IsBossFinisher = evt.isBossFinisher;
		instanceData.initData = initData;
		addEvent.stateMachineName = 'Finisher';
		addEvent.instanceData = instanceData;
		owner = ( ( GameObject )( GetEntity() ) );
		owner.QueueEvent( addEvent );
	}

	protected event OnRipOff( evt : RipOff )
	{
		var owner : weak< GameObject >;
		var addEvent : PSMAddOnDemandStateMachine;
		var initData : TurretInitData;
		var instanceData : StateMachineInstanceData;
		addEvent = new PSMAddOnDemandStateMachine;
		initData = new TurretInitData;
		owner = ( ( GameObject )( GetEntity() ) );
		initData.turret = ( ( GameObject )( GameInstance.FindEntityByID( owner.GetGame(), evt.GetRequesterID() ) ) );
		instanceData.initData = initData;
		addEvent.stateMachineName = 'Turret';
		addEvent.instanceData = instanceData;
		owner.QueueEvent( addEvent );
	}

	protected event OnStartMountingEvent( mountingEvent : MountingEvent )
	{
		var relationship : MountingRelationship;
		var owner : Entity;
		relationship = mountingEvent.relationship;
		owner = GetEntity();
		switch( relationship.relationshipType )
		{
			case gameMountingRelationshipType.Parent:
			{
				MountFromParent( mountingEvent, owner );
			}
			break;
			case gameMountingRelationshipType.Child:
			{
				MountAsChild( mountingEvent, owner );
			}
			break;
			default:
				break;
		}
	}

	protected event OnStartUnmountingEvent( unmountingEvent : UnmountingEvent )
	{
		var relationship : MountingRelationship;
		var owner : Entity;
		relationship = unmountingEvent.relationship;
		owner = GetEntity();
		switch( relationship.relationshipType )
		{
			case gameMountingRelationshipType.Parent:
			{
				UnmountFromParent( unmountingEvent, owner );
			}
			break;
			case gameMountingRelationshipType.Child:
			{
				UnmountChild( unmountingEvent, owner );
			}
			break;
			default:
				break;
		}
	}

	protected function MountFromParent( mountingEvent : MountingEvent, ownerEntity : Entity )
	{
		var initData : VehicleTransitionInitData;
		var relationship : MountingRelationship;
		var otherObjectType : gameMountingObjectType;
		var instanceData : StateMachineInstanceData;
		var otherObject : weak< GameObject >;
		initData = new VehicleTransitionInitData;
		relationship = mountingEvent.relationship;
		otherObjectType = relationship.otherMountableType;
		otherObject = IMountingFacility.RelationshipGetOtherObject( relationship );
		switch( otherObjectType )
		{
			case gameMountingObjectType.Vehicle:
			{
				if( mountingEvent.request.mountData.mountEventOptions.silentUnmount )
				{
					return;
				}
				initData.instant = mountingEvent.request.mountData.isInstant;
				initData.entityID = mountingEvent.request.mountData.mountEventOptions.entityID;
				initData.alive = mountingEvent.request.mountData.mountEventOptions.alive;
				initData.occupiedByNonFriendly = mountingEvent.request.mountData.mountEventOptions.occupiedByNonFriendly;
				instanceData.initData = initData;
				AddStateMachine( 'Vehicle', instanceData, otherObject );
			}
			break;
			case gameMountingObjectType.Object:
				break;
			case gameMountingObjectType.Puppet:
				break;
			case gameMountingObjectType.Platform:
				break;
			case gameMountingObjectType.Invalid:
				break;
			default:
				break;
		}
	}

	protected function MountAsChild( mountingEvent : MountingEvent, ownerEntity : Entity )
	{
		var relationship : MountingRelationship;
		var otherObjectType : gameMountingObjectType;
		var initData : CarriedObjectData;
		var instanceData : StateMachineInstanceData;
		var otherObject : weak< GameObject >;
		var stateMachineIdentifier : StateMachineIdentifier;
		relationship = mountingEvent.relationship;
		otherObjectType = relationship.otherMountableType;
		initData = new CarriedObjectData;
		otherObject = IMountingFacility.RelationshipGetOtherObject( relationship );
		stateMachineIdentifier.definitionName = 'LocomotionTakedown';
		switch( otherObjectType )
		{
			case gameMountingObjectType.Vehicle:
				break;
			case gameMountingObjectType.Object:
			case gameMountingObjectType.Puppet:
			{
				if( otherObject != NULL )
				{
					if( !( IsStateMachinePresent( stateMachineIdentifier ) ) )
					{
						initData.instant = mountingEvent.request.mountData.isInstant;
						instanceData.initData = initData;
						AddStateMachine( 'CarriedObject', instanceData, otherObject );
					}
				}
			}
			;
			break;
			case gameMountingObjectType.Platform:
				break;
			case gameMountingObjectType.Invalid:
				break;
			default:
				break;
		}
	}

	protected function UnmountFromParent( unmountingEvent : UnmountingEvent, ownerEntity : Entity )
	{
		var relationship : MountingRelationship;
		var otherObjectType : gameMountingObjectType;
		var stateMachineIdentifier : StateMachineIdentifier;
		var silentUnmount : Bool;
		relationship = unmountingEvent.relationship;
		otherObjectType = relationship.otherMountableType;
		silentUnmount = unmountingEvent.request.mountData.mountEventOptions.silentUnmount;
		stateMachineIdentifier.definitionName = 'Vehicle';
		switch( otherObjectType )
		{
			case gameMountingObjectType.Vehicle:
			{
				if( !( silentUnmount ) )
				{
					RemoveStateMachine( stateMachineIdentifier );
				}
			}
			break;
			case gameMountingObjectType.Object:
				break;
			case gameMountingObjectType.Puppet:
				break;
			case gameMountingObjectType.Platform:
				break;
			case gameMountingObjectType.Invalid:
				break;
			default:
				break;
		}
	}

	protected function UnmountChild( unmountingEvent : UnmountingEvent, ownerEntity : Entity )
	{
		var relationship : MountingRelationship;
		var otherObjectType : gameMountingObjectType;
		var stateMachineIdentifier : StateMachineIdentifier;
		relationship = unmountingEvent.relationship;
		otherObjectType = relationship.otherMountableType;
		stateMachineIdentifier.definitionName = 'CarriedObject';
		switch( otherObjectType )
		{
			case gameMountingObjectType.Vehicle:
				break;
			case gameMountingObjectType.Object:
			case gameMountingObjectType.Puppet:
			{
				RemoveStateMachine( stateMachineIdentifier );
			}
			;
			break;
			case gameMountingObjectType.Platform:
				break;
			case gameMountingObjectType.Invalid:
				break;
			default:
				break;
		}
	}

}

