class CrosshairLogicController_RasetsuHipFire extends inkLogicController
{
	var offsetLeftRight : Float;
	default offsetLeftRight = .8;
	var latchVertical : Float;
	default latchVertical = 40.0;
	editable var m_topPart : inkWidgetRef;
	editable var m_bottomPart : inkWidgetRef;
	editable var m_horiPart : inkWidgetRef;
	editable var m_vertPart : inkWidgetRef;
	editable var m_leftPart : inkWidgetRef;
	editable var m_rightPart : inkWidgetRef;
	editable var m_targetColorChange : inkWidgetRef;

	public function ApplyBulletSpread( spread : Vector2 )
	{
		inkWidgetRef.SetMargin( m_leftPart, inkMargin( -( spread.X ) * offsetLeftRight, 0.0, 0.0, 0.0 ) );
		inkWidgetRef.SetMargin( m_rightPart, inkMargin( spread.X * offsetLeftRight, 0.0, 0.0, 0.0 ) );
		inkWidgetRef.SetSize( m_vertPart, 3.0, ( spread.Y * 2.0 ) + latchVertical );
		inkWidgetRef.SetSize( m_horiPart, spread.X * 2.0, 3.0 );
		inkWidgetRef.SetMargin( m_topPart, inkMargin( 0.0, -( spread.Y ), 0.0, 0.0 ) );
		inkWidgetRef.SetMargin( m_bottomPart, inkMargin( 0.0, spread.Y, 0.0, 0.0 ) );
	}

	public function ApplyCrosshairGUIState( state : CName, aimedAtEntity : Entity )
	{
		inkWidgetRef.SetState( m_targetColorChange, state );
	}

}

class CrosshairLogicController_RasetsuAimFire extends inkLogicController
{
	editable var m_chargebarContainer : inkWidgetRef;
	editable var m_perfectChargeIndicator : inkWidgetRef;
	var m_chargeBar : weak< ChargebarController >;
	var m_animPerfectCharge : inkAnimProxy;

	public function SetPlayer( player : GameObject )
	{
		m_chargeBar = ( ( ChargebarController )( inkWidgetRef.GetController( m_chargebarContainer ) ) );
		if( m_chargeBar )
		{
			m_chargeBar.OnPlayerAttach( player );
		}
	}

	public function ResetPlayer( player : GameObject )
	{
		if( m_chargeBar )
		{
			m_chargeBar.OnPlayerDetach( player );
		}
	}

	public function ApplyTriggerMode( value : Variant )
	{
		if( m_chargeBar )
		{
			m_chargeBar.OnTriggerModeChanged( value );
		}
	}

	public function ApplyChargeValue( value : Float )
	{
		if( m_chargeBar )
		{
			m_chargeBar.OnChargeValueChanged( value );
		}
	}

	public function ApplyPerfectCharge( type : CName )
	{
		var animOptions : inkAnimOptions;
		animOptions.loopType = inkanimLoopType.Cycle;
		animOptions.loopInfinite = true;
		if( type == 'perfectChargeCharged' )
		{
			inkWidgetRef.SetVisible( m_perfectChargeIndicator, true );
			m_animPerfectCharge = PlayLibraryAnimation( 'release', animOptions );
		}
		else if( type == 'perfectChargeShot' )
		{
			if( m_animPerfectCharge && m_animPerfectCharge.IsPlaying() )
			{
				m_animPerfectCharge.Stop();
			}
			inkWidgetRef.SetVisible( m_perfectChargeIndicator, false );
			PlayLibraryAnimation( 'splash' );
		}
		else if( type == 'perfectChargeFailed' )
		{
			if( m_animPerfectCharge && m_animPerfectCharge.IsPlaying() )
			{
				m_animPerfectCharge.Stop();
			}
			inkWidgetRef.SetVisible( m_perfectChargeIndicator, false );
			PlayLibraryAnimation( 'miss' );
		}
	}

}

class CrosshairGameController_Rasetsu extends gameuiCrosshairBaseGameController
{
	editable var m_hipFire : inkWidgetRef;
	editable var m_aimFire : inkWidgetRef;
	editable var m_showAdsAnimName : CName;
	editable var m_hideAdsAnimName : CName;
	editable var m_loopAdsAnimName : CName;
	editable var m_targetHitAnimationName : CName;
	editable var m_shootAnimationName : CName;
	var m_hipFireLogicController : weak< CrosshairLogicController_RasetsuHipFire >;
	var m_aimFireLogicController : weak< CrosshairLogicController_RasetsuAimFire >;
	var m_weaponLocalBB : weak< IBlackboard >;
	var m_uiGameDataBB : weak< IBlackboard >;
	var m_onChargeChangeBBID : CallbackHandle;
	var m_onChargeTriggerModeBBID : CallbackHandle;
	var m_weaponDataTargetHitBBID : CallbackHandle;
	var m_weaponDataShootBBID : CallbackHandle;
	var m_targetHitAnimation : inkAnimProxy;
	var m_shootAnimation : inkAnimProxy;
	var m_visibilityAnimProxy : inkAnimProxy;
	var m_rootAnimProxy : inkAnimProxy;
	var m_isRootVisible : Bool;
	default m_isRootVisible = true;

