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

[System.Serializable]
public enum StepType {
    Left,
    Right
}

public class CameraBobber : MonoBehaviour {
    public Options Options;
    public Transform CameraTransform;
    public AnimationCurve HeadBobCurve = AnimationCurve.Constant(0, 1, 0);
    public float StepDuration;
    public float BobMagnitude;
    public bool Moving = false;
    public bool InAir = false;
    public AudioSource FootstepSource;
    // TODO: Vary by ground material
    public AudioClip[] LandingFootstepClips;
    public AudioClip[] RightFootstepClips;
    public AudioClip[] LeftFootstepClips;

    [Header("Runtime values")]
    public StepType LastStep;

    private float StepTime = 0;
    private bool WasMoving = false;
    private bool WasInAir = false;
    private Vector3 BasePosition;

    private void Start() {
        BasePosition = CameraTransform.localPosition;
    }

    private void Update() {
        if (Moving) {
            StepTime += Time.deltaTime;
            if (StepTime >= StepDuration) {
                StepTime -= StepDuration;
                if (!InAir) {
                    AlternateStep();
                    PlayStepSound(GetClips(LastStep), 1f);
                }
            }
        } else {
            StepTime = 0;
        }

        Vector3 TargetPosition = BasePosition;
        if (Options.CameraBobbing) {
            if (InAir) {
                TargetPosition = BasePosition + Vector3.up * HeadBobCurve.Evaluate(0.5f) * BobMagnitude;
            } else {
                TargetPosition = BasePosition + Vector3.up * HeadBobCurve.Evaluate(StepTime / StepDuration) * BobMagnitude;
            }
        }
        CameraTransform.localPosition = Vector3.Lerp(CameraTransform.localPosition, TargetPosition, 10f * Time.deltaTime);

        if (Moving != WasMoving && !InAir) {
            AlternateStep();
            PlayStepSound(GetClips(LastStep), 0.7f);
        } else if (WasInAir != InAir) {
            AlternateStep();
            PlayStepSound(LandingFootstepClips, 1f);
        }

        WasMoving = Moving;
        WasInAir = InAir;
    }

    private void AlternateStep() {
        LastStep = LastStep == StepType.Left ? StepType.Right : StepType.Left;
    }

    private AudioClip[] GetClips(StepType stepType) {
        switch (stepType) {
            default:
            case StepType.Left:
                return LeftFootstepClips;
            case StepType.Right:
                return RightFootstepClips;
        }
    }

    private void PlayStepSound(AudioClip[] clips, float volumeModifier) {
        if (clips.Length > 0) {
            FootstepSource.PlayOneShot(clips[Random.Range(0, clips.Length)], volumeModifier);
        }
    }
}
