class ResolveQualityRangeInteractionLayerEvent extends Event
{
	var itemData : weak< gameItemData >;
}

class SetContainerStateEvent extends Event
{
	editable var isDisabled : Bool;
	default isDisabled = true;

	public constexpr export function GetFriendlyDescription() : String
	{
		return "Disable or enable loot container";
	}

}

class ToggleContainerLockEvent extends Event
{
	editable var isLocked : Bool;
	default isLocked = true;

	public constexpr export function GetFriendlyDescription() : String
	{
		return "Toggle container lock";
	}

}

class gameLootContainerBasePS extends GameObjectPS
{
	[ category = "Quest" ]
	protected instanceeditable persistent var m_markAsQuest : Bool;
	[ category = "Quest" ]
	protected instanceeditable persistent var m_isDisabled : Bool;
	[ category = "Quest" ]
	protected instanceeditable persistent var m_isLocked : Bool;
	[ category = "Quest" ]
	protected instanceeditable persistent var m_shouldHideLockedUI : Bool;
	[ category = "Quest" ]
	protected instanceeditable persistent var m_started : Bool;

	public function SetLocked( locked : Bool )
	{
		m_isLocked = locked;
	}

	public function SetIsMarkedAsQuest( isQuest : Bool )
	{
		m_markAsQuest = isQuest;
	}

	public function SetStarted( started : Bool )
	{
		m_started = started;
	}

	public const function IsMarkedAsQuest() : Bool
	{
		return m_markAsQuest;
	}

	public const function IsDisabled() : Bool
	{
		return m_isDisabled;
	}

	public const function IsLocked() : Bool
	{
		return m_isLocked;
	}

	public const function ShouldHideLockedUI() : Bool
	{
		return m_shouldHideLockedUI;
	}

	public const function IsStarted() : Bool
	{
		return m_started;
	}

	private function OnSetContainerStateEventEvent( evt : SetContainerStateEvent ) : EntityNotificationType
	{
		var shouldSendToEntity : Bool;
		shouldSendToEntity = m_isDisabled != evt.isDisabled;
		m_isDisabled = evt.isDisabled;
		if( shouldSendToEntity )
		{
			return EntityNotificationType.SendThisEventToEntity;
		}
		else
		{
			return EntityNotificationType.DoNotNotifyEntity;
		}
	}

	private function OnToggleContainerLockEvent( evt : ToggleContainerLockEvent ) : EntityNotificationType
	{
		var shouldSendToEntity : Bool;
		shouldSendToEntity = m_isLocked != evt.isLocked;
		m_isLocked = evt.isLocked;
		if( shouldSendToEntity )
		{
			return EntityNotificationType.SendThisEventToEntity;
		}
		else
		{
			return EntityNotificationType.DoNotNotifyEntity;
		}
	}

}

