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


public abstract class NoteObject : MonoBehaviour
{
    public static Action<JudgeResult> OnNoteHit;
    protected float remainedTime;

    public Vector3 startPoint { get { return endPoint + new Vector3(0, 0, 50); } }
    public Vector3 endPoint;

	public float maxRemainedTime = 5;
	public float perfectZ = 10;

    public AudioClip[] hitSfx;

    protected virtual void OnDestroy()
    {
        
    }

    public void Awake()
    {
        remainedTime = maxRemainedTime;
    }

    public virtual void NoteHit(JudgeResult judge)
    {
        AudioClip hitClip = null;
        // play hit sound
        if (judge.type == JudgeType.Perfect)
            hitClip = hitSfx[0];
        if (judge.type == JudgeType.Hit)
            hitClip = hitSfx[1];

        if (hitClip)
        {
            AudioSource.PlayClipAtPoint(hitClip, Vector3.zero);
        }

        GameObject hitEffect = null;
        // hit effect

        if (judge.type == JudgeType.Perfect)
            hitEffect = PlayEngine.inst.hitEffectPrefabs[0];
        if (judge.type == JudgeType.Hit)
            hitEffect = PlayEngine.inst.hitEffectPrefabs[1];
        if (judge.type == JudgeType.Miss)
            hitEffect = PlayEngine.inst.hitEffectPrefabs[2];
        OnNoteHit?.Invoke(judge);

        if (hitEffect && judge.type != JudgeType.Ignore)
        {
            // show explosion effect
            Instantiate(hitEffect, transform.position, Quaternion.identity);

            // TODO: temporary implementation
            // make note invisible
            var meshRenderer = gameObject.GetComponent<MeshRenderer>();
            var trailRenderer = gameObject.GetComponent<TrailRenderer>();
            if (meshRenderer) meshRenderer.enabled = false;
            if (trailRenderer) trailRenderer.enabled = false;
        }
    }

    public virtual void SetPosition(float remainedTime)
    {
        float z = 250 * remainedTime;
        float t = Mathf.Pow(1 - z / 250, 3);
        transform.position = new Vector3(t * endPoint.x, t * endPoint.y, endPoint.z + z);
    }

    public abstract bool IsHit(Ray ray);
}
