class BackpackFilterButtonController extends inkLogicController
{
	protected editable var m_icon : inkImageRef;
	protected editable var m_text : inkTextRef;
	private var m_filterType : ItemFilterCategory;
	private var m_active : Bool;
	private var m_hovered : Bool;

	protected event OnInitialize()
	{
		RegisterToCallback( 'OnHoverOver', this, 'OnHoverOver' );
		RegisterToCallback( 'OnHoverOut', this, 'OnHoverOut' );
	}

	protected event OnHoverOver( evt : inkPointerEvent )
	{
		m_hovered = true;
		if( !( m_active ) )
		{
			GetRootWidget().SetState( 'Hover' );
		}
	}

	protected event OnHoverOut( evt : inkPointerEvent )
	{
		m_hovered = false;
		if( !( m_active ) )
		{
			GetRootWidget().SetState( 'Default' );
		}
	}

	public function Setup( filterType : ItemFilterCategory )
	{
		m_filterType = filterType;
		InkImageUtils.RequestSetImage( this, m_icon, GetIcon( m_filterType ) );
	}

	public function GetFilterType() : ItemFilterCategory
	{
		return m_filterType;
	}

	public function SetActive( value : Bool )
	{
		m_active = value;
		GetRootWidget().SetState( ( ( value ) ? ( 'Active' ) : ( 'Default' ) ) );
		if( !( value ) && m_hovered )
		{
			GetRootWidget().SetState( 'Hover' );
		}
	}

	public function GetLabelKey() : CName
	{
		return GetLabelKey( m_filterType );
	}

	public static function GetLabelKey( filterType : ItemFilterCategory ) : CName
	{
		return ItemFilterCategories.GetLabelKey( filterType );
	}

	private static function GetIcon( filterType : ItemFilterCategory ) : String
	{
		return ItemFilterCategories.GetIcon( filterType );
	}

}

final abstract class ItemFilterCategories
{

	public static function GetLabelKey( filterType : Int32 ) : CName
	{
		return GetLabelKey( ( ( ItemFilterCategory )( filterType ) ) );
	}

	public static function GetLabelKey( filterType : ItemFilterCategory ) : CName
	{
		switch( filterType )
		{
			case ItemFilterCategory.RangedWeapons:
				return 'UI-Filters-RangedWeapons';
			case ItemFilterCategory.MeleeWeapons:
				return 'UI-Filters-MeleeWeapons';
			case ItemFilterCategory.Clothes:
				return 'UI-Filters-Clothes';
			case ItemFilterCategory.Consumables:
				return 'UI-Filters-Consumables';
			case ItemFilterCategory.Grenades:
				return 'UI-Filters-Grenades';
			case ItemFilterCategory.SoftwareMods:
				return 'UI-Filters-Mods';
			case ItemFilterCategory.Attachments:
				return 'UI-Filters-Attachments';
			case ItemFilterCategory.Programs:
				return 'UI-Filters-Hacks';
			case ItemFilterCategory.Cyberware:
				return 'Lockey#45229';
			case ItemFilterCategory.Junk:
				return 'UI-Filters-Junk';
			case ItemFilterCategory.Quest:
				return 'UI-Filters-QuestItems';
			case ItemFilterCategory.NewWardrobeAppearances:
				return 'UI-Filters-NewWardrobeAppearances';
			case ItemFilterCategory.Buyback:
				return 'UI-Filters-Buyback';
			case ItemFilterCategory.AllItems:
				return 'UI-Filters-AllItems';
		}
		return 'UI-Filters-AllItems';
	}

	public static function GetIcon( filterType : Int32 ) : String
	{
		return GetIcon( ( ( ItemFilterCategory )( filterType ) ) );
	}

	public static function GetIcon( filterType : ItemFilterCategory ) : String
	{
		switch( filterType )
		{
			case ItemFilterCategory.RangedWeapons:
				return "UIIcon.Filter_RangedWeapons";
			case ItemFilterCategory.MeleeWeapons:
				return "UIIcon.Filter_MeleeWeapons";
			case ItemFilterCategory.Clothes:
				return "UIIcon.Filter_Clothes";
			case ItemFilterCategory.Consumables:
				return "UIIcon.Filter_Consumables";
			case ItemFilterCategory.Grenades:
				return "UIIcon.Filter_Grenades";
			case ItemFilterCategory.SoftwareMods:
				return "UIIcon.Filter_SoftwareMod";
			case ItemFilterCategory.Attachments:
				return "UIIcon.Filter_Attachments";
			case ItemFilterCategory.Programs:
				return "UIIcon.Filter_Hacks";
			case ItemFilterCategory.Cyberware:
				return "UIIcon.Filter_Cyberware";
			case ItemFilterCategory.Junk:
				return "UIIcon.Filter_Junk";
			case ItemFilterCategory.Quest:
				return "UIIcon.Filter_QuestItems";
			case ItemFilterCategory.NewWardrobeAppearances:
				return "UIIcon.Filter_NewWardrobeAppearances";
			case ItemFilterCategory.Buyback:
				return "UIIcon.Filter_Buyback";
			case ItemFilterCategory.AllItems:
				return "UIIcon.Filter_AllItems";
		}
		return "UIIcon.Filter_AllItems";
	}

}

