class inkMotorcycleHUDGameController extends BaseVehicleHUDGameController
{
	private var m_vehicleBlackboard : weak< IBlackboard >;
	private var m_activeVehicleUIBlackboard : weak< IBlackboard >;
	private var m_vehicleBBStateConectionId : CallbackHandle;
	private var m_speedBBConnectionId : CallbackHandle;
	private var m_gearBBConnectionId : CallbackHandle;
	private var m_tppBBConnectionId : CallbackHandle;
	private var m_rpmValueBBConnectionId : CallbackHandle;
	private var m_leanAngleBBConnectionId : CallbackHandle;
	private var m_playerStateBBConnectionId : CallbackHandle;
	private var playOptionReverse : inkAnimOptions;
	private var m_rootWidget : weak< inkCanvas >;
	private var m_mainCanvas : weak< inkCanvas >;
	private var m_activeChunks : Int32;
	private editable var m_chunksNumber : Int32;
	private editable var m_dynamicRpmPath : CName;
	private editable var m_rpmPerChunk : Int32;
	private editable var m_hasRevMax : Bool;
	private editable var m_HiResMode : Bool;
	private editable var m_revMaxPath : CName;
	private editable var m_revMaxChunk : Int32;
	private editable var m_revMax : Int32;
	private editable var m_revRedLine : Int32;
	private editable var m_maxSpeed : Int32;
	private editable var m_speedTextWidget : inkTextRef;
	private editable var m_gearTextWidget : inkTextRef;
	private editable var m_RPMTextWidget : inkTextRef;
	private var m_lower : weak< inkCanvas >;
	private var m_lowerSpeedBigR : weak< inkCanvas >;
	private var m_lowerSpeedBigL : weak< inkCanvas >;
	private var m_lowerSpeedSmallR : weak< inkCanvas >;
	private var m_lowerSpeedSmallL : weak< inkCanvas >;
	private var m_lowerSpeedFluffR : weak< inkImage >;
	private var m_lowerSpeedFluffL : weak< inkImage >;
	private var m_hudLowerPart : weak< inkCanvas >;
	private var m_lowerfluff_R : weak< inkCanvas >;
	private var m_lowerfluff_L : weak< inkCanvas >;
	private var m_HudHideAnimation : inkAnimProxy;
	private var m_HudShowAnimation : inkAnimProxy;
	private var m_HudRedLineAnimation : inkAnimProxy;
	private var m_fluffBlinking : inkAnimController;

	protected event OnInitialize()
	{
		m_rootWidget = ( ( inkCanvas )( GetRootWidget() ) );
		playOptionReverse.playReversed = true;
		if( !( m_HiResMode ) )
		{
			m_rootWidget.SetScale( Vector2( 0.5, 0.5 ) );
		}
		m_rootWidget.SetVisible( false );
		m_lower = ( ( inkCanvas )( GetWidget( 'HudMain/Lower' ) ) );
		m_lowerSpeedBigR = ( ( inkCanvas )( GetWidget( 'HudMain/Lower/bigR' ) ) );
		m_lowerSpeedBigL = ( ( inkCanvas )( GetWidget( 'HudMain/Lower/bigL' ) ) );
		m_lowerSpeedSmallR = ( ( inkCanvas )( GetWidget( 'HudMain/Lower/bigR/smallWingR' ) ) );
		m_lowerSpeedSmallL = ( ( inkCanvas )( GetWidget( 'HudMain/Lower/bigL/smallWingL' ) ) );
		m_lowerSpeedFluffR = ( ( inkImage )( GetWidget( 'HudMain/Lower/bigR/R_lowerFluff' ) ) );
		m_lowerSpeedFluffL = ( ( inkImage )( GetWidget( 'HudMain/Lower/bigL/L_lowerFluff' ) ) );
		m_lowerfluff_L = ( ( inkCanvas )( GetWidget( 'HudMain/Lower/bigL/smallWingL/fluffIcons' ) ) );
		m_lowerfluff_R = ( ( inkCanvas )( GetWidget( 'HudMain/Lower/bigR/smallWingR/R_fluffIcons' ) ) );
		m_hudLowerPart = ( ( inkCanvas )( GetWidget( 'HudMain/Lower' ) ) );
	}

	protected event OnUninitialize() {}

