class DepositQuestItems extends ActionBool
{

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

}

class OpenVendorUI extends ActionBool
{

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

}

class CollectDropPointRewards extends ActionBool
{

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

}

class AddItemForPlayerToPickUp extends ScriptableDeviceAction
{
	[ customEditor = "TweakDBGroupInheritance;LootTables.Base_sts_reward" ][ tooltip = "Items from this loot table will be generated and as long as they are not collected player will have an additionl choice when interacting with Drop Point" ]
	editable var lootTable : TweakDBID;
	editable var shouldAdd : Bool;
	default shouldAdd = true;

	public constexpr export function GetFriendlyDescription() : String
	{
		return "ADD QUEST REWARD TO DROP POINT";
	}

}

class ReserveItemToThisDropPoint extends ScriptableDeviceAction
{
	[ customEditor = "TweakDBGroupInheritance;Items.STSItem" ][ tooltip = "Force player to deliver this item to this specific drop point" ]
	editable var item : TweakDBID;

	public constexpr export function GetFriendlyDescription() : String
	{
		return "RESERVE ITEM FOR THIS DROP POINT ONLY";
	}

}

class DropPointController extends ScriptableDeviceComponent
{

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

}

class DropPointControllerPS extends BasicDistractionDeviceControllerPS
{
	[ customEditor = "TweakDBGroupInheritance;Vendors.DropPoint" ]
	private editable var m_vendorRecord : String;
	private persistent var m_rewardsLootTable : array< TweakDBID >;
	private persistent var m_hasPlayerCollectedReward : Bool;

	protected override function SetDeviceState( state : EDeviceStatus )
	{
		super.SetDeviceState( state );
		if( state != EDeviceStatus.ON && !( IsAttachedToGame() ) )
		{
			UnregisterDropPointMappinInSystem();
		}
	}

	private function UnregisterDropPointMappinInSystem()
	{
		var request : UnregisterDropPointMappinRequest;
		request = new UnregisterDropPointMappinRequest;
		request.ownerID = GetMyEntityID();
		request.removeFromSystem = true;
		GetDropPointSystem().QueueRequest( request );
	}

	public quest const function IsRewardCollected() : Bool
	{
		return m_hasPlayerCollectedReward;
	}

	public const function GetVendorRecordPath() : String
	{
		return m_vendorRecord;
	}

	protected function ActionDepositQuestItems( executor : GameObject ) : DepositQuestItems
	{
		var action : DepositQuestItems;
		action = new DepositQuestItems;
		action.clearanceLevel = DefaultActionsParametersHolder.GetInteractiveClearance();
		action.SetUp( this );
		action.SetProperties();
		action.SetExecutor( executor );
		action.AddDeviceName( m_deviceName );
		action.CreateInteraction();
		return action;
	}

	protected function OnDepositQuestItems( evt : DepositQuestItems ) : EntityNotificationType
	{
		var i : Int32;
		var items : array< weak< gameItemData > >;
		var ts : TransactionSystem;
		var dps : DropPointSystem;
		ts = GameInstance.GetTransactionSystem( GetGameInstance() );
		dps = ( ( DropPointSystem )( GameInstance.GetScriptableSystemsContainer( GetGameInstance() ).Get( 'DropPointSystem' ) ) );
		if( ( !( ts ) || !( dps ) ) || !( evt.GetExecutor() ) )
		{
			return EntityNotificationType.DoNotNotifyEntity;
		}
		ts.GetItemList( evt.GetExecutor(), items );
		for( i = 0; i < items.Size(); i += 1 )
		{
			if( dps.CanDeposit( ItemID.GetTDBID( items[ i ].GetID() ), GetID() ) )
			{
				items[ i ].RemoveDynamicTag( 'Quest' );
				AddFact( GetGameInstance(), items[ i ].GetName(), 1 );
				ts.RemoveItem( evt.GetExecutor(), items[ i ].GetID(), 99999 );
			}
		}
		UseNotifier( evt );
		return EntityNotificationType.DoNotNotifyEntity;
	}

	protected function ActionOpenVendorUI( executor : GameObject ) : OpenVendorUI
	{
		var action : OpenVendorUI;
		action = new OpenVendorUI;
		action.clearanceLevel = DefaultActionsParametersHolder.GetInteractiveClearance();
		action.SetUp( this );
		action.SetProperties();
		action.SetExecutor( executor );
		action.AddDeviceName( m_deviceName );
		action.CreateInteraction();
		action.CreateActionWidgetPackage();
		return action;
	}

	protected function OnOpenVendorUI( evt : OpenVendorUI ) : EntityNotificationType
	{
		var uiSystem : UISystem;
		var vendorData : VendorPanelData;
		if( !( GetDropPointSystem().IsEnabled() ) )
		{
			return EntityNotificationType.DoNotNotifyEntity;
		}
		uiSystem = GameInstance.GetUISystem( GetGameInstance() );
		if( uiSystem )
		{
			vendorData = new VendorPanelData;
			vendorData.data.vendorId = m_vendorRecord;
			vendorData.data.entityID = GetMyEntityID();
			vendorData.data.isActive = true;
			uiSystem.RequestVendorMenu( vendorData );
		}
		UseNotifier( evt );
		return EntityNotificationType.DoNotNotifyEntity;
	}

