class Disarm extends Event
{
	var requester : weak< GameObject >;
}

class Arm extends Event
{
	var requester : weak< GameObject >;
}

class DisarmComponent extends ScriptableComponent
{
	var m_isDisarmingOngoing : Bool;
	default m_isDisarmingOngoing = false;
	var m_owner : weak< GameObject >;
	var m_requester : weak< GameObject >;

	public export function OnGameAttach()
	{
		m_owner = GetOwner();
	}

	protected event OnDisarm( evt : Disarm )
	{
		if( !( evt.requester ) )
		{
			return false;
		}
		m_isDisarmingOngoing = true;
		m_requester = evt.requester;
		if( UnequipWeapons() )
		{
			return false;
		}
		DisarmOwner();
	}

	protected event OnArm( evt : Arm )
	{
		ArmOwner( evt.requester );
	}

	protected event OnUnequipEnded( evt : UnequipEnd )
	{
		if( !( m_isDisarmingOngoing ) )
		{
			return false;
		}
		if( ( evt.GetSlotID() == T"AttachmentSlots.WeaponLeft" ) || ( evt.GetSlotID() == T"AttachmentSlots.WeaponRight" ) )
		{
			DisarmOwner();
		}
	}

	protected function UnequipWeapons() : Bool
	{
		var ts : TransactionSystem;
		var leftHandItem : ItemObject;
		var rightHandItem : ItemObject;
		ts = GetTransactionSystem();
		if( ts && m_owner )
		{
			leftHandItem = ts.GetItemInSlot( m_owner, T"AttachmentSlots.WeaponLeft" );
			rightHandItem = ts.GetItemInSlot( m_owner, T"AttachmentSlots.WeaponRight" );
			if( leftHandItem || rightHandItem )
			{
				SendEquipmentSystemWeaponManipulationRequest( EquipmentManipulationAction.UnequipAll );
				return true;
			}
		}
		return false;
	}

	protected function DisarmOwner()
	{
		var weapons : array< weak< gameItemData > >;
		var notification : SimpleScreenMessage;
		var evt : Disarm;
		var ts : TransactionSystem;
		var i : Int32;
		var tagNames : array< CName >;
		ts = GetTransactionSystem();
		if( !( ts ) )
		{
			return;
		}
		weapons = GetWeapons();
		evt = new Disarm;
		evt.requester = m_owner;
		m_requester.QueueEvent( evt );
		if( weapons.Size() > 0 )
		{
			for( i = 0; i < weapons.Size(); i += 1 )
			{
				ts.TransferItem( m_owner, m_requester, weapons[ i ].GetID(), weapons[ i ].GetQuantity(), tagNames, true );
			}
			notification.isShown = true;
			notification.duration = 3.0;
			notification.message = "LocKey#78051";
			GameInstance.GetBlackboardSystem( m_owner.GetGame() ).Get( GetAllBlackboardDefs().UI_Notifications ).SetVariant( GetAllBlackboardDefs().UI_Notifications.WarningMessage, notification, true );
			SendEquipmentSystemClearAllWeaponSlotsRequest();
		}
		CleanUp();
		GameInstance.GetAutoSaveSystem( m_owner.GetGame() ).RequestCheckpoint();
	}

	protected function ArmOwner( requester : weak< GameObject > )
	{
		var ts : TransactionSystem;
		var notification : SimpleScreenMessage;
		ts = GetTransactionSystem();
		if( !( ts ) )
		{
			return;
		}
		ts.TransferAllItems( requester, m_owner );
		notification.isShown = true;
		notification.duration = 3.0;
		notification.message = "LocKey#78050";
		GameInstance.GetBlackboardSystem( m_owner.GetGame() ).Get( GetAllBlackboardDefs().UI_Notifications ).SetVariant( GetAllBlackboardDefs().UI_Notifications.WarningMessage, notification, true );
		GameInstance.GetAutoSaveSystem( m_owner.GetGame() ).RequestCheckpoint();
		m_isDisarmingOngoing = false;
	}

	protected function GetWeapons() : array< weak< gameItemData > >
	{
		var ts : TransactionSystem;
		var allItems : array< weak< gameItemData > >;
		var weapons : array< weak< gameItemData > >;
		ts = GetTransactionSystem();
		if( ts && m_owner )
		{
			ts.GetItemList( m_owner, allItems );
			RPGManager.ExtractItemsOfEquipArea( gamedataEquipmentArea.Weapon, allItems, weapons );
			RPGManager.ExtractItemsOfEquipArea( gamedataEquipmentArea.QuickSlot, allItems, weapons );
		}
		return weapons;
	}

	protected function CleanUp()
	{
		m_requester = NULL;
		m_isDisarmingOngoing = false;
	}

	private function GetEquipmentSystem() : EquipmentSystem
	{
		var owner : GameObject;
		if( m_owner == NULL )
		{
			owner = GetOwner();
		}
		else
		{
			owner = m_owner;
		}
		return ( ( EquipmentSystem )( GameInstance.GetScriptableSystemsContainer( owner.GetGame() ).Get( 'EquipmentSystem' ) ) );
	}

	private function SendEquipmentSystemWeaponManipulationRequest( requestType : EquipmentManipulationAction, optional equipAnimType : gameEquipAnimationType )
	{
		var request : EquipmentSystemWeaponManipulationRequest;
		request = new EquipmentSystemWeaponManipulationRequest;
		request.owner = m_owner;
		request.requestType = requestType;
		if( equipAnimType != gameEquipAnimationType.Default )
		{
			request.equipAnimType = equipAnimType;
		}
		GetEquipmentSystem().QueueRequest( request );
	}

	private function SendEquipmentSystemClearAllWeaponSlotsRequest()
	{
		var request : ClearAllWeaponSlotsRequest;
		request = new ClearAllWeaponSlotsRequest;
		request.owner = m_owner;
		GetEquipmentSystem().QueueRequest( request );
	}

}

