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

[RequireComponent(typeof(Rigidbody))]
[RequireComponent(typeof(WallController))]
public class TracerControllerV2 : MonoBehaviour {

    private struct Turn {
        public Vector3 turnStartPositionBack;
        public Vector3 turnStartPositionFront;
        public float distanceForTurn;
        public float rotation;
    }

    // wenn Sie diese Checkbox aktivieren, pausiert der
    // Editor nach jeder Drehung, was zum Debuggen praktisch ist
    public bool pauseOnTurns = false;

    public float baseVelocity = 5F;

    public Rigidbody snakeHead; 
    public Transform pointFront;
    public Transform pointBack;
    public Transform rotateBody;

    private Rigidbody myRigidbody = null;
    private WallController wallController = null;
    private Queue<Turn> turns = new Queue<Turn>();

    void Awake() {
        myRigidbody = GetComponent<Rigidbody>();
        wallController = GetComponent<WallController>();
    }

    void Start() {
        myRigidbody.velocity = transform.forward * baseVelocity;
        wallController.TracerTurned();

        snakeHead.transform.position = pointFront.position;
        snakeHead.transform.rotation = pointFront.rotation;
        snakeHead.velocity = transform.forward * baseVelocity;
    }

    void Update() {
        CheckForTurn();
        if (turns.Count > 0) {
            HandleTurn();
        }
    }

    private void HandleTurn() {
        Turn currentTurn = turns.Peek();
        float distanceCovered = Vector3.Distance(
              currentTurn.turnStartPositionBack,
              pointBack.transform.position);

        rotateBody.LookAt(snakeHead.transform);

        if (distanceCovered >= currentTurn.distanceForTurn) {
            rotateBody.localRotation = Quaternion.identity;

            transform.Rotate(0F, currentTurn.rotation, 0F);
            transform.position = currentTurn.turnStartPositionFront;
            myRigidbody.velocity = transform.forward * baseVelocity;

            wallController.TracerTurned();

            turns.Dequeue();

            if (turns.Count == 0) {
                snakeHead.transform.position = pointFront.position;
            } else {
                rotateBody.LookAt(snakeHead.transform);
            }

        }
    }


    private void CheckForTurn() {
        float? testRotation = null;
        if (Input.GetKeyDown(KeyCode.LeftArrow)) {
            testRotation = -90F;
        } else if (Input.GetKeyDown(KeyCode.RightArrow)) {
            testRotation = 90F;
        }

        if (testRotation != null) {
            Turn nextTurn = new Turn();
            nextTurn.rotation = testRotation.Value;
            nextTurn.turnStartPositionFront
              = snakeHead.transform.position;

            if (turns.Count == 0) {
                nextTurn.turnStartPositionBack = pointBack.transform.position;
            } else {
                Turn[] turnsArray = turns.ToArray();
                Turn previousTurn = turnsArray[turns.Count - 1];
                nextTurn.turnStartPositionBack
                  = previousTurn.turnStartPositionFront;
            }

            nextTurn.distanceForTurn = Vector3.Distance(
                nextTurn.turnStartPositionBack,
                nextTurn.turnStartPositionFront);

            turns.Enqueue(nextTurn);

            snakeHead.transform.Rotate(0F, nextTurn.rotation, 0F);
            snakeHead.velocity
              = snakeHead.transform.forward * baseVelocity;
        }
    }

}