import class gameLootBag extends GameObject
{
	private var m_lootQuality : gamedataQuality;
	private var m_hasQuestItems : Bool;
	private var m_isInIconForcedVisibilityRange : Bool;
	private var m_isIconic : Bool;
	private var m_isEmpty : Bool;
	private var m_activeQualityRangeInteraction : CName;

	protected virtual function EvaluateLootQualityByTask()
	{
		GameInstance.GetDelaySystem( GetGame() ).QueueTask( this, NULL, 'EvaluateLootQualityTask', gameScriptTaskExecutionStage.Any );
	}

	protected export function EvaluateLootQualityTask( data : ScriptTaskData )
	{
		EvaluateLootQuality();
	}

	protected event OnInteraction( choiceEvent : InteractionChoiceEvent )
	{
		RPGManager.ProcessReadAction( choiceEvent );
		RequestHUDRefresh();
	}

	protected event OnGameAttached()
	{
		var scanningBlockedEvt : SetScanningBlockedEvent;
		super.OnGameAttached();
		if( m_scanningComponent )
		{
			scanningBlockedEvt = new SetScanningBlockedEvent;
			scanningBlockedEvt.isBlocked = false;
			QueueEvent( scanningBlockedEvt );
		}
		ResolveInvotoryContent();
		if( IsEmpty() )
		{
			ToggleLootHighlight( false );
		}
		else if( IsQuest() )
		{
			ToggleLootHighlight( true );
		}
	}

	private function ResolveInvotoryContent()
	{
		m_isEmpty = GameInstance.GetTransactionSystem( GetGame() ).GetTotalItemQuantity( this ) <= 0;
	}

	public const override function GetDefaultHighlight() : FocusForcedHighlightData
	{
		var highlight : FocusForcedHighlightData;
		var outline : EFocusOutlineType;
		if( IsEmpty() || IsAnyClueEnabled() )
		{
			return NULL;
		}
		if( m_scanningComponent.IsBraindanceBlocked() || m_scanningComponent.IsPhotoModeBlocked() )
		{
			return NULL;
		}
		outline = GetCurrentOutline();
		highlight = new FocusForcedHighlightData;
		highlight.sourceID = GetEntityID();
		highlight.sourceName = GetClassName();
		highlight.priority = EPriority.Low;
		highlight.outlineType = outline;
		if( outline == EFocusOutlineType.QUEST )
		{
			highlight.highlightType = EFocusForcedHighlightType.QUEST;
		}
		else if( outline == EFocusOutlineType.ITEM )
		{
			highlight.highlightType = EFocusForcedHighlightType.ITEM;
		}
		else
		{
			highlight = NULL;
		}
		return highlight;
	}

	public const override function GetCurrentOutline() : EFocusOutlineType
	{
		var outlineType : EFocusOutlineType;
		if( !( IsEmpty() ) )
		{
			if( IsQuest() )
			{
				outlineType = EFocusOutlineType.QUEST;
			}
			else
			{
				outlineType = EFocusOutlineType.ITEM;
			}
		}
		else
		{
			outlineType = EFocusOutlineType.INVALID;
		}
		return outlineType;
	}

	protected const override function ShouldRegisterToHUD() : Bool
	{
		if( m_visionComponent || m_forceRegisterInHudManager )
		{
			return true;
		}
		return false;
	}

	public const override function IsContainer() : Bool
	{
		return !( IsEmpty() );
	}

	public const function HasValidLootQuality() : Bool
	{
		return m_lootQuality != gamedataQuality.Invalid && m_lootQuality != gamedataQuality.Random;
	}

	public const override function IsInIconForcedVisibilityRange() : Bool
	{
		return m_isInIconForcedVisibilityRange;
	}

	protected event OnInventoryEmptyEvent( evt : OnInventoryEmptyEvent )
	{
		GameObjectEffectHelper.StartEffectEvent( this, 'fx_empty' );
		m_lootQuality = gamedataQuality.Invalid;
		m_isEmpty = true;
		UntagObject( this );
		RegisterToHUDManagerByTask( false );
		if( IsQuest() )
		{
			ToggleLootHighlight( false );
			MarkAsQuest( false );
			m_hasQuestItems = false;
			ResolveQualityRangeInteractionLayer();
		}
	}

	protected event OnInventoryChangedEvent( evt : InventoryChangedEvent )
	{
		if( HasValidLootQuality() )
		{
			if( EvaluateLootQuality() )
			{
				RequestHUDRefresh();
			}
		}
	}

	protected event OnItemRemoveddEvent( evt : ItemBeingRemovedEvent )
	{
		if( HasValidLootQuality() )
		{
			if( EvaluateLootQuality() )
			{
				RequestHUDRefresh();
			}
		}
	}

	protected event OnItemAddedEvent( evt : ItemAddedEvent )
	{
		m_isEmpty = false;
		if( HasValidLootQuality() )
		{
			EvaluateLootQuality();
			if( EvaluateLootQuality() )
			{
				RequestHUDRefresh();
			}
		}
	}

	public const override function DeterminGameplayRoleMappinVisuaState( const data : ref< SDeviceMappinData > ) : EMappinVisualState
	{
		if( IsEmpty() )
		{
			return EMappinVisualState.Inactive;
		}
		else
		{
			return EMappinVisualState.Default;
		}
	}

	public const override function DeterminGameplayRole() : EGameplayRole
	{
		return EGameplayRole.Loot;
	}

	public const override function IsQuest() : Bool
	{
		return m_hasQuestItems || m_markAsQuest;
	}

	private const function IsEmpty() : Bool
	{
		return m_isEmpty;
	}

	protected function EvaluateLootQualityEvent()
	{
		var evt : gameEvaluateLootQualityEvent;
		evt = new gameEvaluateLootQualityEvent;
		QueueEvent( evt );
	}

	protected event OnEvaluateLootQuality( evt : gameEvaluateLootQualityEvent )
	{
		EvaluateLootQuality();
		RequestHUDRefresh();
	}

	private function EvaluateLootQuality() : Bool
	{
		var newValue : Int32;
		var lastValue : Int32;
		var cachedQuality : gamedataQuality;
		var iteratedQuality : gamedataQuality;
		var qualityToSet : gamedataQuality;
		var isCurrentlyQuest : Bool;
		var isQuest : Bool;
		var isCurrentlyIconic : Bool;
		var transactionSystem : TransactionSystem;
		var i : Int32;
		var items : array< weak< gameItemData > >;
		var wasChanged : Bool;
		transactionSystem = GameInstance.GetTransactionSystem( GetGame() );
		cachedQuality = m_lootQuality;
		isCurrentlyQuest = IsQuest();
		isCurrentlyIconic = GetIsIconic();
		m_isIconic = false;
		m_hasQuestItems = false;
		if( transactionSystem.GetItemList( this, items ) )
		{
			if( items.Size() > 0 )
			{
				qualityToSet = gamedataQuality.Common;
				m_isEmpty = false;
			}
			for( i = 0; i < items.Size(); i += 1 )
			{
				if( !( m_hasQuestItems ) && items[ i ].HasTag( 'Quest' ) )
				{
					m_hasQuestItems = true;
				}
				iteratedQuality = RPGManager.GetItemDataQuality( items[ i ] );
				newValue = UIItemsHelper.QualityEnumToInt( iteratedQuality );
				if( newValue > lastValue )
				{
					lastValue = newValue;
					qualityToSet = iteratedQuality;
				}
				m_isIconic = m_isIconic || RPGManager.IsItemIconic( items[ i ] );
			}
			m_lootQuality = qualityToSet;
		}
		isQuest = IsQuest();
		if( isCurrentlyQuest != isQuest )
		{
			ToggleLootHighlight( isQuest );
			if( !( isQuest ) )
			{
				MarkAsQuest( false );
			}
		}
		wasChanged = ( m_lootQuality != cachedQuality || isCurrentlyQuest != IsQuest() ) || isCurrentlyIconic != m_isIconic;
		if( wasChanged || !( IsNameValid( m_activeQualityRangeInteraction ) ) )
		{
			ResolveQualityRangeInteractionLayer();
		}
		return wasChanged;
	}

	public const override function GetLootQuality() : gamedataQuality
	{
		return m_lootQuality;
	}

	public const override function GetIsIconic() : Bool
	{
		return m_isIconic;
	}

	private function ToggleLootHighlight( enable : Bool )
	{
		var effectInstance : EffectInstance;
		effectInstance = GameInstance.GetGameEffectSystem( GetGame() ).CreateEffectStatic( 'loot_highlight', 'container_highlight', this );
		EffectData.SetEntity( effectInstance.GetSharedData(), GetAllBlackboardDefs().EffectSharedData.entity, this );
		EffectData.SetBool( effectInstance.GetSharedData(), GetAllBlackboardDefs().EffectSharedData.renderMaterialOverride, false );
		EffectData.SetBool( effectInstance.GetSharedData(), GetAllBlackboardDefs().EffectSharedData.enable, enable );
		effectInstance.Run();
	}

	protected event OnInteractionActivated( evt : InteractionActivationEvent )
	{
		var actorUpdateData : HUDActorUpdateData;
		if( evt.eventType == gameinteractionsEInteractionEventType.EIET_activate )
		{
			if( evt.activator.IsPlayer() )
			{
				if( IsQualityRangeInteractionLayer( evt.layerData.tag ) )
				{
					m_isInIconForcedVisibilityRange = true;
					actorUpdateData = new HUDActorUpdateData;
					actorUpdateData.updateIsInIconForcedVisibilityRange = true;
					actorUpdateData.isInIconForcedVisibilityRangeValue = true;
					RequestHUDRefresh( actorUpdateData );
				}
			}
		}
		else
		{
			if( IsQualityRangeInteractionLayer( evt.layerData.tag ) && evt.activator.IsPlayer() )
			{
				m_isInIconForcedVisibilityRange = false;
				actorUpdateData = new HUDActorUpdateData;
				actorUpdateData.updateIsInIconForcedVisibilityRange = true;
				actorUpdateData.isInIconForcedVisibilityRangeValue = false;
				RequestHUDRefresh( actorUpdateData );
			}
		}
	}

	protected function ResolveQualityRangeInteractionLayer()
	{
		var evt : InteractionSetEnableEvent;
		var currentLayer : CName;
		if( IsNameValid( m_activeQualityRangeInteraction ) )
		{
			evt = new InteractionSetEnableEvent;
			evt.enable = false;
			evt.layer = m_activeQualityRangeInteraction;
			QueueEvent( evt );
			m_activeQualityRangeInteraction = '';
		}
		if( m_lootQuality != gamedataQuality.Invalid && m_lootQuality != gamedataQuality.Random )
		{
			evt = new InteractionSetEnableEvent;
			evt.enable = true;
			if( IsQuest() )
			{
				currentLayer = 'QualityRange_Max';
			}
			else if( m_lootQuality == gamedataQuality.Common )
			{
				currentLayer = 'QualityRange_Short';
			}
			else if( m_lootQuality == gamedataQuality.Uncommon )
			{
				currentLayer = 'QualityRange_Medium';
			}
			else if( m_lootQuality == gamedataQuality.Rare )
			{
				currentLayer = 'QualityRange_Medium';
			}
			else if( m_lootQuality == gamedataQuality.Epic )
			{
				currentLayer = 'QualityRange_Max';
			}
			else if( m_lootQuality == gamedataQuality.Legendary )
			{
				currentLayer = 'QualityRange_Max';
			}
			else if( m_lootQuality == gamedataQuality.Iconic )
			{
				currentLayer = 'QualityRange_Max';
			}
			evt.layer = currentLayer;
			m_activeQualityRangeInteraction = currentLayer;
			QueueEvent( evt );
		}
	}

	private function IsQualityRangeInteractionLayer( layerTag : CName ) : Bool
	{
		return ( layerTag == 'QualityRange_Short' || layerTag == 'QualityRange_Medium' ) || layerTag == 'QualityRange_Max';
	}

}