	protected event OnVehicleMounted()
	{
		var playerPuppet : weak< GameObject >;
		var vehicle : weak< VehicleObject >;
		var shouldConnect : Bool;
		var bbSys : BlackboardSystem;
		m_fluffBlinking = new inkAnimController;
		m_fluffBlinking.Select( m_lowerfluff_L ).Select( m_lowerfluff_R ).Interpolate( 'transparency', 0.25, 1.0 ).Duration( 0.5 ).Interpolate( 'transparency', 1.0, 0.25 ).Delay( 0.55000001 ).Duration( 0.5 ).Type( inkanimInterpolationType.Linear ).Mode( inkanimInterpolationMode.EasyIn );
		playerPuppet = ( ( PlayerPuppet )( GetOwnerEntity() ) );
		vehicle = GetMountedVehicle( playerPuppet );
		bbSys = GameInstance.GetBlackboardSystem( playerPuppet.GetGame() );
		if( shouldConnect )
		{
			m_vehicleBlackboard = vehicle.GetBlackboard();
			m_activeVehicleUIBlackboard = bbSys.Get( GetAllBlackboardDefs().UI_ActiveVehicleData );
		}
		if( m_vehicleBlackboard )
		{
			m_vehicleBBStateConectionId = m_vehicleBlackboard.RegisterListenerInt( GetAllBlackboardDefs().Vehicle.VehicleState, this, 'OnVehicleStateChanged' );
			m_speedBBConnectionId = m_vehicleBlackboard.RegisterListenerFloat( GetAllBlackboardDefs().Vehicle.SpeedValue, this, 'OnSpeedValueChanged' );
			m_gearBBConnectionId = m_vehicleBlackboard.RegisterListenerInt( GetAllBlackboardDefs().Vehicle.GearValue, this, 'OnGearValueChanged' );
			m_rpmValueBBConnectionId = m_vehicleBlackboard.RegisterListenerFloat( GetAllBlackboardDefs().Vehicle.RPMValue, this, 'OnRpmValueChanged' );
			m_leanAngleBBConnectionId = m_vehicleBlackboard.RegisterListenerFloat( GetAllBlackboardDefs().Vehicle.BikeTilt, this, 'OnLeanAngleChanged' );
			m_tppBBConnectionId = m_activeVehicleUIBlackboard.RegisterListenerBool( GetAllBlackboardDefs().UI_ActiveVehicleData.IsTPPCameraOn, this, 'OnCameraModeChanged' );
			m_playerStateBBConnectionId = m_activeVehicleUIBlackboard.RegisterListenerVariant( GetAllBlackboardDefs().UI_ActiveVehicleData.VehPlayerStateData, this, 'OnPlayerStateChanged' );
		}
	}

	protected event OnVehicleUnmounted()
	{
		if( m_vehicleBlackboard )
		{
			m_vehicleBlackboard.UnregisterListenerInt( GetAllBlackboardDefs().Vehicle.VehicleState, m_vehicleBBStateConectionId );
			m_vehicleBlackboard.UnregisterListenerFloat( GetAllBlackboardDefs().Vehicle.SpeedValue, m_speedBBConnectionId );
			m_vehicleBlackboard.UnregisterListenerInt( GetAllBlackboardDefs().Vehicle.GearValue, m_gearBBConnectionId );
			m_vehicleBlackboard.UnregisterListenerFloat( GetAllBlackboardDefs().Vehicle.RPMValue, m_rpmValueBBConnectionId );
			m_vehicleBlackboard.UnregisterListenerFloat( GetAllBlackboardDefs().Vehicle.BikeTilt, m_leanAngleBBConnectionId );
			m_activeVehicleUIBlackboard.UnregisterListenerBool( GetAllBlackboardDefs().UI_ActiveVehicleData.IsTPPCameraOn, m_tppBBConnectionId );
			m_activeVehicleUIBlackboard.UnregisterListenerVariant( GetAllBlackboardDefs().UI_ActiveVehicleData.VehPlayerStateData, m_playerStateBBConnectionId );
		}
	}

	protected event OnHudHideAnimFinished( proxy : inkAnimProxy )
	{
		m_rootWidget.SetVisible( false );
		m_HudHideAnimation.UnregisterFromCallback( inkanimEventType.OnFinish, this, 'OnHudHideAnimFinished' );
	}

