using System;

namespace WS
{
    ///<summary>创建组件工厂</summary>
    public static class ComponentFactory
	{
		public static WSComponent CreateWithParent(Type type, WSComponent parent, bool fromPool = false)
		{
			WSComponent component = GetComponent(type, fromPool);
			Game.EventSystem.AddVComponent(component);
			component.Parent = parent;
			Game.EventSystem.Awake(component);
			return component;
		}

		public static T CreateWithParent<T>(WSComponent parent, bool fromPool = false) where T : WSComponent
		{
			T component = GetComponent<T>(fromPool);
			Game.EventSystem.AddVComponent(component);
			component.Parent = parent;
			Game.EventSystem.Awake(component);
			return component;
		}

		public static T CreateWithParent<T, A>(WSComponent parent, A a, bool fromPool = false) where T : WSComponent
		{
			T component = GetComponent<T>(fromPool);
			Game.EventSystem.AddVComponent(component);
			component.Parent = parent;
			Game.EventSystem.Awake(component, a);
			return component;
		}

		public static T CreateWithParent<T, A, B>(WSComponent parent, A a, B b, bool fromPool = false) where T : WSComponent
		{
			T component = GetComponent<T>(fromPool);
			Game.EventSystem.AddVComponent(component);
			component.Parent = parent;
			Game.EventSystem.Awake(component, a, b);
			return component;
		}

		public static T CreateWithParent<T, A, B, C>(WSComponent parent, A a, B b, C c, bool fromPool = false) where T : WSComponent
		{
			T component = GetComponent<T>(fromPool);
			Game.EventSystem.AddVComponent(component);
			component.Parent = parent;
			Game.EventSystem.Awake(component, a, b, c);
			return component;
		}

		public static WSComponent Create(Type type, bool fromPool = false)
		{
			WSComponent component = GetComponent(type, fromPool);
			Game.EventSystem.AddVComponent(component);
			Game.EventSystem.Awake(component);
			return component;
		}

		public static T Create<T>(bool fromPool = false) where T : WSComponent
		{
			T component = GetComponent<T>(fromPool);
			Game.EventSystem.AddVComponent(component);
			Game.EventSystem.Awake(component);
			return component;
		}

		public static T Create<T, A>(A a, bool fromPool = false) where T : WSComponent
		{
			T component = GetComponent<T>(fromPool);
			Game.EventSystem.AddVComponent(component);
			Game.EventSystem.Awake(component, a);
			return component;
		}

		public static T Create<T, A, B>(A a, B b, bool fromPool = false) where T : WSComponent
		{
			T component = GetComponent<T>(fromPool);
			Game.EventSystem.AddVComponent(component);
			Game.EventSystem.Awake(component, a, b);
			return component;
		}

		public static T Create<T, A, B, C>(A a, B b, C c, bool fromPool = false) where T : WSComponent
		{
			T component = GetComponent<T>(fromPool);
			Game.EventSystem.AddVComponent(component);
			Game.EventSystem.Awake(component, a, b, c);
			return component;
		}

		private static WSComponent GetComponent(Type type, bool fromPool)
		{
			WSComponent component;
			if (fromPool)
			{
				component = Game.ObjectPool.Fetch(type);
			}
			else
			{
				component = (WSComponent)Activator.CreateInstance(type);
			}
			return component;
		}

		private static T GetComponent<T>(bool fromPool) where T : WSComponent
		{
			Type type = typeof(T);

			T component;
			if (fromPool)
			{
				component = (T)Game.ObjectPool.Fetch(type);
			}
			else
			{
				component = (T)Activator.CreateInstance(type);
			}
			return component;
		}
	}
}