enum VehicleVisualCustomizationWidgetCarPart
{
	Default = 0,
	Body = 1,
	Hood = 2,
	Door = 3,
	Bumper = 4,
	Spoiler = 5,
	SpoilerHidden = 6,
}

class vehicleColorInkController extends inkHUDGameController
{
	private var m_vehicle : weak< VehicleObject >;
	private var m_vehicleBlackboard : weak< IBlackboard >;
	private var m_vehiclePS : weak< VehicleComponentPS >;
	private var m_root : weak< inkWidget >;
	private var m_AnimProxy : inkAnimProxy;
	private var m_GlitchAnimProxy : inkAnimProxy;
	private var m_SpoilerAnimProxy : inkAnimProxy;
	private var m_vvcComponent : weak< vehicleVisualCustomizationComponent >;
	private editable var m_primaryColorPane : inkWidgetRef;
	private editable var m_secondaryColorPane : inkWidgetRef;
	private const editable var m_primaryColor : array< inkImageRef >;
	private const editable var m_secondaryColor : array< inkImageRef >;
	private editable var m_carPartType : VehicleVisualCustomizationWidgetCarPart;
	private var m_colorModDefinition : CallbackHandle;
	private var m_cachedPrimaryColor : Color;
	private var m_cachedSecondaryColor : Color;
	private var m_colorSecondaryCodeListener : CallbackHandle;
	private var m_vehicleCollisionListener : CallbackHandle;
	private var m_vehicleDamageListener : CallbackHandle;
	private var m_vehicleModBlockedByDamageListener : CallbackHandle;
	private var m_vehicleModActiveListener : CallbackHandle;
	private var m_vehicleTPPCallbackID : CallbackHandle;
	private var m_vehicleSpeedListener : CallbackHandle;
	private var m_cachedColorDefinitions : vehicleVisualModdingDefinition;
	private var m_moddingBlockedByDamage : Bool;
	private var m_visualCustomizationActive : Bool;
	private var m_spoilerDeployed : Bool;
	private var m_cachedTppView : Bool;
	private var m_fakeUpdateProxy : inkAnimProxy;
	private var m_damageAnimLoopProxy : inkAnimProxy;

	protected event OnInitialize()
	{
		var bbSys : BlackboardSystem;
		var activeVehicleUIBlackboard : weak< IBlackboard >;
		m_root = GetRootWidget();
		m_vehicle = ( ( VehicleObject )( GetOwnerEntity() ) );
		m_vehiclePS = m_vehicle.GetVehiclePS();
		m_vehicleBlackboard = m_vehicle.GetBlackboard();
		m_vvcComponent = GetPlayer( m_vehicle.GetGame() ).GetVehicleVisualCustomizationComponent();
		m_visualCustomizationActive = m_vehiclePS.GetIsVehicleVisualCustomizationActive();
		m_moddingBlockedByDamage = m_vehiclePS.GetIsVehicleVisualCustomizationBlockedByDamage();
		if( m_visualCustomizationActive && m_vehicle.IsPlayerMounted() )
		{
			RestoreVisualCustomization();
		}
		if( !( m_vehicleCollisionListener ) )
		{
			m_vehicleCollisionListener = m_vehicleBlackboard.RegisterListenerBool( GetAllBlackboardDefs().Vehicle.Collision, this, 'OnVehicleCollision' );
		}
		if( !( m_vehicleModBlockedByDamageListener ) )
		{
			m_vehicleModBlockedByDamageListener = m_vehicleBlackboard.RegisterListenerBool( GetAllBlackboardDefs().Vehicle.VehicleCustomizationBlockedByDamage, this, 'OnVehicleCustomizationBlockedByDamage' );
		}
		if( !( m_vehicleModActiveListener ) )
		{
			m_vehicleModActiveListener = m_vehicleBlackboard.RegisterListenerBool( GetAllBlackboardDefs().Vehicle.VehicleCustomizationActive, this, 'OnVehicleVisualCustomizationActive' );
		}
		if( !( m_vehicleTPPCallbackID ) )
		{
			bbSys = GameInstance.GetBlackboardSystem( m_vehicle.GetGame() );
			activeVehicleUIBlackboard = bbSys.Get( GetAllBlackboardDefs().UI_ActiveVehicleData );
			m_vehicleTPPCallbackID = activeVehicleUIBlackboard.RegisterListenerBool( GetAllBlackboardDefs().UI_ActiveVehicleData.IsTPPCameraOn, this, 'OnVehicleCameraChange' );
		}
		if( !( m_vehicleSpeedListener ) )
		{
			m_vehicleSpeedListener = m_vehicleBlackboard.RegisterListenerFloat( GetAllBlackboardDefs().Vehicle.SpeedValue, this, 'OnVehicleSpeedChange' );
		}
	}