	protected event OnHudShowAnimFinished( proxy : inkAnimProxy )
	{
		var LoopOptions : inkAnimOptions;
		LoopOptions.loopType = inkanimLoopType.Cycle;
		LoopOptions.loopInfinite = true;
		m_fluffBlinking.PlayWithOptions( LoopOptions );
		m_HudShowAnimation.UnregisterFromCallback( inkanimEventType.OnFinish, this, 'OnHudShowAnimFinished' );
	}

	protected event OnVehicleStateChanged( state : Int32 )
	{
		if( state == ( ( Int32 )( vehicleEState.On ) ) )
		{
		}
		if( state != ( ( Int32 )( vehicleEState.On ) ) )
		{
		}
	}

	protected event OnPlayerStateChanged( data : Variant )
	{
		var newData : VehEntityPlayerStateData;
		var playerState : Int32;
		newData = ( ( VehEntityPlayerStateData )data );
		playerState = newData.state;
		if( playerState == 4 )
		{
			m_fluffBlinking.Stop();
			m_HudHideAnimation = PlayLibraryAnimation( 'show', playOptionReverse );
			m_HudHideAnimation.RegisterToCallback( inkanimEventType.OnFinish, this, 'OnHudHideAnimFinished' );
		}
	}

	protected event OnRpmMaxChanged( rpmMax : Float )
	{
		var rpm : Int32;
		var level : Float;
		var levelInt : Int32;
		rpm = ( ( Int32 )( rpmMax ) );
		level = ( ( Float )( rpm / m_rpmPerChunk ) );
		levelInt = ( ( Int32 )( level ) );
		EvaluateRPMMeterWidget( levelInt );
	}

	protected event OnSpeedValueChanged( speedValue : Float )
	{
		var calcSpeed : Int32;
		var animRatio : Float;
		var calcSpeedFloat : Float;
		animRatio = 0.69999999;
		calcSpeedFloat = speedValue * 2.23693991;
		calcSpeed = RoundMath( calcSpeedFloat );
		if( speedValue < 0.0 )
		{
			inkTextRef.SetText( m_speedTextWidget, "Common-Digits-Zero" );
		}
		else
		{
			inkTextRef.SetText( m_speedTextWidget, IntToString( calcSpeed ) );
		}
		m_lowerSpeedBigL.SetTranslation( Vector2( ( ( Float )( calcSpeedFloat ) ) * ( animRatio * -1.0 ), 0.0 ) );
		m_lowerSpeedBigR.SetTranslation( Vector2( ( ( Float )( calcSpeedFloat ) ) * animRatio, 0.0 ) );
		m_lowerSpeedSmallL.SetTranslation( Vector2( ( ( Float )( calcSpeedFloat ) ) * ( animRatio * -1.0 ), 0.0 ) );
		m_lowerSpeedSmallR.SetTranslation( Vector2( ( ( Float )( calcSpeedFloat ) ) * animRatio, 0.0 ) );
		m_lowerSpeedFluffL.SetTranslation( Vector2( ( ( Float )( calcSpeedFloat ) ) * ( animRatio * -1.20000005 ), 0.0 ) );
		m_lowerSpeedFluffR.SetTranslation( Vector2( ( ( Float )( calcSpeedFloat ) ) * ( animRatio * 1.20000005 ), 0.0 ) );
		m_hudLowerPart.SetTranslation( Vector2( 0.0, ( ( Float )( calcSpeedFloat ) ) * ( animRatio * -1.0 ) ) );
	}

	protected event OnGearValueChanged( gearValue : Int32 )
	{
		if( gearValue == ( ( Int32 )( 0 ) ) )
		{
			inkTextRef.SetText( m_gearTextWidget, "UI-Cyberpunk-Vehicles-Gears-Neutral" );
		}
		else
		{
			inkTextRef.SetText( m_gearTextWidget, IntToString( gearValue ) );
		}
	}

	protected event OnRpmValueChanged( rpmValue : Float )
	{
		inkTextRef.SetText( m_RPMTextWidget, IntToString( RoundMath( rpmValue ) ) );
		if( rpmValue > 7800.0 )
		{
			m_HudRedLineAnimation = PlayLibraryAnimation( 'redLine' );
		}
		drawRPMGaugeFull( rpmValue );
	}

