using System.Collections.Generic;
using UnityEngine;
namespace XenseAR
{

    [RequireComponent(typeof(Renderer))]
    public class BillBoardSpriteRendererController : MonoBehaviour
    {
        [SerializeField] GameObject parent;
        [SerializeField] List<SpriteRenderer> spriteRenders = new List<SpriteRenderer>();
        [SerializeField] List<MeshRenderer> meshRenders = new List<MeshRenderer>();

        [Space]
        [SerializeField] bool lockXZAxis = true;
        [SerializeField] bool gradient = false;
        [SerializeField, Min(0f)] float HideDistance = 5f;
        [SerializeField, Min(0f)] float viewDistance = 15f;
        //[Min(0f)]
        //[SerializeField] float viewDistance = 10f;

        bool isShowing = true;

        private void Start()
        {
            foreach (MeshRenderer render in meshRenders)
            {
                render.material = new Material(render.material);
            }
        }

        // Update is called once per frame
        void Update()
        {
            if (lockXZAxis)
            {
                parent.transform.rotation = Quaternion.Euler(0f, Camera.main.transform.rotation.eulerAngles.y, 0f);
            }
            else
            {
                parent.transform.rotation = Camera.main.transform.rotation;
            }

            float distance = Vector3.Distance(Camera.main.transform.position, parent.transform.position);

            if (Application.isEditor)
            {
                distance = HideDistance / 2;
            }

            if (viewDistance == 0f)
            {
                if (!isShowing) Show();
                if (distance >= HideDistance) SetGradient(1f);
                else SetGradient(0f);
            }
            if (viewDistance != 0f)
            {
                if (distance < HideDistance) SetGradient(0f);
                else
                {
                    if (distance > viewDistance && isShowing)
                    {
                        Hide();
                    }
                    if (distance <= viewDistance)
                    {
                        if (!isShowing) Show();
                        if (gradient) SetGradient((viewDistance - distance) / (viewDistance - HideDistance));
                        else SetGradient(1f);
                    }
                }
            }
        }

        private void OnBecameVisible()
        {
            enabled = true;
        }

        private void OnBecameInvisible()
        {
            enabled = false;
        }

        void Show()
        {
            foreach (SpriteRenderer render in spriteRenders)
            {
                render.enabled = true;
            }
            foreach (MeshRenderer render in meshRenders)
            {
                render.enabled = true;
            }
            isShowing = true;
        }

        void Hide()
        {
            foreach (SpriteRenderer render in spriteRenders)
            {
                render.enabled = false;
            }
            foreach (MeshRenderer render in meshRenders)
            {
                render.enabled = false;
            }
            isShowing = false;
        }

        void SetGradient(float percent)
        {
            foreach (SpriteRenderer render in spriteRenders)
            {
                render.color = new Color(render.color.r, render.color.g, render.color.b, percent);
            }
            foreach (MeshRenderer render in meshRenders)
            {
                render.material.color = new Color(render.material.color.r, render.material.color.g, render.material.color.b, percent);
            }
        }
    }
}
