/*
 * +================================================================================+
 *      __  ___  ______________  __  __  ______________   ____
 *     / / / / |/ /  _/_  __/\ \/ / / / / /_  __/  _/ /  / __/
 *    / /_/ /    // /  / /    \  / / /_/ / / / _/ // /___\ \
 *    \____/_/|_/___/ /_/     /_/  \____/ /_/ /___/____/___/
 *
 * +================================================================================+
 *
 *    "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>
	/// Game object helper that lets you easily instantiate game objects.
	/// </summary>
	public abstract class GameObjectHelper {

		/// <summary>
		/// Instantiates the specified game object.
		/// </summary>
		/// <param name="original">The original game object.</param>
		public static GameObject Instantiate(GameObject original) {
			return (GameObject) GameObject.Instantiate(original);
		}

		/// <summary>
		/// Instantiates the specified game object at the given position.
		/// </summary>
		/// <param name="original">The original game object.</param>
		/// <param name="position">The position.</param>
		public static GameObject Instantiate(GameObject original, Vector3 position) {
			GameObject instance = (GameObject) GameObject.Instantiate(original);
			instance.transform.position = position;
			return instance;
		}

		/// <summary>
		/// Instantiates the specified game object with the given rotation.
		/// </summary>
		/// <param name="original">The original game object.</param>
		/// <param name="rotation">The rotation.</param>
		public static GameObject Instantiate(GameObject original, Quaternion rotation) {
			GameObject instance = (GameObject) GameObject.Instantiate(original);
			instance.transform.rotation = rotation;
			return instance;
		}

		/// <summary>
		/// Instantiates the specified game object at the given position and with the given rotation.
		/// </summary>
		/// <param name="original">The original game object.</param>
		/// <param name="position">The position.</param>
		/// <param name="rotation">The rotation.</param>
		public static GameObject Instantiate(GameObject original, Vector3 position, Quaternion rotation) {
			GameObject instance = (GameObject) GameObject.Instantiate(original);
			instance.transform.position = position;
			instance.transform.rotation = rotation;
			return instance;
		}

		/// <summary>
		/// Instantiates the specified game object and parents it to a given transform.
		/// </summary>
		/// <param name="original">The original game object.</param>
		/// <param name="parent">The parent.</param>
		public static GameObject Instantiate(GameObject original, Transform parent) {
			return Instantiate(original, parent, Vector3.zero);
		}

		/// <summary>
		/// Instantiates the specified game object and parents it to a given transform with an offset.
		/// </summary>
		/// <param name="original">The original game object.</param>
		/// <param name="parent">The parent.</param>
		/// <param name="offset">The offset.</param>
		public static GameObject Instantiate(GameObject original, Transform parent, Vector3 offset) {
			GameObject instance = (GameObject) GameObject.Instantiate(original);
			instance.transform.parent = parent;
			instance.transform.position = parent.position + offset;
			return instance;
		}

		/// <summary>
		/// Instantiates a random game object.
		/// </summary>
		/// <param name="originals">The original game objects.</param>
		public static GameObject Instantiate(GameObject[] originals) {
			if (originals.Length > 0) return Instantiate(originals[Random.Range(0, originals.Length)]);
			return null;
		}

		/// <summary>
		/// Instantiates a random game object at the given position.
		/// </summary>
		/// <param name="originals">The original game objects.</param>
		/// <param name="position">The position.</param>
		public static GameObject Instantiate(GameObject[] originals, Vector3 position) {
			if (originals.Length > 0) return Instantiate(originals[Random.Range(0, originals.Length)], position);
			return null;
		}

		/// <summary>
		/// Instantiates a random game object and parents it to a given transform.
		/// </summary>
		/// <param name="originals">The original game objects.</param>
		/// <param name="parent">The parent.</param>
		public static GameObject Instantiate(GameObject[] originals, Transform parent) {
			if (originals.Length > 0) return Instantiate(originals[Random.Range(0, originals.Length)], parent);
			return null;
		}

		/// <summary>
		/// Instantiates a random game object and parents it to a given transform with an offset.
		/// </summary>
		/// <param name="originals">The original game objects.</param>
		/// <param name="parent">The parent.</param>
		/// <param name="offset">The offset.</param>
		public static GameObject Instantiate(GameObject[] originals, Transform parent, Vector3 offset) {
			if (originals.Length > 0) return Instantiate(originals[Random.Range(0, originals.Length)], parent, offset);
			return null;
		}

		/// <summary>
		/// Instantiates a random game object.
		/// </summary>
		/// <param name="originals">The original game objects.</param>
		public static GameObject Instantiate(List<GameObject> originals) {
			if (originals.Count > 0) return Instantiate(originals[Random.Range(0, originals.Count)]);
			return null;
		}

		/// <summary>
		/// Instantiates a random game object at the given position.
		/// </summary>
		/// <param name="originals">The original game objects.</param>
		/// <param name="position">The position.</param>
		public static GameObject Instantiate(List<GameObject> originals, Vector3 position) {
			if (originals.Count > 0) return Instantiate(originals[Random.Range(0, originals.Count)], position);
			return null;
		}

		/// <summary>
		/// Instantiates a random game object and parents it to a given transform.
		/// </summary>
		/// <param name="originals">The original game objects.</param>
		/// <param name="parent">The parent.</param>
		public static GameObject Instantiate(List<GameObject> originals, Transform parent) {
			if (originals.Count > 0) return Instantiate(originals[Random.Range(0, originals.Count)], parent);
			return null;
		}

		/// <summary>
		/// Instantiates a random game object and parents it to a given transform with an offset.
		/// </summary>
		/// <param name="originals">The original game objects.</param>
		/// <param name="parent">The parent.</param>
		/// <param name="offset">The offset.</param>
		public static GameObject Instantiate(List<GameObject> originals, Transform parent, Vector3 offset) {
			if (originals.Count > 0) return Instantiate(originals[Random.Range(0, originals.Count)], parent, offset);
			return null;
		}
	}
}
