using UnityEngine;
using System.Collections;

public class Shaker : MonoBehaviour 
{
    public bool m_triggerDebugShake;

	public bool m_rotationZ = true;
	public bool m_scale = false;
    public Vector3 m_moveAmplitude;

    public float m_amplitude = 10.0f;
	public float m_duration = 1.0f;
	public GFCurve m_curve = GFCurve.WaveOut4;
	private float m_time = 0.0f;

	private Transform m_target;
    private Vector3 m_originalPos;
    private Quaternion m_originalRotation;
	private Vector3 m_originalScale;

    public bool IsShaking()
	{
		return m_time > 0.0f;
	}

    public void StopShake()
    {
        if (m_time > 0.0f)
        {
            m_time = 0.0f;
            var target = (m_target != null) ? m_target : transform;
            target.localPosition = m_originalPos;
            target.localRotation = m_originalRotation;
            target.localScale = m_originalScale;
        }
    }

    public void Shake (Transform target = null) 
	{
        //@HM reshake or deny
        if (m_time > 0.0f)
            StopShake();
            //return;

		m_time = 1.0f;
		m_target = (target != null) ? target : transform;

        // keep previous originals if didn't finished
        m_originalPos = m_target.localPosition;
        m_originalRotation = m_target.localRotation;
        m_originalScale = m_target.localScale;
	}

	void Update () 
	{
        if (m_triggerDebugShake)
        {
            m_triggerDebugShake = false;
            Shake();
        }

        Transform tran = m_target;

		if(m_time > 0.0f)
		{
            Vector3 pos = Vector3.zero;
            Vector3 rot = Vector3.zero;
			float scale = 1.0f;
			m_time -= Time.deltaTime / m_duration;
			if(m_time <= 0.0f)
			{
				m_time = 0.0f;
                m_target = null;
            }
			else
			{
				float s = GFMath.CurvedDistribution(1.0f - m_time, m_curve);
                float s2 = GFMath.CurvedDistribution(1.0f - m_time * 1.7f, m_curve);
                pos = m_moveAmplitude * s2;
				rot.z = s * m_amplitude;
				scale = 1.0f + s * m_amplitude;
			}

            if (m_moveAmplitude != Vector3.zero)
                tran.localPosition = m_originalPos + pos;
            if (m_rotationZ)
				tran.localRotation = Quaternion.Euler(rot) * m_originalRotation;
			if(m_scale)
				tran.localScale = m_originalScale * scale;
		}
		else
		{
			m_target = null;
		}
	}
}