	private const function ActionCollectDropPointRewards( executor : GameObject ) : CollectDropPointRewards
	{
		var action : CollectDropPointRewards;
		action = new CollectDropPointRewards;
		action.clearanceLevel = DefaultActionsParametersHolder.GetInteractiveClearance();
		action.SetUp( this );
		action.SetProperties();
		action.SetExecutor( executor );
		action.AddDeviceName( m_deviceName );
		action.CreateInteraction();
		return action;
	}

	private function OnCollectDropPointRewards( evt : CollectDropPointRewards ) : EntityNotificationType
	{
		var lootManager : LootManager;
		var ts : TransactionSystem;
		var itemList : array< ItemModParams >;
		var i : Int32;
		var itemData : weak< gameItemData >;
		var scalingMod : gameStatModifierData;
		var statsSystem : StatsSystem;
		var itemID : ItemID;
		lootManager = GameInstance.GetLootManager( GetGameInstance() );
		ts = GameInstance.GetTransactionSystem( GetGameInstance() );
		if( lootManager && ts )
		{
			for( i = 0; i < m_rewardsLootTable.Size(); i += 1 )
			{
				lootManager.GenerateLoot( m_rewardsLootTable[ i ], itemList, evt.GetExecutor() );
			}
			statsSystem = GameInstance.GetStatsSystem( GetGameInstance() );
			scalingMod = RPGManager.CreateStatModifier( gamedataStatType.PowerLevel, gameStatModifierType.Additive, statsSystem.GetStatValue( evt.GetExecutor().GetEntityID(), gamedataStatType.PowerLevel ) );
			for( i = 0; i < itemList.Size(); i += 1 )
			{
				itemID = itemList[ i ].itemID;
				ts.GiveItem( evt.GetExecutor(), itemID, itemList[ i ].quantity );
				if( !( TweakDBInterface.GetItemRecord( ItemID.GetTDBID( itemID ) ).IsSingleInstance() ) )
				{
					itemData = ts.GetItemData( evt.GetExecutor(), itemID );
					statsSystem.RemoveAllModifiers( itemData.GetStatsObjectID(), gamedataStatType.PowerLevel, true );
					statsSystem.AddSavedModifier( itemData.GetStatsObjectID(), scalingMod );
				}
			}
			m_rewardsLootTable.Clear();
			m_hasPlayerCollectedReward = true;
		}
		UseNotifier( evt );
		GameInstance.GetAutoSaveSystem( GetGameInstance() ).RequestCheckpoint();
		return EntityNotificationType.DoNotNotifyEntity;
	}

	public function OnReserveItemToThisDropPoint( evt : ReserveItemToThisDropPoint ) : EntityNotificationType
	{
		var dps : DropPointSystem;
		var request : DropPointRequest;
		dps = GetDropPointSystem();
		if( dps )
		{
			request = new DropPointRequest;
			request.CreateRequest( evt.item, DropPointPackageStatus.ACTIVE, GetID() );
			dps.QueueRequest( request );
		}
		return EntityNotificationType.DoNotNotifyEntity;
	}

	public function OnAddItemForPlayerToPickUp( evt : AddItemForPlayerToPickUp ) : EntityNotificationType
	{
		var i : Int32;
		if( evt.shouldAdd )
		{
			m_rewardsLootTable.PushBack( evt.lootTable );
			m_hasPlayerCollectedReward = false;
		}
		else
		{
			for( i = 0; i < m_rewardsLootTable.Size(); i += 1 )
			{
				if( m_rewardsLootTable[ i ] == evt.lootTable )
				{
					m_rewardsLootTable.EraseFast( i );
				}
			}
		}
		UseNotifier( evt );
		return EntityNotificationType.DoNotNotifyEntity;
	}

	public override function GetActions( out outActions : array< DeviceAction >, context : GetActionsContext ) : Bool
	{
		var dps : DropPointSystem;
		if( !( super.GetActions( outActions, context ) ) )
		{
			return false;
		}
		dps = GetDropPointSystem();
		if( !( dps.IsEnabled() ) )
		{
			return false;
		}
		if( m_rewardsLootTable.Size() > 0 )
		{
			outActions.PushBack( ActionCollectDropPointRewards( context.processInitiatorObject ) );
		}
		outActions.PushBack( ActionOpenVendorUI( context.processInitiatorObject ) );
		dps = GetDropPointSystem();
		if( dps && dps.HasItemsThatCanBeDeposited( context.processInitiatorObject, GetID() ) )
		{
			outActions.PushBack( ActionDepositQuestItems( context.processInitiatorObject ) );
		}
		SetActionIllegality( outActions, m_illegalActions.regularActions );
		return true;
	}

	protected override function GetDeviceIconTweakDBID() : TweakDBID
	{
		return T"DeviceIcons.ScreenDeviceIcon";
	}

	protected override function GetBackgroundTextureTweakDBID() : TweakDBID
	{
		return T"DeviceIcons.ScreenDeviceBackground";
	}

}

