using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public class WeightedItem<T>
{
	public WeightedItem()
	{
	}
	
	public WeightedItem(T value, float weight)
	{
		this.value = value;
		this.weight = weight;
	}
	
	public T value { get; set; }
	public float weight	{ get; set; }
}

public class WeightedPicklist<T> : IEnumerable<WeightedItem<T>>, ICollection<WeightedItem<T>>
{
	private float _totalWeight;
	private List<WeightedItem<T>> _items;
	
	public WeightedPicklist()
	{
		_items = new List<WeightedItem<T>>();	
	}
	
	public WeightedItem<T> this[int index]
	{
		get { return _items[index]; }
	}
	
	public int Count
	{
		get { return _items.Count; }
	}
	
	public bool IsReadOnly
	{
		get { return false; }
	}
	
	public void Add(T value, float weight)
	{
		var item = new WeightedItem<T>(value, weight);
		_totalWeight += weight;
		_items.Add(item);
	}
	
	public void Add(WeightedItem<T> item)
	{
		_totalWeight += item.weight;
		_items.Add(item);
	}
	
	public void AddRange(IEnumerable<WeightedItem<T>> range)
	{
		foreach(var item in range)
		{
			Add(item);
		}
	}
	
	public void Clear()
	{
		_totalWeight = 0f;
		_items.Clear();
	}
	
	public bool Contains(WeightedItem<T> item)
	{
		return _items.Contains(item);
	}
	
	public void CopyTo(WeightedItem<T>[] array, int index)
	{
		_items.CopyTo(array, index);
	}
	
	public bool Remove(WeightedItem<T> item)
	{
		var isRemoved = _items.Remove(item);
		if(isRemoved)
		{
			_totalWeight -= item.weight;
		}
		return isRemoved;
	}
	
	public void RemoveAt(int index)
	{
		_totalWeight -= _items[index].weight;
		_items.RemoveAt(index);
	}
	
	public T PickRandom()
	{
		if(_items.Count == 0)
		{
			return default(T);
		}
		
		float value = Random.value * _totalWeight;
		
		for(int i = 0; i < _items.Count; i++)
		{
			var item = _items[i];
			value -= item.weight;
			if(value < 0f)
			{
				return item.value;
			}
		}
		
		return _items[_items.Count - 1].value;
	}
	
	public IEnumerator<WeightedItem<T>> GetEnumerator()
	{
		return _items.GetEnumerator();
	}

	IEnumerator IEnumerable.GetEnumerator()
	{
		return _items.GetEnumerator();
	}
	
}