	protected event OnInitialize()
	{
		super.OnInitialize();
		m_uiGameDataBB = GetBlackboardSystem().Get( GetAllBlackboardDefs().UIGameData );
		m_hipFireLogicController = ( ( CrosshairLogicController_RasetsuHipFire )( inkWidgetRef.GetController( m_hipFire ) ) );
		m_aimFireLogicController = ( ( CrosshairLogicController_RasetsuAimFire )( inkWidgetRef.GetController( m_aimFire ) ) );
		if( m_aimFireLogicController )
		{
			m_aimFireLogicController.SetPlayer( GetPlayerControlledObject() );
		}
		RequestProcessFitToViewport();
	}

	protected event OnUninitialize()
	{
		if( m_aimFireLogicController )
		{
			m_aimFireLogicController.ResetPlayer( GetPlayerControlledObject() );
		}
		super.OnUninitialize();
	}

	protected event OnPreIntro()
	{
		var m_uiActiveWeaponBlackboard : weak< IBlackboard >;
		m_weaponLocalBB = GetWeaponLocalBlackboard();
		if( m_weaponLocalBB )
		{
			m_onChargeChangeBBID = m_weaponLocalBB.RegisterListenerFloat( GetAllBlackboardDefs().Weapon.Charge, this, 'OnChargeChanged' );
			m_onChargeTriggerModeBBID = m_weaponLocalBB.RegisterListenerVariant( GetAllBlackboardDefs().Weapon.TriggerMode, this, 'OnTriggerModeChanged' );
		}
		super.OnPreIntro();
		m_uiActiveWeaponBlackboard = GetUIActiveWeaponBlackboard();
		if( m_uiActiveWeaponBlackboard )
		{
			m_weaponDataTargetHitBBID = m_uiActiveWeaponBlackboard.RegisterDelayedListenerVariant( GetAllBlackboardDefs().UI_ActiveWeaponData.TargetHitEvent, this, 'OnTargetHit' );
			m_weaponDataShootBBID = m_uiActiveWeaponBlackboard.RegisterDelayedListenerVariant( GetAllBlackboardDefs().UI_ActiveWeaponData.ShootEvent, this, 'OnShoot' );
		}
	}

	protected event OnPreOutro()
	{
		var m_uiActiveWeaponBlackboard : weak< IBlackboard >;
		if( m_weaponLocalBB )
		{
			m_weaponLocalBB.UnregisterListenerFloat( GetAllBlackboardDefs().Weapon.Charge, m_onChargeChangeBBID );
			m_weaponLocalBB.UnregisterListenerVariant( GetAllBlackboardDefs().Weapon.TriggerMode, m_onChargeTriggerModeBBID );
		}
		m_uiActiveWeaponBlackboard = GetUIActiveWeaponBlackboard();
		if( m_uiActiveWeaponBlackboard )
		{
			m_uiActiveWeaponBlackboard.UnregisterDelayedListener( GetAllBlackboardDefs().UI_ActiveWeaponData.TargetHitEvent, m_weaponDataTargetHitBBID );
			m_uiActiveWeaponBlackboard.UnregisterDelayedListener( GetAllBlackboardDefs().UI_ActiveWeaponData.ShootEvent, m_weaponDataShootBBID );
		}
		super.OnPreOutro();
	}

	public export override function GetIntroAnimation( firstEquip : Bool ) : inkAnimProxy
	{
		var anim : inkAnimDef;
		var alphaInterpolator : inkAnimTransparency;
		anim = new inkAnimDef;
		alphaInterpolator = new inkAnimTransparency;
		alphaInterpolator.SetStartTransparency( 0.0 );
		alphaInterpolator.SetEndTransparency( 1.0 );
		alphaInterpolator.SetDuration( 0.40000001 );
		alphaInterpolator.SetType( inkanimInterpolationType.Linear );
		alphaInterpolator.SetMode( inkanimInterpolationMode.EasyIn );
		anim.AddInterpolator( alphaInterpolator );
		return m_rootWidget.PlayAnimation( anim );
	}