import class gameLootContainerBase extends GameObject
{
	private import var wasLootInitalized : Bool;
	protected var m_lootQuality : gamedataQuality;
	default m_lootQuality = gamedataQuality.Common;
	private var m_hasQuestItems : Bool;
	protected var m_isInIconForcedVisibilityRange : Bool;
	private var m_isIconic : Bool;
	protected var m_activeQualityRangeInteraction : CName;

	public import const function IsLogicReady() : Bool;

	protected virtual function EvaluateLootQualityByTask()
	{
		GameInstance.GetDelaySystem( GetGame() ).QueueTask( this, NULL, 'EvaluateLootQualityTask', gameScriptTaskExecutionStage.Any );
	}

	protected export function EvaluateLootQualityTask( data : ScriptTaskData )
	{
		EvaluateLootQuality();
	}

	protected event OnGameAttached()
	{
		var scanningBlockedEvt : SetScanningBlockedEvent;
		super.OnGameAttached();
		if( m_scanningComponent )
		{
			scanningBlockedEvt = new SetScanningBlockedEvent;
			scanningBlockedEvt.isBlocked = false;
			QueueEvent( scanningBlockedEvt );
		}
		if( IsEmpty() || IsDisabled() )
		{
			ToggleLootHighlight( false );
		}
		else if( IsQuest() )
		{
			ToggleLootHighlight( true );
		}
	}

	protected const override function GetPS() : gameLootContainerBasePS
	{
		return ( ( gameLootContainerBasePS )( GetBasePS() ) );
	}

	public const function ShouldHideLockedUI() : Bool
	{
		return GetPS().ShouldHideLockedUI();
	}

	public const override function GetDefaultHighlight() : FocusForcedHighlightData
	{
		var highlight : FocusForcedHighlightData;
		var outline : EFocusOutlineType;
		if( ( IsEmpty() || IsDisabled() ) || IsAnyClueEnabled() )
		{
			return NULL;
		}
		if( m_scanningComponent.IsBraindanceBlocked() || m_scanningComponent.IsPhotoModeBlocked() )
		{
			return NULL;
		}
		outline = GetCurrentOutline();
		highlight = new FocusForcedHighlightData;
		highlight.sourceID = GetEntityID();
		highlight.sourceName = GetClassName();
		highlight.priority = EPriority.Low;
		highlight.outlineType = outline;
		if( outline == EFocusOutlineType.QUEST )
		{
			highlight.highlightType = EFocusForcedHighlightType.QUEST;
		}
		else if( outline == EFocusOutlineType.ITEM )
		{
			highlight.highlightType = EFocusForcedHighlightType.ITEM;
		}
		else
		{
			highlight = NULL;
		}
		return highlight;
	}

	public const override function GetCurrentOutline() : EFocusOutlineType
	{
		var outlineType : EFocusOutlineType;
		if( !( IsEmpty() ) && !( IsDisabled() ) )
		{
			if( IsQuest() )
			{
				outlineType = EFocusOutlineType.QUEST;
			}
			else
			{
				outlineType = EFocusOutlineType.ITEM;
			}
		}
		else
		{
			outlineType = EFocusOutlineType.INVALID;
		}
		return outlineType;
	}

	protected const override function ShouldRegisterToHUD() : Bool
	{
		if( m_visionComponent || m_forceRegisterInHudManager )
		{
			return true;
		}
		return false;
	}

	public const override function IsContainer() : Bool
	{
		return !( IsEmpty() ) && !( IsDisabled() );
	}

	public const function HasValidLootQuality() : Bool
	{
		return m_lootQuality != gamedataQuality.Invalid && m_lootQuality != gamedataQuality.Random;
	}

	public const override function IsInIconForcedVisibilityRange() : Bool
	{
		return m_isInIconForcedVisibilityRange;
	}

	protected event OnInventoryEmptyEvent( evt : OnInventoryEmptyEvent )
	{
		GameObjectEffectHelper.StartEffectEvent( this, 'fx_empty' );
		m_lootQuality = gamedataQuality.Invalid;
		UntagObject( this );
		RegisterToHUDManagerByTask( false );
		if( IsQuest() )
		{
			ToggleLootHighlight( false );
			MarkAsQuest( false );
			m_hasQuestItems = false;
			ResolveQualityRangeInteractionLayer();
		}
	}

	protected event OnInventoryChangedEvent( evt : InventoryChangedEvent )
	{
		if( HasValidLootQuality() )
		{
			if( EvaluateLootQuality() )
			{
				RequestHUDRefresh();
			}
		}
	}

	protected event OnItemRemoveddEvent( evt : ItemBeingRemovedEvent )
	{
		if( HasValidLootQuality() )
		{
			if( EvaluateLootQuality() )
			{
				RequestHUDRefresh();
			}
		}
	}

	protected event OnItemAddedEvent( evt : ItemAddedEvent )
	{
		if( HasValidLootQuality() )
		{
			EvaluateLootQuality();
			if( EvaluateLootQuality() )
			{
				RequestHUDRefresh();
			}
		}
	}

	protected event OnInventoryFilledEvent( evt : ContainerFilledEvent )
	{
		wasLootInitalized = true;
		EvaluateLootQualityByTask();
	}

	protected event OnInteraction( choiceEvent : InteractionChoiceEvent )
	{
		RPGManager.ProcessReadAction( choiceEvent );
		GameObjectEffectHelper.StartEffectEvent( this, 'fx_checked' );
		RequestHUDRefresh();
	}

	public const override function DeterminGameplayRoleMappinVisuaState( const data : ref< SDeviceMappinData > ) : EMappinVisualState
	{
		if( IsEmpty() || IsDisabled() )
		{
			return EMappinVisualState.Inactive;
		}
		else
		{
			return EMappinVisualState.Default;
		}
	}

	public const override function DeterminGameplayRole() : EGameplayRole
	{
		return EGameplayRole.Loot;
	}

	public const override function IsQuest() : Bool
	{
		var ps : gameLootContainerBasePS;
		ps = GetPS();
		if( ps )
		{
			return !( ps.IsDisabled() ) && ( ps.IsMarkedAsQuest() || m_hasQuestItems );
		}
		return m_hasQuestItems;
	}

	protected override function MarkAsQuest( isQuest : Bool )
	{
		var ps : gameLootContainerBasePS;
		ps = GetPS();
		if( ps )
		{
			ps.SetIsMarkedAsQuest( isQuest );
		}
	}

	public const function IsDisabled() : Bool
	{
		var ps : gameLootContainerBasePS;
		ps = GetPS();
		if( ps )
		{
			return ps.IsDisabled();
		}
		else
		{
			return false;
		}
	}

	public import const function IsEmpty() : Bool;
	public import const function IsIllegal() : Bool;
	public import const function GetContentAssignment() : TweakDBID;

	protected function EvaluateLootQualityEvent()
	{
		var evt : gameEvaluateLootQualityEvent;
		evt = new gameEvaluateLootQualityEvent;
		QueueEvent( evt );
	}

	protected event OnEvaluateLootQuality( evt : gameEvaluateLootQualityEvent )
	{
		EvaluateLootQuality();
		RequestHUDRefresh();
	}

	private function EvaluateLootQuality() : Bool
	{
		var newValue : Int32;
		var lastValue : Int32;
		var cachedQuality : gamedataQuality;
		var iteratedQuality : gamedataQuality;
		var qualityToSet : gamedataQuality;
		var isCurrentlyQuest : Bool;
		var isQuest : Bool;
		var isCurrentlyIconic : Bool;
		var transactionSystem : TransactionSystem;
		var i : Int32;
		var items : array< weak< gameItemData > >;
		var wasChanged : Bool;
		transactionSystem = GameInstance.GetTransactionSystem( GetGame() );
		cachedQuality = m_lootQuality;
		isCurrentlyQuest = IsQuest();
		isCurrentlyIconic = GetIsIconic();
		m_isIconic = false;
		m_hasQuestItems = false;
		if( transactionSystem.GetItemList( this, items ) )
		{
			if( items.Size() > 0 )
			{
				qualityToSet = gamedataQuality.Common;
			}
			for( i = 0; i < items.Size(); i += 1 )
			{
				if( !( m_hasQuestItems ) && items[ i ].HasTag( 'Quest' ) )
				{
					m_hasQuestItems = true;
				}
				iteratedQuality = RPGManager.GetItemDataQuality( items[ i ] );
				newValue = UIItemsHelper.QualityEnumToInt( iteratedQuality );
				if( newValue > lastValue )
				{
					lastValue = newValue;
					qualityToSet = iteratedQuality;
				}
				m_isIconic = m_isIconic || RPGManager.IsItemIconic( items[ i ] );
			}
			m_lootQuality = qualityToSet;
		}
		isQuest = IsQuest();
		if( isCurrentlyQuest != isQuest )
		{
			ToggleLootHighlight( isQuest );
			if( !( isQuest ) )
			{
				MarkAsQuest( false );
			}
		}
		wasChanged = ( m_lootQuality != cachedQuality || isCurrentlyQuest != IsQuest() ) || isCurrentlyIconic != m_isIconic;
		if( wasChanged || !( IsNameValid( m_activeQualityRangeInteraction ) ) )
		{
			ResolveQualityRangeInteractionLayer();
		}
		return wasChanged;
	}

	public const override function GetLootQuality() : gamedataQuality
	{
		return m_lootQuality;
	}

	public const override function GetIsIconic() : Bool
	{
		return m_isIconic;
	}

	protected function ToggleLootHighlight( enable : Bool )
	{
		var effectInstance : EffectInstance;
		effectInstance = GameInstance.GetGameEffectSystem( GetGame() ).CreateEffectStatic( 'loot_highlight', 'container_highlight', this );
		EffectData.SetEntity( effectInstance.GetSharedData(), GetAllBlackboardDefs().EffectSharedData.entity, this );
		EffectData.SetBool( effectInstance.GetSharedData(), GetAllBlackboardDefs().EffectSharedData.renderMaterialOverride, false );
		EffectData.SetBool( effectInstance.GetSharedData(), GetAllBlackboardDefs().EffectSharedData.enable, enable );
		effectInstance.Run();
	}

	protected event OnSetContainerStateEventEvent( evt : SetContainerStateEvent )
	{
		RequestHUDRefresh();
		ToggleLootHighlight( IsQuest() );
	}

	protected virtual function ResolveQualityRangeInteractionLayer()
	{
		m_activeQualityRangeInteraction = 'Invalid';
	}

}

