/*
 * +================================================================================+
 *      __  ___  ______________  __  __  ______________   ____
 *     / / / / |/ /  _/_  __/\ \/ / / / / /_  __/  _/ /  / __/
 *    / /_/ /    // /  / /    \  / / /_/ / / / _/ // /___\ \
 *    \____/_/|_/___/ /_/     /_/  \____/ /_/ /___/____/___/
 *
 * +================================================================================+
 *
 *    "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 UnityEngine;
using Utils;

namespace Utils.Effects {

	/// <summary>
	/// Hand camera effect.
	/// </summary>
	public class HandCamera : Effect {

		[Header("Effect parameters")]
		[Tooltip("The amount of the effect. Result is also dependent on the given duration (this effect is infinite).")]
		/// <summary>
		/// The amount of the effect. Result is also dependent on the given duration (this effect is infinite).
		/// </summary>
		public float Amount = 1f;
		[Tooltip("The ease function.")]
		/// <summary>
		/// The ease function.
		/// </summary>
		public Ease.EaseFunctions EaseFunction;

		/// <summary>
		/// The local duration for hand shaking.
		/// </summary>
		private float localDuration;
		/// <summary>
		/// The local current time for hand shaking.
		/// </summary>
		private float localCurrentTime;
		/// <summary>
		/// The original position.
		/// </summary>
		private Vector3 originalPosition;
		/// <summary>
		/// The start position.
		/// </summary>
		private Vector3 startPosition;
		/// <summary>
		/// The target position.
		/// </summary>
		private Vector3 targetPosition;

		protected override void InitEffect() {
			infinite = true;

			localDuration = Random.Range(Duration / 2f, Duration);
			localCurrentTime = currentTime;

			// Get and calculate positions
			originalPosition = transform.localPosition;
			startPosition = originalPosition;
			targetPosition = originalPosition + Random.insideUnitSphere * Random.Range(0f, (Amount / 2f));
		}
		
		protected override void UpdateEffect() {
			// Increase local current time
			localCurrentTime += Time.deltaTime;

			// Hand shaking
			transform.localPosition = Ease.GetEase(EaseFunction, localCurrentTime / localDuration, startPosition, targetPosition);
			if (localCurrentTime / localDuration >= 1f) {
				localCurrentTime -= localDuration;
				localDuration = Random.Range(Duration / 2f, localDuration);
				startPosition = targetPosition;
				targetPosition = originalPosition + Random.insideUnitSphere * Random.Range(0f, (Amount / 2f));
			}

			// Breathing
			transform.localPosition = transform.localPosition + Vector3.up * (Amount / 2f) *  Mathf.Sin(currentTime * 2f / Duration);
		}
		
		protected override void CleanUpEffect() {
			// Reset position
			transform.localPosition = originalPosition;
		}
	}
}