	protected event OnUninitialize()
	{
		var bbSys : BlackboardSystem;
		var activeVehicleUIBlackboard : weak< IBlackboard >;
		m_vehicleBlackboard.UnregisterListenerInt( GetAllBlackboardDefs().Vehicle.DamageState, m_vehicleDamageListener );
		m_vehicleBlackboard.UnregisterListenerInt( GetAllBlackboardDefs().Vehicle.DamageState, m_vehicleCollisionListener );
		m_vehicleBlackboard.UnregisterListenerBool( GetAllBlackboardDefs().Vehicle.VehicleCustomizationBlockedByDamage, m_vehicleModBlockedByDamageListener );
		m_vehicleBlackboard.UnregisterListenerBool( GetAllBlackboardDefs().Vehicle.VehicleCustomizationActive, m_vehicleModActiveListener );
		m_vehicleBlackboard.UnregisterListenerFloat( GetAllBlackboardDefs().Vehicle.SpeedValue, m_vehicleSpeedListener );
		bbSys = GameInstance.GetBlackboardSystem( m_vehicle.GetGame() );
		activeVehicleUIBlackboard = bbSys.Get( GetAllBlackboardDefs().UI_ActiveVehicleData );
		activeVehicleUIBlackboard.UnregisterListenerBool( GetAllBlackboardDefs().UI_ActiveVehicleData.IsTPPCameraOn, m_vehicleTPPCallbackID );
		m_damageAnimLoopProxy.Stop();
	}

	protected event OnVehicleVisualCustomizationActive( value : Bool )
	{
		var isRequestInstant : Bool;
		isRequestInstant = m_vehicleBlackboard.GetBool( GetAllBlackboardDefs().Vehicle.VehicleCustomizationInstant );
		m_visualCustomizationActive = value;
		m_cachedColorDefinitions = m_vehiclePS.GetVehicleVisualCustomizationDefinition();
		if( value )
		{
			if( !( isRequestInstant ) )
			{
				ProcessColorsUpdates();
			}
			else
			{
				RestoreVisualCustomization();
			}
		}
		else
		{
			if( !( m_moddingBlockedByDamage ) )
			{
				PlayLibraryAnimation( 'Reset' );
			}
		}
	}

	private function RestoreVisualCustomization()
	{
		var isRequestInstant : Bool;
		isRequestInstant = m_vehicleBlackboard.GetBool( GetAllBlackboardDefs().Vehicle.VehicleCustomizationInstant );
		m_cachedColorDefinitions = m_vehiclePS.GetVehicleVisualCustomizationDefinition();
		if( m_vehiclePS.GetIsVehicleVisualCustomizationBlockedByDamage() )
		{
			return;
		}
		m_cachedPrimaryColor = m_vvcComponent.VehicleVisualCustomizationColorParamsToColor( m_cachedColorDefinitions.primaryColorH, false, m_cachedColorDefinitions.primaryColorS, m_cachedColorDefinitions.primaryColorB );
		m_cachedSecondaryColor = m_vvcComponent.VehicleVisualCustomizationColorParamsToColor( m_cachedColorDefinitions.secondaryColorH, false, m_cachedColorDefinitions.secondaryColorS, m_cachedColorDefinitions.secondaryColorB );
		if( !( isRequestInstant ) )
		{
			ProcessColorsUpdates();
		}
		else
		{
			ApplyColors( false );
		}
	}