	public function drawRPMGaugeFull( rpmValue : Float )
	{
		var rpm : Int32;
		var level : Float;
		var levelInt : Int32;
		rpm = ( ( Int32 )( rpmValue ) );
		level = ( ( Float )( rpm / m_rpmPerChunk ) );
		levelInt = ( ( Int32 )( level ) );
		EvaluateRPMMeterWidget( levelInt );
	}

	private function EvaluateRPMMeterWidget( currentAmountOfChunks : Int32 )
	{
		if( currentAmountOfChunks == m_activeChunks )
		{
			return;
		}
		RedrawRPM( currentAmountOfChunks );
	}

	private function RedrawRPM( currentAmountOfChunks : Int32 )
	{
		var increasing : Bool;
		var difference : Int32;
		var chunkToModify : String;
		var widgetToModify : weak< inkRectangle >;
		var i : Int32;
		difference = Abs( currentAmountOfChunks - m_activeChunks );
		increasing = currentAmountOfChunks > m_activeChunks;
		if( increasing )
		{
			for( i = m_activeChunks; i <= ( m_activeChunks + difference ); i += 1 )
			{
				chunkToModify = NameToString( m_dynamicRpmPath ) + IntToString( i );
				widgetToModify = ( ( inkRectangle )( GetWidget( StringToName( chunkToModify ) ) ) );
				widgetToModify.SetVisible( true );
				widgetToModify.SetOpacity( 1.0 );
			}
		}
		else
		{
			for( i = m_activeChunks; i >= ( m_activeChunks - difference ); i -= 1 )
			{
				chunkToModify = NameToString( m_dynamicRpmPath ) + IntToString( i );
				widgetToModify = ( ( inkRectangle )( GetWidget( StringToName( chunkToModify ) ) ) );
				widgetToModify.SetVisible( false );
			}
		}
		m_activeChunks = currentAmountOfChunks;
	}

	private function AddChunk()
	{
		var chunkToActivate : String;
		var widgetToShow : weak< inkRectangle >;
		var i : Int32;
		if( IsNameValid( m_dynamicRpmPath ) )
		{
			for( i = 1; i <= m_activeChunks; i += 1 )
			{
				chunkToActivate = NameToString( m_dynamicRpmPath ) + IntToString( i );
				widgetToShow = ( ( inkRectangle )( GetWidget( StringToName( chunkToActivate ) ) ) );
				widgetToShow.SetVisible( true );
				widgetToShow.SetOpacity( 1.0 );
			}
		}
	}

	private function RemoveChunk()
	{
		var chunkToRemove : String;
		var widgetToHide : weak< inkRectangle >;
		var i : Int32;
		if( IsNameValid( m_dynamicRpmPath ) )
		{
			for( i = m_chunksNumber; i > m_activeChunks; i -= 1 )
			{
				chunkToRemove = NameToString( m_dynamicRpmPath ) + IntToString( i );
				widgetToHide = ( ( inkRectangle )( GetWidget( StringToName( chunkToRemove ) ) ) );
				widgetToHide.SetVisible( false );
			}
		}
	}

	protected event OnLeanAngleChanged( leanAngle : Float ) {}

	protected event OnCameraModeChanged( mode : Bool )
	{
		if( mode == true )
		{
			m_rootWidget.SetVisible( true );
			m_HudShowAnimation = PlayLibraryAnimation( 'show' );
			m_HudShowAnimation.RegisterToCallback( inkanimEventType.OnFinish, this, 'OnHudShowAnimFinished' );
		}
		else if( mode == false )
		{
			m_fluffBlinking.Stop();
			m_HudHideAnimation = PlayLibraryAnimation( 'show', playOptionReverse );
			m_HudHideAnimation.RegisterToCallback( inkanimEventType.OnFinish, this, 'OnHudHideAnimFinished' );
		}
	}

	protected function CheckVehicleType( const desiredType : ref< String > ) : Bool
	{
		var playerPuppet : weak< GameObject >;
		var vehicle : weak< VehicleObject >;
		var record : weak< Vehicle_Record >;
		var typeRecord : weak< VehicleType_Record >;
		var type : String;
		playerPuppet = ( ( PlayerPuppet )( GetOwnerEntity() ) );
		vehicle = GetMountedVehicle( playerPuppet );
		record = vehicle.GetRecord();
		typeRecord = record.Type();
		type = typeRecord.EnumName();
		if( type == desiredType )
		{
			return true;
		}
		return false;
	}

}