final abstract class ItemFilters
{

	public static function GetLabelKey( filterType : Int32 ) : CName
	{
		return GetLabelKey( ( ( ItemFilterType )( filterType ) ) );
	}

	public static function GetLabelKey( filterType : ItemFilterType ) : CName
	{
		switch( filterType )
		{
			case ItemFilterType.All:
				return 'UI-Filters-AllItems';
			case ItemFilterType.Weapons:
				return 'UI-Filters-Weapons';
			case ItemFilterType.Clothes:
				return 'UI-Filters-Clothes';
			case ItemFilterType.Consumables:
				return 'UI-Filters-Consumables';
			case ItemFilterType.Cyberware:
				return 'UI-Filters-Cyberware';
			case ItemFilterType.Attachments:
				return 'UI-Filters-Attachments';
			case ItemFilterType.Quest:
				return 'UI-Filters-QuestItems';
			case ItemFilterType.Buyback:
				return 'UI-Filters-Buyback';
			case ItemFilterType.LightWeapons:
				return 'UI-Filters-LightWeapons';
			case ItemFilterType.HeavyWeapons:
				return 'UI-Filters-HeavyWeapons';
			case ItemFilterType.MeleeWeapons:
				return 'UI-Filters-MeleeWeapons';
			case ItemFilterType.Hacks:
				return 'UI-Filters-Hacks';
		}
		return 'UI-Filters-AllItems';
	}

	public static function GetIcon( filterType : Int32 ) : String
	{
		return GetIcon( ( ( ItemFilterType )( filterType ) ) );
	}

	public static function GetIcon( filterType : ItemFilterType ) : String
	{
		switch( filterType )
		{
			case ItemFilterType.All:
				return "UIIcon.Filter_AllItems";
			case ItemFilterType.Weapons:
				return "UIIcon.Filter_Weapons";
			case ItemFilterType.Clothes:
				return "UIIcon.Filter_Clothes";
			case ItemFilterType.Consumables:
				return "UIIcon.Filter_Consumables";
			case ItemFilterType.Cyberware:
				return "UIIcon.Filter_Cyberware";
			case ItemFilterType.Attachments:
				return "UIIcon.Filter_Attachments";
			case ItemFilterType.Quest:
				return "UIIcon.Filter_QuestItems";
			case ItemFilterType.Buyback:
				return "UIIcon.Filter_Buyback";
			case ItemFilterType.LightWeapons:
				return "UIIcon.Filter_LightWeapons";
			case ItemFilterType.HeavyWeapons:
				return "UIIcon.Filter_HeavyWeapons";
			case ItemFilterType.MeleeWeapons:
				return "UIIcon.Filter_MeleeWeapons";
			case ItemFilterType.Hacks:
				return "UIIcon.Filter_Hacks";
		}
		return "UIIcon.Filter_AllItems";
	}

}

enum ItemFilterType
{
	All = 0,
	Weapons = 1,
	Clothes = 2,
	Consumables = 3,
	Cyberware = 4,
	Attachments = 5,
	Quest = 6,
	Buyback = 7,
	LightWeapons = 8,
	HeavyWeapons = 9,
	MeleeWeapons = 10,
	Hacks = 11,
}

class ItemCategoryFliterManager
{
	private var m_filtersToCheck : array< ItemFilterCategory >;
	private var m_filters : array< ItemFilterCategory >;
	private var m_sharedFiltersToCheck : array< ItemFilterCategory >;
	private var m_isOrderDirty : Bool;

	public static function Make( optional skipDefaultFilters : Bool ) : ItemCategoryFliterManager
	{
		var i : Int32;
		var instance : ItemCategoryFliterManager;
		instance = new ItemCategoryFliterManager;
		instance.m_filters.Clear();
		instance.m_filtersToCheck.Clear();
		instance.m_sharedFiltersToCheck.Clear();
		if( !( skipDefaultFilters ) )
		{
			for( i = 0; i < ( ( Int32 )( ItemFilterCategory.BaseCount ) ); i += 1 )
			{
				instance.m_filtersToCheck.PushBack( ( ( ItemFilterCategory )( i ) ) );
			}
		}
		return instance;
	}

