class CraftingItemTemplateClassifier extends inkVirtualItemTemplateClassifier
{

	public export virtual function ClassifyItem( data : Variant ) : Uint32
	{
		if( IsSmall( data ) )
		{
			return 0;
		}
		else
		{
			return 1;
		}
	}

	public static function IsSmall( data : Variant ) : Bool
	{
		var recipe : RecipeData;
		var inventoryItem : ItemCraftingData;
		recipe = ( ( RecipeData )( ( ( IScriptable )data ) ) );
		if( recipe )
		{
			return recipe.id.EquipArea().Type() != gamedataEquipmentArea.Weapon;
		}
		inventoryItem = ( ( ItemCraftingData )( ( ( IScriptable )data ) ) );
		if( inventoryItem )
		{
			if( InventoryItemData.GetEquipmentArea( inventoryItem.inventoryItem ) == gamedataEquipmentArea.Weapon )
			{
				return false;
			}
			return true;
		}
		return false;
	}

	public static function GetIconPosition( data : Variant ) : ECraftingIconPositioning
	{
		var recipe : RecipeData;
		var inventoryItem : ItemCraftingData;
		recipe = ( ( RecipeData )( ( ( IScriptable )data ) ) );
		if( recipe )
		{
			if( recipe.id.EquipArea().Type() == gamedataEquipmentArea.Weapon )
			{
				return ECraftingIconPositioning.weaponBig;
			}
		}
		inventoryItem = ( ( ItemCraftingData )( ( ( IScriptable )data ) ) );
		if( inventoryItem )
		{
			if( InventoryItemData.GetEquipmentArea( inventoryItem.inventoryItem ) == gamedataEquipmentArea.Weapon )
			{
				if( InventoryItemData.GetShape( inventoryItem.inventoryItem ) == EInventoryItemShape.DoubleSlot )
				{
					return ECraftingIconPositioning.weaponBig;
				}
				else
				{
					return ECraftingIconPositioning.weaponSmall;
				}
			}
		}
		return ECraftingIconPositioning.generic;
	}

}

class CraftingDataView extends ScriptableDataView
{
	private var m_itemFilterType : ItemFilterCategory;
	private var m_itemSortMode : ItemSortMode;
	private var m_attachmentsList : array< gamedataItemType >;
	private var m_uiScriptableSystem : weak< UIScriptableSystem >;

	public function BindUIScriptableSystem( uiScriptableSystem : weak< UIScriptableSystem > )
	{
		m_uiScriptableSystem = uiScriptableSystem;
	}

	public function SetFilterType( type : ItemFilterCategory )
	{
		m_itemFilterType = type;
		Filter();
	}

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

	public function SetSortMode( mode : ItemSortMode )
	{
		m_itemSortMode = mode;
		Sort();
	}

	public function GetSortMode() : ItemSortMode
	{
		return m_itemSortMode;
	}

	protected virtual function PreSortingInjection( builder : ItemCompareBuilder ) : ItemCompareBuilder
	{
		return builder;
	}

