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

namespace Machete {
	public class Teacher : MonoBehaviour {

    [SerializeField]
    List<Vector3> InitialWaypoints;
    [SerializeField]
    List<Vector3> LoopWaypoints;
    [SerializeField]
    float speed = 5f;
    [SerializeField]
    float stopRadius = 0.1f;

    delegate void UpdateHandler();
    UpdateHandler updateHandler;

    Vector3 target;
    int currentWaypoint = -1;

		// Use this for initialization
		void Start () {
      transform.position = InitialWaypoints[0];
      InitialWaypoints.RemoveAt(0);
      updateHandler = InitialWaypointsHandler;
		}

		// Update is called once per frame
		void Update () {
      updateHandler();
		}

    void InitialWaypointsHandler() {
      if (InitialWaypoints.Count == 0) {
        updateHandler = LoopWaypointsHandler;
        return;
      }

      // Get new target.
      target = InitialWaypoints[0];
      InitialWaypoints.RemoveAt(0);
      updateHandler = LookAtHandler;
    }

    void LoopWaypointsHandler() {
      if (InitialWaypoints.Count == 0) {
        updateHandler = NothingHandler;
      }

      // Get new target.
      currentWaypoint++;
      currentWaypoint = currentWaypoint % LoopWaypoints.Count;
      target = LoopWaypoints[currentWaypoint];
      updateHandler = LookAtHandler;
    }

    void LookAtHandler() {
      transform.forward = target - transform.position;
      updateHandler = MoveHandler;
    }

    void MoveHandler() {
      // Calculate next position and distance.
      transform.position = transform.position + transform.forward * speed * Time.deltaTime;
      float distance = (target - transform.position).magnitude;

      // Check if there.
      if (distance < stopRadius) {
        transform.position = target;
        if (InitialWaypoints.Count > 0) {
          updateHandler = InitialWaypointsHandler;
        } else {
          updateHandler = LoopWaypointsHandler;
        }
      }
    }

    void NothingHandler() {

    }

    private void OnDrawGizmos() {
      Gizmos.color = Color.red;
      foreach(Vector3 point in InitialWaypoints) {
        Gizmos.DrawWireSphere(point + Vector3.up * 0.5f, 0.2f);
      }
      foreach(Vector3 point in LoopWaypoints) {
        Gizmos.DrawWireSphere(point + Vector3.up * 0.5f, 0.2f);
      }
    }

    private void OnTriggerEnter(Collider other) {
      Desk desk = other.GetComponent<Desk>();
      desk.InCheck = true;
    }

    private void OnTriggerExit(Collider other) {
      Desk desk = other.GetComponent<Desk>();
      desk.InCheck = false;
    }
	}
}