	public function AddItem( itemData : weak< gameItemData > )
	{
		var i : Int32;
		for( i = 0; i < m_sharedFiltersToCheck.Size(); i += 1 )
		{
			if( ItemCategoryFliter.IsOfCategoryType( m_sharedFiltersToCheck[ i ], itemData ) )
			{
				if( !( m_filters.Contains( m_sharedFiltersToCheck[ i ] ) ) )
				{
					m_filters.PushBack( m_sharedFiltersToCheck[ i ] );
				}
				m_sharedFiltersToCheck.Erase( i );
				m_isOrderDirty = true;
				continue;
			}
		}
		for( i = 0; i < m_filtersToCheck.Size(); i += 1 )
		{
			if( ItemCategoryFliter.IsOfCategoryType( m_filtersToCheck[ i ], itemData ) )
			{
				if( !( m_filters.Contains( m_filtersToCheck[ i ] ) ) )
				{
					m_filters.PushBack( m_filtersToCheck[ i ] );
				}
				m_filtersToCheck.Remove( m_filtersToCheck[ i ] );
				m_isOrderDirty = true;
				return;
			}
		}
	}

	public function AddItem( itemCategory : ItemFilterCategory )
	{
		var i : Int32;
		for( i = 0; i < m_filtersToCheck.Size(); i += 1 )
		{
			if( m_filtersToCheck[ i ] == itemCategory )
			{
				m_filters.PushBack( m_filtersToCheck[ i ] );
				m_filtersToCheck.Erase( i );
				m_isOrderDirty = true;
				return;
			}
		}
	}

	public function GetAt( index : Int32 ) : ItemFilterCategory
	{
		if( ( index >= 0 ) && ( index < m_filters.Size() ) )
		{
			return m_filters[ index ];
		}
		return ItemFilterCategory.Invalid;
	}

	public function Contains( category : ItemFilterCategory ) : Bool
	{
		return m_filters.Contains( category );
	}

	public function GetFiltersList() : array< ItemFilterCategory >
	{
		var fallbackResult : array< ItemFilterCategory >;
		if( m_filters.Size() == 0 )
		{
			fallbackResult.PushBack( ItemFilterCategory.AllItems );
			return fallbackResult;
		}
		return m_filters;
	}

	public function GetFiltersListSize() : Int32
	{
		return m_filters.Size();
	}

	public function SortFiltersList()
	{
		var result : array< ItemFilterCategory >;
		var i : Int32;
		if( m_isOrderDirty )
		{
			for( i = 0; i < ( ( Int32 )( ItemFilterCategory.AllCount ) ); i += 1 )
			{
				if( m_filters.Contains( ( ( ItemFilterCategory )( i ) ) ) )
				{
					result.PushBack( ( ( ItemFilterCategory )( i ) ) );
				}
			}
			m_filters = result;
			m_isOrderDirty = false;
		}
	}

	public function GetSortedFiltersList() : array< ItemFilterCategory >
	{
		SortFiltersList();
		return GetFiltersList();
	}

	public function GetIntFiltersList() : array< Int32 >
	{
		var result : array< Int32 >;
		var filters : array< ItemFilterCategory >;
		var i : Int32;
		filters = GetFiltersList();
		for( i = 0; i < filters.Size(); i += 1 )
		{
			result.PushBack( ( ( Int32 )( filters[ i ] ) ) );
		}
		return result;
	}

	public function GetSortedIntFiltersList() : array< Int32 >
	{
		SortFiltersList();
		return GetIntFiltersList();
	}

	public function InsertFilter( position : Int32, filter : ItemFilterCategory )
	{
		m_filters.Remove( filter );
		m_filters.Insert( position, filter );
	}

	public function Clear( optional skipDefaultFilters : Bool )
	{
		var i : Int32;
		m_filters.Clear();
		m_sharedFiltersToCheck.Clear();
		m_filtersToCheck.Clear();
		if( !( skipDefaultFilters ) )
		{
			for( i = 0; i < ( ( Int32 )( ItemFilterCategory.BaseCount ) ); i += 1 )
			{
				m_filtersToCheck.PushBack( ( ( ItemFilterCategory )( i ) ) );
			}
		}
	}

	public function AddFilter( filter : ItemFilterCategory )
	{
		if( !( m_filters.Contains( filter ) ) )
		{
			m_filters.PushBack( filter );
			m_isOrderDirty = true;
		}
	}

