using System.Collections.Generic;
using FrameworkEngine.Initialize;
using FrameworkEngine.Locate;
using UnityEngine;


namespace GameEngine
{
	public class ProjectileThrower : MonoBehaviour, ILocateBehaviour, IConstructBehaviour
	{
		[SerializeField] private int m_MaxSteps = default(int);
		[SerializeField] private Projectile m_ProjectilePrefab = default(Projectile);
		[SerializeField] private float m_MinSpeed = default(float);
		[SerializeField] private float m_MaxSpeed = default(float);
		[SerializeField] private LineRenderer m_LineRenderer = default(LineRenderer);
		[SerializeField] private float m_Radius = default(float);
		[SerializeField] private LayerMask m_CollisionMask = default(LayerMask);
		[SerializeField] private float m_DistanceScale = default(float);
		private List<Vector3> _pointScratch;




		void IConstructBehaviour.Construct()
		{
			_pointScratch = new List<Vector3>(50);
		}




		public float GetSpeed(float value)
		{
			return Mathf.Lerp(m_MinSpeed, m_MaxSpeed, Mathf.Clamp01(value));
		}


		public void SetPreviewPath(float baseSpeed, float value)
		{
			Vector2 position = transform.position;
			Vector2 startDirection = transform.right;
			
			m_LineRenderer.SetVertexCount(m_MaxSteps);
			m_LineRenderer.SetPosition(0, position);
			int vertices = 1;

			Vector2 velocity = transform.right * GetSpeed(value);

			RaycastHit2D hit = default(RaycastHit2D);
			float distance = 0f;

			while (vertices < m_MaxSteps &&
				   (hit = Physics2D.Raycast(position, velocity.normalized, velocity.magnitude * Time.fixedDeltaTime, m_CollisionMask)).transform == null)
			{
				distance += velocity.magnitude*Time.fixedDeltaTime;
				position += velocity * Time.fixedDeltaTime;
				velocity += Physics2D.gravity*Time.fixedDeltaTime;

				m_LineRenderer.SetPosition(vertices, position);
				vertices++;
			}

			if (hit.transform != null)
			{
				m_LineRenderer.SetPosition(vertices, hit.point);
				vertices++;
			}

			m_LineRenderer.material.mainTextureScale = new Vector2(m_DistanceScale*distance, 1f);
			m_LineRenderer.SetVertexCount(vertices);
		}


		public Projectile ThrowProjectile(float baseSpeed, float value)
		{
			Projectile projectile = Instantiate(m_ProjectilePrefab);

			Vector2 projectileSpeed = transform.right*GetSpeed(value);
			Vector2 runSpeed = Vector2.right*baseSpeed;

			projectile.Initialize(transform.position, projectileSpeed+ runSpeed);

			return projectile;
		}

		public void EmptyPreviewPath()
		{
			m_LineRenderer.SetVertexCount(0);
		}
	}
}