class gameContainerObjectBasePS extends gameLootContainerBasePS
{
}

importonly final class ResetContainerEvent extends Event
{
}

importonly final class RegenerateLootEvent extends Event
{
}

import class gameContainerObjectBase extends gameLootContainerBase
{
	[ customEditor = "TweakDBGroupInheritance;Keycards.Keycard" ]
	protected instanceeditable var m_lockedByKey : TweakDBID;

	protected event OnToggleContainerLockEvent( evt : ToggleContainerLockEvent )
	{
		GetPS().SetLocked( evt.isLocked );
		RefereshInteraction( GetPlayer( GetGame() ), true );
	}

	public const function IsLocked( activator : GameObject ) : Bool
	{
		var ts : TransactionSystem;
		var isLocked : Bool;
		if( GetPS().IsLocked() )
		{
			return true;
		}
		ts = GameInstance.GetTransactionSystem( GetGame() );
		if( !( ts ) )
		{
			return false;
		}
		if( TDBID.IsValid( m_lockedByKey ) )
		{
			if( !( ts.HasItem( activator, ItemID.FromTDBID( m_lockedByKey ) ) ) )
			{
				isLocked = true;
			}
			else
			{
				isLocked = false;
			}
		}
		return isLocked;
	}

	protected event OnInteractionActivated( evt : InteractionActivationEvent )
	{
		var actorUpdateData : HUDActorUpdateData;
		if( evt.eventType == gameinteractionsEInteractionEventType.EIET_activate )
		{
			if( evt.activator.IsPlayer() )
			{
				RefereshInteraction( evt.activator );
				if( IsQualityRangeInteractionLayer( evt.layerData.tag ) )
				{
					m_isInIconForcedVisibilityRange = true;
					actorUpdateData = new HUDActorUpdateData;
					actorUpdateData.updateIsInIconForcedVisibilityRange = true;
					actorUpdateData.isInIconForcedVisibilityRangeValue = true;
					RequestHUDRefresh( actorUpdateData );
				}
			}
		}
		else
		{
			if( IsQualityRangeInteractionLayer( evt.layerData.tag ) && evt.activator.IsPlayer() )
			{
				m_isInIconForcedVisibilityRange = false;
				actorUpdateData = new HUDActorUpdateData;
				actorUpdateData.updateIsInIconForcedVisibilityRange = true;
				actorUpdateData.isInIconForcedVisibilityRangeValue = false;
				RequestHUDRefresh( actorUpdateData );
			}
		}
	}

	protected override function ResolveQualityRangeInteractionLayer()
	{
		var evt : InteractionSetEnableEvent;
		var currentLayer : CName;
		if( IsNameValid( m_activeQualityRangeInteraction ) )
		{
			evt = new InteractionSetEnableEvent;
			evt.enable = false;
			evt.layer = m_activeQualityRangeInteraction;
			QueueEvent( evt );
			m_activeQualityRangeInteraction = '';
		}
		if( m_lootQuality != gamedataQuality.Invalid && m_lootQuality != gamedataQuality.Random )
		{
			evt = new InteractionSetEnableEvent;
			evt.enable = true;
			if( IsQuest() )
			{
				currentLayer = 'QualityRange_Max';
			}
			else if( m_lootQuality == gamedataQuality.Common )
			{
				currentLayer = 'QualityRange_Short';
			}
			else if( m_lootQuality == gamedataQuality.Uncommon )
			{
				currentLayer = 'QualityRange_Medium';
			}
			else if( m_lootQuality == gamedataQuality.Rare )
			{
				currentLayer = 'QualityRange_Medium';
			}
			else if( m_lootQuality == gamedataQuality.Epic )
			{
				currentLayer = 'QualityRange_Max';
			}
			else if( m_lootQuality == gamedataQuality.Legendary )
			{
				currentLayer = 'QualityRange_Max';
			}
			else if( m_lootQuality == gamedataQuality.Iconic )
			{
				currentLayer = 'QualityRange_Max';
			}
			evt.layer = currentLayer;
			m_activeQualityRangeInteraction = currentLayer;
			QueueEvent( evt );
		}
	}

	protected function RefereshInteraction( activator : GameObject, optional force : Bool )
	{
		var ts : TransactionSystem;
		var isLocked : Bool;
		var controlWrapper : LootVisualiserControlWrapper;
		var setChoices : InteractionSetChoicesEvent;
		if( activator == NULL )
		{
			return;
		}
		if( IsDisabled() )
		{
			return;
		}
		ts = GameInstance.GetTransactionSystem( GetGame() );
		if( !( ts ) )
		{
			return;
		}
		isLocked = IsLocked( activator );
		if( ( TDBID.IsValid( m_lockedByKey ) || force ) || isLocked )
		{
			LootVisualiserControlWrapper.AddOperation( controlWrapper, gameinteractionsELootVisualiserControlOperation.Locked, isLocked );
			setChoices = LootVisualiserControlWrapper.Wrap( controlWrapper );
			QueueEvent( setChoices );
		}
	}

	private function IsQualityRangeInteractionLayer( layerTag : CName ) : Bool
	{
		return ( layerTag == 'QualityRange_Short' || layerTag == 'QualityRange_Medium' ) || layerTag == 'QualityRange_Max';
	}

	protected function OpenContainerWithTransformAnimation()
	{
		var evtTransformAnimation : gameTransformAnimationPlayEvent;
		evtTransformAnimation = new gameTransformAnimationPlayEvent;
		evtTransformAnimation.animationName = 'Open';
		evtTransformAnimation.looping = false;
		evtTransformAnimation.timeScale = 1.0;
		evtTransformAnimation.timesPlayed = 1;
		QueueEventForEntityID( GetEntityID(), evtTransformAnimation );
	}

	public const override function ShouldShowScanner() : Bool
	{
		if( GameInstance.GetSceneSystem( GetGame() ).GetScriptInterface().IsRewindableSectionActive() )
		{
			return false;
		}
		return super.ShouldShowScanner();
	}

}