	private function IsSharedFilter( filter : ItemFilterCategory ) : Bool
	{
		return filter == ItemFilterCategory.Quest;
	}

	public function AddFilterToCheck( filter : ItemFilterCategory )
	{
		if( IsSharedFilter( filter ) )
		{
			m_sharedFiltersToCheck.PushBack( filter );
			return;
		}
		m_filtersToCheck.PushBack( filter );
	}

	public function RemvoeFilterToCheck( filter : ItemFilterCategory )
	{
		if( IsSharedFilter( filter ) )
		{
			m_sharedFiltersToCheck.Remove( filter );
			return;
		}
		m_filtersToCheck.Remove( filter );
	}

}

abstract class ItemCategoryFliter
{

	public static function FilterItem( filter : ItemFilterCategory, wrappedData : WrappedInventoryItemData ) : Bool
	{
		if( filter == ItemFilterCategory.Invalid )
		{
			return true;
		}
		if( wrappedData.Item )
		{
			if( filter == ItemFilterCategory.Quest )
			{
				return wrappedData.Item.IsQuestItem();
			}
			if( filter == ItemFilterCategory.AllItems )
			{
				return true;
			}
			return filter == wrappedData.Item.GetFilterCategory();
		}
		return ItemCategoryFliter.IsOfCategoryType( filter, InventoryItemData.GetGameItemData( wrappedData.ItemData ) );
	}

	public static function IsOfCategoryType( filter : ItemFilterCategory, data : weak< gameItemData > ) : Bool
	{
		if( !( data ) )
		{
			return false;
		}
		switch( filter )
		{
			case ItemFilterCategory.RangedWeapons:
				return data.HasTag( WeaponObject.GetRangedWeaponTag() );
			case ItemFilterCategory.MeleeWeapons:
				return data.HasTag( WeaponObject.GetMeleeWeaponTag() );
			case ItemFilterCategory.Clothes:
				return data.HasTag( 'Clothing' );
			case ItemFilterCategory.Consumables:
				return data.HasTag( 'Consumable' );
			case ItemFilterCategory.Grenades:
				return data.HasTag( 'Grenade' );
			case ItemFilterCategory.Attachments:
				return ( data.HasTag( 'itemPart' ) && !( data.HasTag( 'Fragment' ) ) ) && !( data.HasTag( 'SoftwareShard' ) );
			case ItemFilterCategory.Programs:
				return data.HasTag( 'SoftwareShard' ) || data.HasTag( 'QuickhackCraftingPart' );
			case ItemFilterCategory.Cyberware:
				return data.HasTag( 'Cyberware' ) || data.HasTag( 'Fragment' );
			case ItemFilterCategory.Quest:
				return data.HasTag( 'Quest' );
			case ItemFilterCategory.Junk:
				return data.HasTag( 'Junk' );
			case ItemFilterCategory.AllItems:
				return true;
		}
		return false;
	}

	public static function GetItemCategoryType( data : weak< UIInventoryItem > ) : ItemFilterCategory
	{
		var weaponType : WeaponType;
		var itemType : gamedataItemType;
		weaponType = data.GetWeaponType();
		if( weaponType == WeaponType.Ranged )
		{
			return ItemFilterCategory.RangedWeapons;
		}
		if( weaponType == WeaponType.Melee )
		{
			return ItemFilterCategory.MeleeWeapons;
		}
		itemType = data.GetItemType();
		if( UIInventoryItemsManager.IsItemTypeCloting( itemType ) )
		{
			return ItemFilterCategory.Clothes;
		}
		return ItemFilterCategory.Invalid;
	}

	public static function GetItemCategoryType( data : weak< gameItemData > ) : ItemFilterCategory
	{
		var i : Int32;
		for( i = 0; i < ( ( Int32 )( ItemFilterCategory.BaseCount ) ); i += 1 )
		{
			if( IsOfCategoryType( ( ( ItemFilterCategory )( i ) ), data ) )
			{
				return ( ( ItemFilterCategory )( i ) );
			}
		}
		return ItemFilterCategory.Invalid;
	}

}

enum ItemFilterCategory
{
	RangedWeapons = 0,
	MeleeWeapons = 1,
	Clothes = 2,
	Consumables = 3,
	Grenades = 4,
	SoftwareMods = 5,
	Attachments = 6,
	Programs = 7,
	Cyberware = 8,
	Junk = 9,
	BaseCount = 10,
	Quest = 11,
	NewWardrobeAppearances = 12,
	Buyback = 13,
	AllItems = 14,
	AllCount = 15,
	Invalid = -1,
}