	public export override function SortItem( left : IScriptable, right : IScriptable ) : Bool
	{
		var itemDataLeft, itemDataRight : ItemCraftingData;
		var recipeDataLeft, recipeDataRight : RecipeData;
		var leftItem, rightItem : InventoryItemSortData;
		itemDataLeft = ( ( ItemCraftingData )( ( ( IScriptable )( left ) ) ) );
		itemDataRight = ( ( ItemCraftingData )( ( ( IScriptable )( right ) ) ) );
		recipeDataLeft = ( ( RecipeData )( ( ( IScriptable )( left ) ) ) );
		recipeDataRight = ( ( RecipeData )( ( ( IScriptable )( right ) ) ) );
		if( itemDataLeft && itemDataRight )
		{
			leftItem = InventoryItemData.GetSortData( itemDataLeft.inventoryItem );
			rightItem = InventoryItemData.GetSortData( itemDataRight.inventoryItem );
			if( leftItem.Name == "" )
			{
				leftItem = ItemCompareBuilder.BuildInventoryItemSortData( itemDataLeft.inventoryItem, m_uiScriptableSystem );
			}
			if( rightItem.Name == "" )
			{
				rightItem = ItemCompareBuilder.BuildInventoryItemSortData( itemDataRight.inventoryItem, m_uiScriptableSystem );
			}
		}
		else if( recipeDataLeft && recipeDataRight )
		{
			leftItem = InventoryItemData.GetSortData( recipeDataLeft.inventoryItem );
			rightItem = InventoryItemData.GetSortData( recipeDataRight.inventoryItem );
		}
		switch( m_itemSortMode )
		{
			case ItemSortMode.NewItems:
				return PreSortingInjection( ItemCompareBuilder.Make( leftItem, rightItem ) ).NewItem( m_uiScriptableSystem ).QualityDesc().ItemType().NameAsc().GetBool();
			case ItemSortMode.NameAsc:
				return PreSortingInjection( ItemCompareBuilder.Make( leftItem, rightItem ) ).NameAsc().QualityDesc().GetBool();
			case ItemSortMode.NameDesc:
				return PreSortingInjection( ItemCompareBuilder.Make( leftItem, rightItem ) ).NameDesc().QualityDesc().GetBool();
			case ItemSortMode.DpsAsc:
				return PreSortingInjection( ItemCompareBuilder.Make( leftItem, rightItem ) ).DPSAsc().QualityDesc().NameAsc().GetBool();
			case ItemSortMode.DpsDesc:
				return PreSortingInjection( ItemCompareBuilder.Make( leftItem, rightItem ) ).DPSDesc().QualityDesc().NameDesc().GetBool();
			case ItemSortMode.QualityAsc:
				return PreSortingInjection( ItemCompareBuilder.Make( leftItem, rightItem ) ).QualityDesc().NameAsc().QualityDesc().GetBool();
			case ItemSortMode.QualityDesc:
				return PreSortingInjection( ItemCompareBuilder.Make( leftItem, rightItem ) ).QualityAsc().NameAsc().QualityDesc().GetBool();
			case ItemSortMode.WeightAsc:
				return PreSortingInjection( ItemCompareBuilder.Make( leftItem, rightItem ) ).WeightAsc().NameAsc().QualityDesc().GetBool();
			case ItemSortMode.WeightDesc:
				return PreSortingInjection( ItemCompareBuilder.Make( leftItem, rightItem ) ).WeightDesc().NameAsc().QualityDesc().GetBool();
			case ItemSortMode.PriceAsc:
				return PreSortingInjection( ItemCompareBuilder.Make( leftItem, rightItem ) ).PriceAsc().NameAsc().QualityDesc().GetBool();
			case ItemSortMode.PriceDesc:
				return PreSortingInjection( ItemCompareBuilder.Make( leftItem, rightItem ) ).PriceDesc().NameAsc().QualityDesc().GetBool();
			case ItemSortMode.ItemType:
				return PreSortingInjection( ItemCompareBuilder.Make( leftItem, rightItem ) ).ItemType().NameAsc().QualityDesc().GetBool();
		}
		return PreSortingInjection( ItemCompareBuilder.Make( leftItem, rightItem ) ).ChimeraMod().QualityDesc().ItemType().NameAsc().GetBool();
	}

	public export override function FilterItem( item : IScriptable ) : Bool
	{
		var itemData : ItemCraftingData;
		var recipeData : RecipeData;
		var itemRecord : Item_Record;
		itemData = ( ( ItemCraftingData )( ( ( IScriptable )( item ) ) ) );
		recipeData = ( ( RecipeData )( ( ( IScriptable )( item ) ) ) );
		if( itemData )
		{
			itemRecord = TweakDBInterface.GetItemRecord( ItemID.GetTDBID( InventoryItemData.GetID( itemData.inventoryItem ) ) );
		}
		else if( recipeData )
		{
			itemRecord = recipeData.id;
		}
		switch( m_itemFilterType )
		{
			case ItemFilterCategory.RangedWeapons:
				return itemRecord.TagsContains( WeaponObject.GetRangedWeaponTag() );
			case ItemFilterCategory.MeleeWeapons:
				return itemRecord.TagsContains( WeaponObject.GetMeleeWeaponTag() );
			case ItemFilterCategory.Clothes:
				return itemRecord.TagsContains( 'Clothing' );
			case ItemFilterCategory.Consumables:
				return itemRecord.TagsContains( 'Consumable' ) || itemRecord.TagsContains( 'Ammo' );
			case ItemFilterCategory.Grenades:
				return itemRecord.TagsContains( 'Grenade' );
			case ItemFilterCategory.Attachments:
				return ( itemRecord.TagsContains( 'itemPart' ) && !( itemRecord.TagsContains( 'Fragment' ) ) ) && !( itemRecord.TagsContains( 'SoftwareShard' ) );
			case ItemFilterCategory.Programs:
				return itemRecord.TagsContains( 'SoftwareShard' ) || itemRecord.TagsContains( 'QuickhackCraftingPart' );
			case ItemFilterCategory.Cyberware:
				return itemRecord.TagsContains( 'Cyberware' ) || itemRecord.TagsContains( 'Fragment' );
			case ItemFilterCategory.AllItems:
				return true;
		}
		return true;
	}

}

enum ECraftingIconPositioning
{
	generic = 0,
	weaponBig = 1,
	weaponSmall = 2,
}

