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

namespace com.deeperbeige.lib
{
    public class Lists
    {
        // Concatenate two lists into a new list
        // Original lists untouched
        public static List<T> Concat<T>(List<T> a, List<T> b)
        {
            if (a == null) throw new ArgumentNullException("a");
            if (b == null) throw new ArgumentNullException("b");
            
            List<T> output = new List<T>();
			output.AddRange(a);
			output.AddRange(b);
            
            return output;
        }
        
		// Union two lists into a new list (no duplicates)
		// Original lists untouched
		public static List<T> Union<T>(List<T> a, List<T> b)
		{
			if (a == null) throw new ArgumentNullException("a");
			if (b == null) throw new ArgumentNullException("b");
			
			List<T> output = new List<T>();
			output.AddRange(a);

			foreach (T element in b)
			{
				if (output.Contains(element)) continue;
				output.Add(element);
			}

			return output;
		}
		
		// Returns contents of list as a string, ideal for debugging
		public static string Contents<T>(List<T> list)
		{
			string result    = "";
			string separator = "";
			
			foreach (T item in list)
			{
				result += separator + item.ToString();
				separator = ", ";
			}
			
			return result;
		}
		
		// In-place unbiased shuffle
        // **** WARNING: UNTESTED ****
        public static void Shuffle<T> (List<T> list)
        {
            int n = list.Count;
            while (n > 1) 
            {
				int k   = Maths.RandomInt(0, --n);
                T temp  = list[n];
				list[n] = list[k];
				list[k] = temp;
            }
        }
        
        // Select a random element from the given list
        public static T RandomElement<T> (List<T> list)
        {
            if (list == null)    return default(T);
            if (list.Count == 0) return default(T);

            int j = Maths.RandomInt(0, list.Count - 1);
            return list[j];
        }
    }
}