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

[ExecuteAlways]
public class ImmediateDrawControl : ImmediateModeShapeDrawer
{
	public Transform anchor;
	public Transform midJoint;
	public Transform smashBall;
	public Transform player;

	public List<PointHistory> trails;
	private PuckMove puck;

	private DoubleCenter doubleCenter;
	private BigAir bigAir;
	private LittleKing littleKing;
	private ProgressDisplay progressDisplay;
	private VictoryReward victoryReward;
	private TitleDisplay titleDisplay;

	private AntiFriction littleBooster;
	private AntiFriction bigBooster;

	public override void DrawShapes(Camera cam)
	{

		using (Draw.Command(cam))
		{
			Draw.LineGeometry = LineGeometry.Flat2D;
			Draw.ThicknessSpace = ThicknessSpace.Meters;
			Draw.Thickness = .1f;
			Draw.Matrix = transform.localToWorldMatrix;

			DrawPendulumHardware();
			DrawTrails();
			DrawPendulumColliders();
			DrawPlayerPuck();

			doubleCenter.ImmediateDraw();
			bigAir.ImmediateDraw();
			littleKing.ImmediateDraw();
			progressDisplay.ImmediateDraw();
			titleDisplay.ImmediateDraw();
			victoryReward.ImmediateDraw();
		}

	}

	private void DrawPlayerPuck()
	{
		Color color = (puck != null && puck.IsStunned()) ? Color.gray : Color.white;
		Draw.LineEndCaps = LineEndCap.Round;

		Vector3 palmOffset = 0.1f * Vector3.down + 0.01f * Vector3.right;
		Draw.Ring(player.position + palmOffset, radius: 0.425f, thickness: 0.135f, color);

		// Fingers, one by one, with great care...
		Vector3 p = player.position;
		Vector3 fingerOffset = 0.21f * Vector3.right;
		Vector3 fingerHeight = 0.2f * Vector3.up;

		Draw.Line(
			p + new Vector3(-0.22f, 0.29f),
			p + new Vector3(-0.22f, 0.46f),
			thickness: 0.19f, color
		);

		Draw.Line(
			p + new Vector3(-0.01f, 0.36f),
			p + new Vector3(-0.01f, 0.52f),
			thickness: 0.21f, color
		);

		Draw.Line(
			p + new Vector3(0.20f, 0.31f),
			p + new Vector3(0.20f, 0.49f),
			thickness: 0.18f, color
		);

		Draw.Line(
			p + new Vector3(0.375f, 0.15f),
			p + new Vector3(0.375f, 0.38f),
			thickness: 0.14f, color
		);

		//Thumb:
		Draw.Line(
			p + new Vector3(-0.400f, -0.300f),
			p + new Vector3(-0.550f, 0.0f),
			thickness: 0.19f, color
		);

		Vector3 fingerStart = player.position + 0.22f * Vector3.left + 0.06f * Vector3.down;
	}

	private void DrawPendulumColliders()
	{
		Color littleColor = Color.white;
		Color bigColor = Color.white;
		float boostedHue = 302f/360f;

		if (littleBooster.activated)
		{
			littleColor = Color.HSVToRGB(boostedHue, littleBooster.activationFactor, 1.0f);
		}

		if (bigBooster.activated)
		{
			bigColor = Color.HSVToRGB(boostedHue, bigBooster.activationFactor, 1.0f);
		}

		Draw.Ring(midJoint.position, 0.25f, littleColor);
		Draw.Ring(smashBall.position, 0.5f, bigColor);
	}

	private void DrawPendulumHardware()
	{
		Color darkGray = new Color(0.25f, 0.25f, 0.25f, 1.0f);
		Draw.LineEndCaps = LineEndCap.None;
		Draw.Line(anchor.position, midJoint.position, darkGray);
		Draw.Line(midJoint.position, smashBall.position, darkGray);
		Draw.Disc(anchor.position, 0.25f, darkGray);
	}

	private void DrawTrails()
	{
		foreach (PointHistory trail in trails)
		{
			DrawTrailAsPolyLine(trail);
		}
	}

	private static void DrawTrailAsPolyLine(PointHistory trail)
	{
		if (trail.points == null || trail.points.Count < 2)
			return;

		Color lightGray = new Color(0.6f, 0.6f, 0.6f, 1.0f);
		using (var polyLine = new PolylinePath())
		{
			for (int i = 0; i < trail.points.Count; i++)
			{
				float trailThickness = Mathf.Max(0.05f, ((float)(trail.depth - i)) / (float)trail.depth);

				PointData dat = trail.points[i];
				PolylinePoint polyPoint = new PolylinePoint(dat.position, dat.color, trailThickness);
				polyLine.AddPoint(polyPoint);
			}

			Draw.Polyline(polyLine, closed: false, thickness: .1f);
		}
	}

	private void Start()
	{
		puck = player.GetComponent<PuckMove>();
		doubleCenter = GetComponent<DoubleCenter>();
		bigAir = GetComponent<BigAir>();
		littleKing = GetComponent<LittleKing>();
		progressDisplay = GetComponent<ProgressDisplay>();
		titleDisplay = GetComponent<TitleDisplay>();
		victoryReward = GetComponent<VictoryReward>();

		littleBooster = midJoint.GetComponent<AntiFriction>();
		bigBooster = smashBall.GetComponent<AntiFriction>();
	}
}
