/*
 * +================================================================================+
 *      __  ___  ______________  __  __  ______________   ____
 *     / / / / |/ /  _/_  __/\ \/ / / / / /_  __/  _/ /  / __/
 *    / /_/ /    // /  / /    \  / / /_/ / / / _/ // /___\ \
 *    \____/_/|_/___/ /_/     /_/  \____/ /_/ /___/____/___/
 *
 * +================================================================================+
 *
 *    "THE BEER-WARE LICENSE"
 *    -----------------------
 *
 *    As long as you retain this notice you can do whatever you want with this
 *    stuff. However it is expressly forbidden to sell or commercially distribute
 *    Unity Utils or parts of it apart from your games.
 *    If you meet any of the authors some day, and you think this stuff is
 *    worth it, you can buy them a beer in return.
 *
 *    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 *    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 *    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 *    AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 *    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 *    OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 *    THE SOFTWARE.
 *
 * +================================================================================+
 *
 *    Authors:
 *    David Krummenacher (dave@timbookedtwo.com)
 *
 */

using System.Collections.Generic;
using UnityEngine;

namespace Utils.Helpers {

	/// <summary>
	/// Helper methods for collections like lists and arrays.
	/// </summary>
	public abstract class CollectionHelper {

		/// <summary>
		/// Gets a random entry from a list.
		/// </summary>
		/// <returns>The random entry.</returns>
		/// <param name="list">The list.</param>
		/// <typeparam name="T">The type of the list.</typeparam>
		public static T GetRandomEntry<T>(List<T> list) {
			if (list.Count == 0) return default(T);
			return list[Random.Range(0, list.Count)];
		}

		/// <summary>
		/// Gets a random entry from an array.
		/// </summary>
		/// <returns>The random entry.</returns>
		/// <param name="array">The array.</param>
		/// <typeparam name="T">The type of the array.</typeparam>
		public static T GetRandomEntry<T>(T[] array) {
			if (array.Length == 0) return default(T);
			return array[Random.Range(0, array.Length)];
		}

		/// <summary>
		/// Shuffles the specified list.
		/// This is not optimized. Only use on small lists.
		/// </summary>
		/// <param name="list">The list.</param>
		/// <typeparam name="T">The type of the list.</typeparam>
		public static List<T> Shuffle<T>(List<T> list) {
			// Copy list
			List<T> newList = new List<T>(list);

			if (newList.Count <= 1) return newList;

			for (int i = 0; i < newList.Count; i++) {
				int newIndex = Random.Range(0, newList.Count);

				// Swap elemets
				T temp = newList[i];
				newList[i] = newList[newIndex];
				newList[newIndex] = temp;
			}

			return newList;
		}

		/// <summary>
		/// Shuffles the specified array.
		/// This is not optimized. Only use on small arrays.
		/// </summary>
		/// <param name="array">The array.</param>
		/// <typeparam name="T">The type of the array.</typeparam>
		public static T[] Shuffle<T>(T[] array) {
			if (array.Length <= 1) return array;
			
			for (int i = 0; i < array.Length; i++) {
				int newIndex = Random.Range(0, array.Length);
				
				// Swap elemets
				T temp = array[i];
				array[i] = array[newIndex];
				array[newIndex] = temp;
			}

			return array;
		}
	}
}