	public export override function GetOutroAnimation() : inkAnimProxy
	{
		var anim : inkAnimDef;
		var alphaInterpolator : inkAnimTransparency;
		anim = new inkAnimDef;
		alphaInterpolator = new inkAnimTransparency;
		alphaInterpolator.SetStartTransparency( 1.0 );
		alphaInterpolator.SetEndTransparency( 0.0 );
		alphaInterpolator.SetDuration( 0.40000001 );
		alphaInterpolator.SetType( inkanimInterpolationType.Linear );
		alphaInterpolator.SetMode( inkanimInterpolationMode.EasyIn );
		anim.AddInterpolator( alphaInterpolator );
		return m_rootWidget.PlayAnimation( anim );
	}

	protected event OnBulletSpreadChanged( spread : Vector2 )
	{
		super.OnBulletSpreadChanged( spread );
		if( m_hipFireLogicController )
		{
			m_hipFireLogicController.ApplyBulletSpread( spread );
		}
	}

	protected event OnChargeChanged( argCharge : Float )
	{
		if( m_aimFireLogicController )
		{
			m_aimFireLogicController.ApplyChargeValue( argCharge );
		}
	}

	protected event OnTriggerModeChanged( triggerMode : Variant )
	{
		if( m_aimFireLogicController )
		{
			m_aimFireLogicController.ApplyTriggerMode( triggerMode );
		}
	}

	protected override function ApplyCrosshairGUIState( state : CName, aimedAtEntity : Entity )
	{
		if( m_hipFireLogicController )
		{
			m_hipFireLogicController.ApplyCrosshairGUIState( state, aimedAtEntity );
		}
	}

	protected override function OnState_HipFire()
	{
		ApplyWeaponSwayToCamera( false );
		ShowRootWidget( true );
		if( m_visibilityAnimProxy )
		{
			m_visibilityAnimProxy.UnregisterFromAllCallbacks( inkanimEventType.OnFinish );
			m_visibilityAnimProxy.Stop();
		}
		m_visibilityAnimProxy = PlayLibraryAnimation( m_hideAdsAnimName );
	}

	protected override function OnState_Aim()
	{
		ApplyWeaponSwayToCamera( true );
		ShowRootWidget( true );
		if( m_visibilityAnimProxy )
		{
			m_visibilityAnimProxy.UnregisterFromAllCallbacks( inkanimEventType.OnFinish );
			m_visibilityAnimProxy.Stop();
		}
		m_visibilityAnimProxy = PlayLibraryAnimation( m_showAdsAnimName );
		m_visibilityAnimProxy.RegisterToCallback( inkanimEventType.OnFinish, this, 'OnStartLoop' );
	}

	protected event OnStartLoop( proxy : inkAnimProxy )
	{
		proxy.UnregisterFromAllCallbacks( inkanimEventType.OnFinish );
		PlayLibraryAnimation( m_loopAdsAnimName );
	}

	private function ApplyWeaponSwayToCamera( value : Bool )
	{
		m_uiGameDataBB.SetBool( GetAllBlackboardDefs().UIGameData.ApplyWeaponSwayToCamera, value );
	}

	private function ShowRootWidget( isVisible : Bool )
	{
		if( m_isRootVisible != isVisible )
		{
			m_isRootVisible = isVisible;
			m_rootWidget.StopAllAnimations();
			if( isVisible )
			{
				GetIntroAnimation( false );
			}
			else
			{
				GetOutroAnimation();
			}
		}
	}

	protected override function OnState_GrenadeCharging()
	{
		ApplyWeaponSwayToCamera( false );
		ShowRootWidget( false );
	}

	protected override function OnState_Reload()
	{
		ApplyWeaponSwayToCamera( false );
		ShowRootWidget( false );
	}

	protected override function OnState_Safe()
	{
		ApplyWeaponSwayToCamera( false );
		ShowRootWidget( false );
	}

	protected override function OnState_Sprint()
	{
		ApplyWeaponSwayToCamera( false );
		ShowRootWidget( false );
	}

	protected override function OnState_Scanning()
	{
		ApplyWeaponSwayToCamera( false );
		ShowRootWidget( false );
	}

	protected override function OnState_LeftHandCyberware()
	{
		ApplyWeaponSwayToCamera( false );
		ShowRootWidget( false );
	}

	protected event OnPerfectChargeUIEvent( evt : PerfectChargeUIEvent )
	{
		if( m_aimFireLogicController )
		{
			m_aimFireLogicController.ApplyPerfectCharge( evt.type );
		}
	}

	protected event OnShoot( arg : Variant )
	{
		if( m_shootAnimation )
		{
			m_shootAnimation.Stop();
		}
		m_shootAnimation = PlayLibraryAnimation( m_shootAnimationName, IronsightDetail.PlaybackCycleOnce() );
	}

	protected event OnTargetHit( arg : Variant )
	{
		if( m_targetHitAnimation )
		{
			m_targetHitAnimation.Stop();
		}
		m_targetHitAnimation = PlayLibraryAnimation( m_targetHitAnimationName, IronsightDetail.PlaybackCycleOnce() );
	}

}