class ContainerObjectSingleItemPS extends gameLootContainerBasePS
{
}

import class ContainerObjectSingleItem extends gameContainerObjectBase
{
	protected import var itemTDBID : TweakDBID;
}

class LootContainerObjectAnimatedByTransformPS extends gameLootContainerBasePS
{
}

class LootContainerObjectAnimatedByTransform extends gameContainerObjectBase
{
	protected var wasOpened : Bool;

	protected event OnResetContainerEvent( evt : ResetContainerEvent )
	{
		var evtRegenerateLoot : RegenerateLootEvent;
		var evtTransformAnimationReset : gameTransformAnimationResetEvent;
		var setContainerStateEvent : SetContainerStateEvent;
		var ps : gameLootContainerBasePS;
		evtRegenerateLoot = new RegenerateLootEvent;
		evtTransformAnimationReset = new gameTransformAnimationResetEvent;
		setContainerStateEvent = new SetContainerStateEvent;
		ps = GetPS();
		QueueEvent( evtRegenerateLoot );
		setContainerStateEvent.isDisabled = false;
		GameInstance.GetPersistencySystem( GetGame() ).QueuePSEvent( ps.GetID(), ps.GetClassName(), setContainerStateEvent );
		RegisterToHUDManagerByTask( true );
		if( IsQuest() )
		{
			ToggleLootHighlight( true );
			MarkAsQuest( true );
			ResolveQualityRangeInteractionLayer();
		}
		evtTransformAnimationReset.animationName = 'Open';
		QueueEventForEntityID( GetEntityID(), evtTransformAnimationReset );
		wasOpened = false;
	}

