/*
 * +================================================================================+
 *      __  ___  ______________  __  __  ______________   ____
 *     / / / / |/ /  _/_  __/\ \/ / / / / /_  __/  _/ /  / __/
 *    / /_/ /    // /  / /    \  / / /_/ / / / _/ // /___\ \
 *    \____/_/|_/___/ /_/     /_/  \____/ /_/ /___/____/___/
 *
 * +================================================================================+
 *
 *    "THE BEER-WARE LICENSE"
 *    -----------------------
 *
 *    As long as you retain this notice you can do whatever you want with this
 *    stuff. However it is expressly forbidden to sell or commercially distribute
 *    Unity Utils or parts of it apart from your games.
 *    If you meet any of the authors some day, and you think this stuff is
 *    worth it, you can buy them a beer in return.
 *
 *    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 *    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 *    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 *    AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 *    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 *    OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 *    THE SOFTWARE.
 *
 * +================================================================================+
 *
 *    Authors:
 *    David Krummenacher (dave@timbookedtwo.com)
 *
 */

using System.Collections.Generic;
using UnityEngine;
using Utils.Helpers;

namespace Utils.AnimatorController {

	/// <summary>
	/// Footstep behaviour that plays footsteps on given time steps.
	/// </summary>
	public class FootstepBehaviour : StateMachineBehaviour {

		[Tooltip("The time steps that indicate when to play the sound.\nThe values go from 0 (start of the animation) to 1 (end of the animation).")]
		/// <summary>
		/// The time steps that indicate when to play the sound.
		/// The values go from 0 (start of the animation) to 1 (end of the animation).
		/// </summary>
		public List<float> TimeSteps;
		[Tooltip("The footstep audio clips.")]
		/// <summary>
		/// The footstep audio clips.
		/// </summary>
		public List<AudioClip> FootstepAudioClips;
		[Tooltip("The particle prefabs.")]
		/// <summary>
		/// The particle prefabs.
		/// </summary>
		public List<GameObject> ParticlePrefabs;

		/// <summary>
		/// The current time step index.
		/// </summary>
		private int currentTimeStepIndex = 0;
		/// <summary>
		/// The next time step in seconds.
		/// </summary>
		private float nextTimeStep;

		override public void OnStateEnter(Animator animator, AnimatorStateInfo stateInfo, int layerIndex) {
			if (TimeSteps.Count <= 0) return;

			// Reset time step
			currentTimeStepIndex = 0;
			nextTimeStep = TimeSteps[currentTimeStepIndex];
		}

		override public void OnStateUpdate(Animator animator, AnimatorStateInfo stateInfo, int layerIndex) {
			if (TimeSteps.Count <= 0) return;

			// Play sound and place particles if necessairy
			if (stateInfo.normalizedTime >= nextTimeStep) {
				AudioObject.Create(FootstepAudioClips, animator.gameObject.transform).RandomizePitch().RandomizeVolume().Play();
				GameObjectHelper.Instantiate(ParticlePrefabs, animator.gameObject.transform);

				// Time handling
				currentTimeStepIndex++;
				nextTimeStep = 0f;

				if (currentTimeStepIndex >= TimeSteps.Count) {
					currentTimeStepIndex = 0;
					nextTimeStep += 1f;
				}

				nextTimeStep += TimeSteps[currentTimeStepIndex] + Mathf.Floor(stateInfo.normalizedTime);
			}
		}
	}
}