	private function ProcessColorsUpdates()
	{
		if( m_moddingBlockedByDamage == true )
		{
			return;
		}
		m_cachedPrimaryColor = m_vvcComponent.VehicleVisualCustomizationColorParamsToColor( m_cachedColorDefinitions.primaryColorH, false, m_cachedColorDefinitions.primaryColorS, m_cachedColorDefinitions.primaryColorB );
		m_cachedSecondaryColor = m_vvcComponent.VehicleVisualCustomizationColorParamsToColor( m_cachedColorDefinitions.secondaryColorH, false, m_cachedColorDefinitions.secondaryColorS, m_cachedColorDefinitions.secondaryColorB );
		ApplyColors( false );
	}

	private function HandleGlitch( optional val : Int32 )
	{
		if( m_moddingBlockedByDamage == true )
		{
			return;
		}
		if( m_GlitchAnimProxy.IsPlaying() )
		{
			m_GlitchAnimProxy.Stop( true );
		}
		m_GlitchAnimProxy = PlayLibraryAnimation( 'Glitch' );
	}

	protected event OnVehicleDamageState( val : Int32 )
	{
		HandleGlitch();
	}

	protected event OnVehicleCollision( val : Bool )
	{
		HandleGlitch();
	}

	protected event OnVehicleCustomizationBlockedByDamage( val : Bool )
	{
		var animOptions : inkAnimOptions;
		if( val )
		{
			if( !( m_moddingBlockedByDamage ) )
			{
				m_damageAnimLoopProxy = PlayLibraryAnimation( 'DamageDisable', animOptions );
				m_moddingBlockedByDamage = true;
				animOptions.loopType = inkanimLoopType.Cycle;
				animOptions.loopInfinite = false;
				animOptions.loopCounter = 1;
			}
		}
	}

	private function ApplyColors( optional instant : Bool )
	{
		var i, j : Int32;
		var animOptions : inkAnimOptions;
		var animExecutionDelay : Float;
		while( i < m_primaryColor.Size() )
		{
			inkImageRef.SetTintColor( m_primaryColor[ i ], m_cachedPrimaryColor );
			i += 1;
		}
		while( j < m_secondaryColor.Size() )
		{
			inkImageRef.SetTintColor( m_secondaryColor[ j ], m_cachedSecondaryColor );
			j += 1;
		}
		if( !( instant ) )
		{
			animExecutionDelay = m_vehicleBlackboard.GetFloat( GetAllBlackboardDefs().Vehicle.VehicleCustomizationWidgetDelay );
			if( animExecutionDelay > 0.60000002 )
			{
				animExecutionDelay = 0.0;
			}
			animOptions.executionDelay = animExecutionDelay;
			m_AnimProxy = PlayLibraryAnimation( 'SwitchColor', animOptions );
			m_vehicleBlackboard.SetFloat( GetAllBlackboardDefs().Vehicle.VehicleCustomizationWidgetDelay, animExecutionDelay + 0.15000001 );
		}
	}

	protected event OnVehicleCameraChange( tppCamera : Bool )
	{
		if( tppCamera != m_cachedTppView )
		{
			m_cachedTppView = tppCamera;
			ApplyColors( true );
		}
	}

	protected event OnSpolierAnimationEnd( proxy : inkAnimProxy )
	{
		m_SpoilerAnimProxy.UnregisterFromCallback( inkanimEventType.OnFinish, this, 'OnSpolierAnimationEnd' );
		ApplyColors( true );
		GetRootWidget().SetVisible( false );
	}

	protected event OnVehicleSpeedChange( speed : Float )
	{
		switch( m_carPartType )
		{
			case VehicleVisualCustomizationWidgetCarPart.SpoilerHidden:
			{
				if( ( speed > 20.0 ) && !( m_spoilerDeployed ) )
				{
					ApplyColors( true );
					GetRootWidget().SetVisible( true );
					m_spoilerDeployed = true;
					return true;
				}
				if( ( speed < 15.0 ) && m_spoilerDeployed )
				{
					m_spoilerDeployed = false;
					m_SpoilerAnimProxy = PlayLibraryAnimation( 'SpoilerDelay' );
					m_SpoilerAnimProxy.RegisterToCallback( inkanimEventType.OnFinish, this, 'OnSpolierAnimationEnd' );
					return true;
				}
				if( ( speed == 0.0 ) && !( m_spoilerDeployed ) )
				{
					GetRootWidget().SetVisible( false );
					m_spoilerDeployed = false;
					ApplyColors( true );
					return true;
				}
			}
		}
	}

}