	protected event OnToggleContainerLockEvent( evt : ToggleContainerLockEvent )
	{
		super.OnToggleContainerLockEvent( evt );
		if( !( evt.isLocked ) )
		{
			GameObjectEffectHelper.StartEffectEvent( this, 'fx_checked' );
			RequestHUDRefresh();
			OpenContainerWithTransformAnimation();
			wasOpened = true;
		}
	}

	protected event OnInteraction( choiceEvent : InteractionChoiceEvent )
	{
		super.OnInteraction( choiceEvent );
		if( !( wasOpened ) )
		{
			OpenContainerWithTransformAnimation();
			wasOpened = true;
		}
	}

	private const function HasTransactionFromTweakID( itemId : TweakDBID ) : Bool
	{
		var transactionSystem : weak< TransactionSystem >;
		var currentItemID : ItemID;
		var currentGameData : weak< gameItemData >;
		var tweakID : TweakDBID;
		transactionSystem = GameInstance.GetTransactionSystem( GetGame() );
		currentItemID = ItemID.FromTDBID( itemId );
		currentGameData = transactionSystem.GetItemData( this, currentItemID );
		tweakID = ItemID.GetTDBID( currentGameData.GetID() );
		return tweakID != TDBID.None();
	}

	public const override function IsRifleAmmoLoot() : Bool
	{
		return HasTransactionFromTweakID( T"Ammo.RifleAmmo" );
	}

