﻿using UnityEngine;

namespace AC.CombatExample
{

	public abstract class CombatCharacter : MonoBehaviour
	{

		// This is a base class for "combat" characters, i.e. the Player and enemies, who can attack, take damage, and die

		#region Variables

		[SerializeField] protected Variables variables = null;
		[SerializeField] private string healthVariableName = "Health";
		private GVar healthVariable;

		[SerializeField] private string maxHealthVariableName = "MaxHealth";
		private GVar maxHealthVariable;

		[SerializeField] protected AudioClip takeDamageSound = null;
		[SerializeField] protected AudioClip dieSound = null;
		private float attackTimer;
		protected const float animCrossfadeTime = 0.15f;

		protected float originalWalkSpeed;
		protected float originalRunSpeed;
		protected float originalTurnSpeed;

		#endregion


		#region UnityStandards

		private void LateUpdate ()
		{
			if (attackTimer > 0f) attackTimer -= Time.deltaTime;
		}

		#endregion


		#region PublicFunctions

		public void TakeDamage (int damage)
		{
			// Reduce health, and react (die / animate) as necessary

			if (Health> 0)
			{
				Health -= damage;

				if (Health <= 0)
				{
					OnDie ();
				}
				else if (damage > 0)
				{
					OnTakeDamage ();
				}
				else if (Health > MaxHealth)
				{
					Health = MaxHealth;
				}
			}
		}


		public bool IsDead ()
		{
			return Health <= 0;
		}

		#endregion


		#region ProtectedFunctions

		protected void SetAttackDelay (float delay)
		{
			// Prevents the character from attacking for a set time
			if (delay < 0f) return;
			attackTimer = delay;
		}


		protected bool CanAttack ()
		{
			return (attackTimer <= 0f);
		}

		protected abstract void OnDie ();

		protected abstract void OnTakeDamage ();

		protected abstract void Attack ();

		#endregion


		#region GetSet

		protected int Health
		{
			get
			{
				if (healthVariable == null) healthVariable = variables.GetVariable (healthVariableName);
				return healthVariable.IntegerValue;
			}
			set
			{
				if (healthVariable == null) healthVariable = variables.GetVariable (healthVariableName);
				healthVariable.IntegerValue = value;
			}
		}


		protected int MaxHealth
		{
			get
			{
				if (maxHealthVariable == null) maxHealthVariable = variables.GetVariable (maxHealthVariableName);
				return maxHealthVariable.IntegerValue;
			}
			set
			{
				if (maxHealthVariable == null) maxHealthVariable = variables.GetVariable (maxHealthVariableName);
				maxHealthVariable.IntegerValue = value;
			}
		}

		#endregion

	}

}