using System;
using System.Collections;
using System.Runtime.InteropServices.WindowsRuntime;
using UnityEngine;
namespace HQFPSWeapons
{
[Serializable]
public class ItemContainer : IEnumerable
{
public ItemSlot this[int i] { get { return m_Slots[i]; } set { m_Slots[i] = value; } }
// A little hack for now
public int SelectedSlot { get; set; }
/// Slot count.
public int Count { get { return m_Slots.Length; } }
public ItemSlot[] Slots { get { return m_Slots; } }
public string Name { get { return m_Name; } }
public ItemContainerFlags Flag { get { return m_Flag; } }
public Transform Parent { get { return m_Parent; } }
public bool IsExpanded { get { return m_IsExpanded; } set { m_IsExpanded = value; } }
[NonSerialized]
public Message Changed = new Message();
[NonSerialized]
private Transform m_Parent = null;
private string m_Name;
private ItemContainerFlags m_Flag;
private ItemSlot[] m_Slots;
private string[] m_ValidCategories;
private string[] m_RequiredProperties;
private bool m_IsExpanded = true;
public ItemContainer(string name, int size, Transform parent, ItemContainerFlags flag, string[] validCategories = null, string[] validProperties = null)
{
m_Name = name;
m_Slots = new ItemSlot[size];
for(int i = 0;i < m_Slots.Length;i ++)
{
m_Slots[i] = new ItemSlot();
m_Slots[i].Changed.AddListener(OnSlotChanged);
}
m_Flag = flag;
m_ValidCategories = validCategories;
m_RequiredProperties = validProperties;
}
IEnumerator IEnumerable.GetEnumerator()
{
return m_Slots.GetEnumerator();
}
public int AddItem(ItemData itemData, int amount, ItemPropertyList customProperties = null)
{
if(itemData == null || !AllowsItem(itemData))
return 0;
int amountInInventory = GetItemCount(itemData.Name);
if (amountInInventory >= itemData.StackSize)
return 0;
else
amount = Mathf.Min(itemData.StackSize - amountInInventory, amount);
int added = 0;
// Go through each slot and see where we can add the item(s)
for(int i = 0;i < m_Slots.Length;i ++)
{
added += AddToSlot(m_Slots[i], itemData, amount, customProperties);
// We've added all the items, we can stop now
if(added == amount)
return added;
}
return added;
}
public int AddItem(string name, int amount, ItemPropertyList customProperties = null)
{
ItemData itemData;
if(!ItemDatabase.Default.TryGetItem(name, out itemData) || !AllowsItem(itemData))
return 0;
return AddItem(itemData, amount, customProperties);
}
public bool AddItem(SaveableItem item)
{
if(AllowsItem(item))
{
if(item.CurrentStackSize > 1)
return AddItem(item.Data, item.CurrentStackSize, item.Properties) > 0;
else
{
if(m_Slots != null && m_Slots.Length > 0 && !m_Slots[Mathf.Clamp(SelectedSlot, 0, m_Slots.Length - 1)].HasItem)
{
m_Slots[Mathf.Clamp(SelectedSlot, 0, m_Slots.Length - 1)].SetItem(item);
return true;
}
else
{
// Go through each slot and see where we can add the item
for (int i = 0; i < m_Slots.Length; i++)
{
if (!m_Slots[i].HasItem)
{
m_Slots[i].SetItem(item);
return true;
}
}
}
return false;
}
}
else
return false;
}
public int RemoveItem(string name, int amount)
{
int removed = 0;
for(int i = 0;i < m_Slots.Length;i ++)
{
if(m_Slots[i].HasItem && m_Slots[i].Item.Name == name)
{
removed += m_Slots[i].RemoveFromStack(amount - removed);
// We've removed all the items, we can stop now
if(removed == amount)
return removed;
}
}
return removed;
}
public bool RemoveItem(SaveableItem item)
{
for(int i = 0;i < m_Slots.Length;i ++)
if(m_Slots[i].Item == item)
{
m_Slots[i].SetItem(null);
return true;
}
return false;
}
public bool ContainsItem(SaveableItem item)
{
for(int i = 0;i < m_Slots.Length;i ++)
if(m_Slots[i].Item == item)
return true;
return false;
}
public int GetItemCount(string name)
{
int count = 0;
for(int i = 0;i < m_Slots.Length;i ++)
{
if(m_Slots[i].HasItem && m_Slots[i].Item.Name == name)
count += m_Slots[i].Item.CurrentStackSize;
}
return count;
}
public bool AllowsItem(ItemData itemData)
{
bool isFromValidCategories = m_ValidCategories == null || m_ValidCategories.Length == 0;
bool hasValidProperties = true;
if(m_ValidCategories != null)
{
for(int i = 0;i < m_ValidCategories.Length;i ++)
{
if(m_ValidCategories[i] == itemData.Category)
isFromValidCategories = true;
}
}
if(m_RequiredProperties != null)
{
for(int i = 0;i < m_RequiredProperties.Length;i ++)
{
bool hasProperty = false;
for(int p = 0;p < itemData.Properties.Length;p ++)
{
if(itemData.Properties[p].Name == m_RequiredProperties[i])
{
hasProperty = true;
break;
}
}
if(!hasProperty)
{
hasValidProperties = false;
break;
}
}
}
return isFromValidCategories && hasValidProperties;
}
public bool AllowsItem(SaveableItem item)
{
bool isFromValidCategories = m_ValidCategories == null || m_ValidCategories.Length == 0;
bool hasRequiredProperties = true;
if(m_ValidCategories != null)
{
for(int i = 0;i < m_ValidCategories.Length;i ++)
{
if(m_ValidCategories[i] == item.Data.Category)
isFromValidCategories = true;
}
}
if(m_RequiredProperties != null)
{
for(int i = 0;i < m_RequiredProperties.Length;i ++)
{
if(!item.HasProperty(m_RequiredProperties[i]))
hasRequiredProperties = false;
}
}
return isFromValidCategories && hasRequiredProperties;
}
public int GetPositionOfItem(SaveableItem item)
{
for(int i = 0; i < m_Slots.Length; i ++)
if(m_Slots[i].Item == item)
return i;
return -1;
}
public bool ContainerIsFull ()
{
foreach (var slot in m_Slots)
{
if (!slot.HasItem)
return false;
}
return true;
}
private int AddToSlot(ItemSlot slot, ItemData itemData, int amount, ItemPropertyList customProperties = null)
{
if(slot.HasItem && itemData.Name != slot.Item.Name)
return 0;
bool wasEmpty = false;
if(!slot.HasItem)
{
slot.SetItem(new SaveableItem(itemData, 1, customProperties));
amount --;
wasEmpty = true;
}
int addedToStack = slot.AddToStack(amount);
return addedToStack + (wasEmpty ? 1 : 0);
}
private void OnSlotChanged(ItemSlot slot)
{
try
{
Changed.Send(slot);
}
catch { };
}
}
}