	public const override function IsShotgunAmmoLoot() : Bool
	{
		return HasTransactionFromTweakID( T"Ammo.ShotgunAmmo" );
	}

	public const override function IsHandgunAmmoLoot() : Bool
	{
		return HasTransactionFromTweakID( T"Ammo.HandgunAmmo" );
	}

	public const override function IsSniperAmmoLoot() : Bool
	{
		return HasTransactionFromTweakID( T"Ammo.SniperRifleAmmo" );
	}

}

class LootContainerObjectAnimatedByTransformWithFlarePS extends LootContainerObjectAnimatedByTransformPS
{
}

class LootContainerObjectAnimatedByTransformWithFlare extends LootContainerObjectAnimatedByTransform
{
	var m_colliderWithInteraction : IComponent;
	var m_colliderWithoutInteraction : IComponent;
	var m_lightComponent1 : IComponent;
	var m_lightComponent2 : IComponent;

	protected event OnRequestComponents( ri : EntityRequestComponentsInterface )
	{
		super.OnRequestComponents( ri );
		EntityRequestComponentsInterface.RequestComponent( ri, 'ColliderWithoutInteraction', 'entColliderComponent', false );
		EntityRequestComponentsInterface.RequestComponent( ri, 'ColliderWithInteraction', 'entColliderComponent', false );
		EntityRequestComponentsInterface.RequestComponent( ri, 'L_Flare_FX', 'entLightComponent', false );
		EntityRequestComponentsInterface.RequestComponent( ri, 'L_Flare_FX_01', 'entLightComponent', false );
	}

