class PlatformDevice extends InteractiveDevice
{
	default m_controllerTypeName = 'PlatformController';
	private var m_movingPlatform : MovingPlatform;
	private var m_offMeshConnection : OffMeshConnectionComponent;
	instanceeditable var m_StartAudioEvent : CName;
	instanceeditable var m_StopAudioEvent : CName;
	instanceeditable var m_MovingVFX : CName;

	protected event OnRequestComponents( ri : EntityRequestComponentsInterface )
	{
		super.OnRequestComponents( ri );
		EntityRequestComponentsInterface.RequestComponent( ri, 'movingPlatform', 'MovingPlatform', true );
		EntityRequestComponentsInterface.RequestComponent( ri, 'offMeshConnection', 'OffMeshConnectionComponent', true );
	}

	protected event OnTakeControl( ri : EntityResolveComponentsInterface )
	{
		m_movingPlatform = ( ( MovingPlatform )( EntityResolveComponentsInterface.GetComponent( ri, 'movingPlatform' ) ) );
		m_offMeshConnection = ( ( OffMeshConnectionComponent )( EntityResolveComponentsInterface.GetComponent( ri, 'offMeshConnection' ) ) );
		super.OnTakeControl( ri );
		m_controller = ( ( PlatformController )( EntityResolveComponentsInterface.GetComponent( ri, 'controller' ) ) );
	}

	public override function OnMaraudersMapDeviceDebug( sink : MaraudersMapDevicesSink )
	{
		super.OnMaraudersMapDeviceDebug( sink );
		sink.PushString( "Error message", GetDevicePS().GetError() );
	}

	protected const override function GetController() : PlatformController
	{
		return ( ( PlatformController )( m_controller ) );
	}

	public const override function GetDevicePS() : PlatformControllerPS
	{
		return GetController().GetPS();
	}

	public const function GetPosition() : Vector4
	{
		return GetWorldPosition();
	}

	protected export override function IsDeviceMovableScript() : Bool
	{
		return true;
	}

	protected override function ResolveGameplayState()
	{
		var teleportEvent : TeleportTo;
		var platfPos : Vector4;
		var destNodeRef : GlobalNodeRef;
		var transform : Transform;
		var markerPos : Vector4;
		platfPos = GetPosition() + m_movingPlatform.GetLocalPosition();
		destNodeRef = ResolveNodeRefWithEntityID( GetDevicePS().GetDestinationNode(), GetEntityID() );
		GameInstance.GetNodeTransform( GetGame(), destNodeRef, transform );
		markerPos = transform.position;
		if( ( !( m_movingPlatform.IsMoving() ) && platfPos != markerPos ) && !( GetDevicePS().IsPaused() ) )
		{
			teleportEvent = new TeleportTo;
			teleportEvent.destinationNode = GetDevicePS().GetDestinationNode();
			QueueEvent( teleportEvent );
		}
		super.ResolveGameplayState();
	}

	private function StartPostProductionEvents()
	{
		PlaySoundEvent( this, m_StartAudioEvent );
		GameObjectEffectHelper.StartEffectEvent( this, m_MovingVFX );
	}

	private function StopPostProductionEvents()
	{
		PlaySoundEvent( this, m_StopAudioEvent );
		GameObjectEffectHelper.StopEffectEvent( this, m_MovingVFX );
		StopSound( this, m_StartAudioEvent );
	}

	protected function MoveToMarker( destination : NodeRef )
	{
		var moveToEvent : MoveTo;
		var dynamicMov : MovingPlatformMovementDynamic;
		moveToEvent = new MoveTo;
		dynamicMov = new MovingPlatformMovementDynamic;
		dynamicMov.curveName = GetDevicePS().GetCurveName();
		dynamicMov.SetInitData( gameMovingPlatformMovementInitializationType.Speed, GetDevicePS().GetSpeed() );
		dynamicMov.SetDestinationNode( destination );
		moveToEvent.movement = dynamicMov;
		StartPostProductionEvents();
		QueueEvent( moveToEvent );
	}

	protected function Pause()
	{
		StopPostProductionEvents();
		GetDevicePS().SetPauseTime( m_movingPlatform.Pause() );
	}

	protected function Resume( time : Float )
	{
		StartPostProductionEvents();
		m_movingPlatform.Unpause( time );
	}

	protected event OnArrivedAt( evt : ArrivedAt )
	{
		StopPostProductionEvents();
		SendEventToDefaultPS( evt );
	}

	protected event OnMovementChange( evt : MovementStateChanged )
	{
		GetDevicePS().SetIsMoving( evt.isMoving );
		SendEventToDefaultPS( evt );
	}

	protected event OnAreaEnter( evt : AreaEnteredEvent )
	{
		var activator : weak< GameObject >;
		activator = ( ( GameObject )( EntityGameInterface.GetEntity( evt.activator ) ) );
		if( activator.IsPlayer() )
		{
			super.OnAreaEnter( evt );
			GetDevicePS().SetPlayerOnPlatform( true );
		}
	}

	protected event OnAreaExit( evt : AreaExitedEvent )
	{
		var activator : weak< GameObject >;
		activator = ( ( GameObject )( EntityGameInterface.GetEntity( evt.activator ) ) );
		if( activator.IsPlayer() )
		{
			super.OnAreaExit( evt );
			GetDevicePS().SetPlayerOnPlatform( false );
		}
	}

	protected event OnDetach()
	{
		super.OnDetach();
		GetDevicePS().SetPlayerOnPlatform( false );
	}

	protected event OnQuestMoveToFloor( evt : QuestMoveToFloor )
	{
		MoveToMarker( GetDevicePS().GetDestinationNode() );
	}

	protected event OnTeleport( evt : TeleportTo )
	{
		GetDevicePS().SetIsMoving( false );
	}

	protected event OnMoveNext( evt : QuestMoveToNextFloor )
	{
		MoveToMarker( evt.floor );
	}

	protected event OnMovePrev( evt : QuestMoveToPrevFloor )
	{
		MoveToMarker( evt.floor );
	}

	protected event OnQuestPause( evt : QuestPause )
	{
		Pause();
	}

	protected event OnQuestResume( evt : QuestResume )
	{
		Resume( GetDevicePS().GetResumeTime() );
	}

}

