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

[RequireComponent(typeof(Rigidbody))]
public class CarController : MonoBehaviour
{
    [System.Serializable]
    public class Tire
    {
        public WheelCollider collider;
        public Transform graphics;

        public void Update()
        {
            Vector3 pos;
            Quaternion rot;
            collider.GetWorldPose(out pos, out rot);
            graphics.position = pos;
            graphics.rotation = rot;
        }
    }

    public enum DriveMode { FWD, RWD, AWD }

    [Header("Tires")]
    public Tire FR;
    public Tire FL;
    public Tire BR;
    public Tire BL;

    [Header("Handling")]
    public float steeringMaxAngle = 25;
    public DriveMode driveMode;
    public float driveTorque = 500;
    public float brakeTorque = 1500;

    List<Tire> tires = new List<Tire>();
    Rigidbody rb;
    float accelerator = 0;
    float steeringWheel = 0;
    bool brake = false;

    void Start()
    {
        //!!!!COMMENT THIS OUT!!!!  I tend to set Time.timeScale to 2 for anything meant to feel "Arcade-y" instead of realistic.
        Time.timeScale = 2;

        rb = GetComponent<Rigidbody>();

        //make a useful list
        tires.Add(FR);
        tires.Add(FL);
        tires.Add(BR);
        tires.Add(BL);
    }

    private void Update()
    {
        steeringWheel = Input.GetAxis("Horizontal");
        //generally inverted
        accelerator = -Input.GetAxis("Vertical");

        brake = Input.GetButton("Jump");

        //update the visuals of each tire (steering angle, rotation, so on)
        foreach (var t in tires)
        {
            t.Update();
        }
    }

    void FixedUpdate()
    {
        //apply steering
        FL.collider.steerAngle = steeringWheel * steeringMaxAngle;
        FR.collider.steerAngle = steeringWheel * steeringMaxAngle;

        //apply drive torque based on drive mode
        switch (driveMode)
        {
            case DriveMode.FWD:
                FL.collider.motorTorque = accelerator * driveTorque;
                FR.collider.motorTorque = accelerator * driveTorque;
                break;
            case DriveMode.RWD:
                BL.collider.motorTorque = accelerator * driveTorque;
                BR.collider.motorTorque = accelerator * driveTorque;
                break;
            case DriveMode.AWD:
                foreach(Tire t in tires)
                    t.collider.motorTorque = accelerator * driveTorque;
                break;
        }

        //apply brake torque
        foreach (var t in tires)
        {
            t.collider.brakeTorque = brake ? brakeTorque : 0;
        }
    }


}