	protected event OnTakeControl( ri : EntityResolveComponentsInterface )
	{
		super.OnTakeControl( ri );
		m_colliderWithInteraction = ( ( IComponent )( EntityResolveComponentsInterface.GetComponent( ri, 'ColliderWithInteraction' ) ) );
		m_colliderWithoutInteraction = ( ( IComponent )( EntityResolveComponentsInterface.GetComponent( ri, 'ColliderWithoutInteraction' ) ) );
		m_lightComponent1 = ( ( IComponent )( EntityResolveComponentsInterface.GetComponent( ri, 'L_Flare_FX' ) ) );
		m_lightComponent2 = ( ( IComponent )( EntityResolveComponentsInterface.GetComponent( ri, 'L_Flare_FX_01' ) ) );
	}

	protected event OnToggleContainerLockEvent( evt : ToggleContainerLockEvent )
	{
		super.OnToggleContainerLockEvent( evt );
		if( wasOpened )
		{
			m_colliderWithInteraction.Toggle( true );
			m_colliderWithoutInteraction.Toggle( false );
			RequestHUDRefresh();
			m_lightComponent1.Toggle( false );
			m_lightComponent2.Toggle( false );
			GameObjectEffectHelper.BreakEffectLoopEvent( this, 'e_vfx_flare_smoke_red_1' );
			GameObjectEffectHelper.BreakEffectLoopEvent( this, 'e_vfx_flare_smoke_red_2' );
		}
	}

	protected event OnGameAttached()
	{
		var isEmpty : Bool;
		var isDisabled : Bool;
		var isLocked : Bool;
		super.OnGameAttached();
		isEmpty = IsEmpty();
		isDisabled = IsDisabled();
		if( !( isEmpty ) && !( isDisabled ) )
		{
			isLocked = IsLocked( GetPlayer( GetGame() ) );
			m_colliderWithInteraction.Toggle( !( isLocked ) );
			m_colliderWithoutInteraction.Toggle( isLocked );
			m_lightComponent1.Toggle( isLocked );
			m_lightComponent2.Toggle( isLocked );
			if( isLocked )
			{
				GameObjectEffectHelper.StartEffectEvent( this, 'e_vfx_flare_smoke_red_1' );
				GameObjectEffectHelper.StartEffectEvent( this, 'e_vfx_flare_smoke_red_2' );
			}
		}
	}

	protected event OnInteraction( choiceEvent : InteractionChoiceEvent )
	{
		super.OnInteraction( choiceEvent );
		if( wasOpened )
		{
			m_colliderWithInteraction.Toggle( true );
			m_colliderWithoutInteraction.Toggle( false );
			GameObjectEffectHelper.BreakEffectLoopEvent( this, 'e_vfx_flare_smoke_red_1' );
			GameObjectEffectHelper.BreakEffectLoopEvent( this, 'e_vfx_flare_smoke_red_2' );
			m_lightComponent1.Toggle( false );
			m_lightComponent2.Toggle( false );
		}
	}

}

