enum EMalfunctioningType
{
	NONE = 0,
	LOUD_ANNOUNCEMENT = 1,
	HALF_OPENING = 2,
	GLITCHING = 3,
}

class BunkerDoorController extends DoorController
{

	public const override function GetPS() : BunkerDoorControllerPS
	{
		return ( ( BunkerDoorControllerPS )( GetBasePS() ) );
	}

}

class BunkerDoorControllerPS extends DoorControllerPS
{
	[ category = "Npc Opening Setup" ]
	private instanceeditable var m_NpcOpenSpeed : Float;
	default m_NpcOpenSpeed = 1f;
	[ category = "Npc Opening Setup" ]
	private instanceeditable var m_NpcOpenTime : Float;
	default m_NpcOpenTime = 1f;
	[ category = "Malfunctioning" ]
	private instanceeditable persistent var m_malfunctioningType : EMalfunctioningType;
	[ category = "Malfunctioning" ]
	private instanceeditable persistent var m_malfunctioningChance : Int32;
	default m_malfunctioningChance = 100;
	[ category = "Malfunctioning" ]
	private instanceeditable var m_malfunctioningStimRange : Float;
	default m_malfunctioningStimRange = 10;
	private persistent var m_malfanctioningBehaviourActive : Bool;

	public const function GetMalfunctioningType() : EMalfunctioningType
	{
		return m_malfunctioningType;
	}

	public const function GetMalfunctioningStimRange() : Float
	{
		return m_malfunctioningStimRange;
	}

	public const function GetNpcOpenSpeed() : Float
	{
		return m_NpcOpenSpeed;
	}

	public const function GetNpcOpenTime() : Float
	{
		return m_NpcOpenTime;
	}

	public const function IsMalfunctioningBehaviourActive( type : EMalfunctioningType ) : Bool
	{
		return GetMalfunctioningType() == type && m_malfanctioningBehaviourActive;
	}

	private const function ShouldMalfunction() : Bool
	{
		return RandRange( 0, 100 ) <= m_malfunctioningChance;
	}

	protected override function Initialize()
	{
		super.Initialize();
		ReinitializeMalfunctionBehaviour();
	}

	protected override function OnSetIsOpened()
	{
		super.OnSetIsOpened();
		ReinitializeMalfunctionBehaviour();
	}

	public function SetMalfunctioningType( type : EMalfunctioningType )
	{
		m_malfunctioningType = type;
		m_malfanctioningBehaviourActive = true;
	}

	private function ReinitializeMalfunctionBehaviour()
	{
		m_malfanctioningBehaviourActive = ShouldMalfunction();
	}

	public export function OnMalfunctionHalfOpen( evt : MalfunctionHalfOpen ) : EntityNotificationType
	{
		var notifier : ActionNotifier;
		notifier = new ActionNotifier;
		notifier.SetAll();
		if( ( !( IsMalfunctioningBehaviourActive( EMalfunctioningType.HALF_OPENING ) ) || IsDisabled() ) || IsSealed() )
		{
			return SendActionFailedEvent( evt, evt.GetRequesterID(), "Sealed or Disabled" );
		}
		ReinitializeMalfunctionBehaviour();
		Notify( notifier, evt );
		return EntityNotificationType.SendThisEventToEntity;
	}

	public function ActionMalfunctionHalfOpen() : MalfunctionHalfOpen
	{
		var action : MalfunctionHalfOpen;
		action = new MalfunctionHalfOpen;
		action.clearanceLevel = DefaultActionsParametersHolder.GetToggleOpenClearance();
		action.SetUp( this );
		action.SetProperties();
		action.AddDeviceName( m_deviceName );
		action.CreateInteraction();
		action.CreateActionWidgetPackage();
		return action;
	}

	protected override function GetPlayerToggleOpenAction() : ToggleOpen
	{
		if( IsMalfunctioningBehaviourActive( EMalfunctioningType.HALF_OPENING ) )
		{
			return ActionMalfunctionHalfOpen();
		}
		return ActionToggleOpen();
	}

	protected override function CanAddToggleOpenAction( context : GetActionsContext ) : Bool
	{
		if( IsMalfunctioningBehaviourActive( EMalfunctioningType.HALF_OPENING ) )
		{
			return MalfunctionHalfOpen.IsDefaultConditionMet( this, context );
		}
		return super.CanAddToggleOpenAction( context );
	}

}

class MalfunctionHalfOpen extends ToggleOpen
{

	public function SetProperties()
	{
		actionName = 'Open';
		prop = DeviceActionPropertyFunctions.SetUpProperty_Bool( actionName, true, 'LocKey#273', 'LocKey#273' );
	}

	public override function GetTweakDBChoiceRecord() : String
	{
		return "Open";
	}

	public static function IsDefaultConditionMet( device : BunkerDoorControllerPS, const context : ref< GetActionsContext > ) : Bool
	{
		return ( IsAvailable( device ) && IsClearanceValid( context.clearance ) ) && context.processInitiatorObject.IsPlayer();
	}

	public static function IsAvailable( device : BunkerDoorControllerPS ) : Bool
	{
		if( !( device.IsMalfunctioningBehaviourActive( EMalfunctioningType.HALF_OPENING ) ) )
		{
			return false;
		}
		if( device.IsDisabled() )
		{
			return false;
		}
		if( device.IsSealed() )
		{
			return false;
		}
		if( device.IsOpen() )
		{
			return false;
		}
		return true;
	}

	public static function IsClearanceValid( clearance : Clearance ) : Bool
	{
		return Clearance.IsInRange( clearance, DefaultActionsParametersHolder.GetToggleOpenClearance() );
	}

	public override function GetInkWidgetTweakDBID() : TweakDBID
	{
		return T"DevicesUIDefinitions.DoorDeviceActionWidget";
	}

}

class SetDoorMalfunctioningType extends Event
{
	editable var malfunctioningType : EMalfunctioningType;

	public constexpr function GetFriendlyDescription() : String
	{
		return "Sets door malfunctioning type";
	}

}

