using UnityEngine;
using System.Collections.Generic;

public class ObjectOcclusion : MonoBehaviour
{
    public float playerLightAngle = 45f;
    public float playerLightDistance = 50f;
    public Transform playerTransform;

    private List<Light> m_lightList;

    public static ObjectOcclusion Instance
    {
        get; private set;
    }

    private List<ObjectOcclusionOcludee> m_ocludeeList;

    private void Awake()
    {
        if (Instance == null)
        {
            Instance = this;
        }
        else
        {
            Debug.LogError("Stop touching me; t: " + Time.time);
        }

        m_ocludeeList = new List<ObjectOcclusionOcludee>();
        m_lightList = new List<Light>();
    }

    private void Update()
    {
        if(playerTransform == null)
        {
            return;
        }

        //HideOcludedObjects();

        CalculateVisibleLights();
    }

    private void HideOcludedObjects()
    {
        for (int i = 0; i < m_ocludeeList.Count; i++)
        {
            if (m_ocludeeList[i].inFixedLight)
            {
                continue;
            }

            if (Vector3.Distance(m_ocludeeList[i].transform.position, playerTransform.position) < playerLightDistance)
            {
                Vector3 targetDir = m_ocludeeList[i].transform.position - playerTransform.position;
                float angle = Vector3.Angle(targetDir, playerTransform.forward);

                if (angle < playerLightAngle)
                {
                    m_ocludeeList[i].SetVisible(true);
                    //m_ocludeeList.Sort(oc);
                }
                else
                {
                    m_ocludeeList[i].SetVisible(false);
                }
            }
            else
            {
                m_ocludeeList[i].SetVisible(false);
            }
        }
    }

    private void CalculateVisibleLights()
    {
        for (int i = 0; i < m_lightList.Count; i++)
        {
            if(Vector3.Distance(m_lightList[i].transform.position, playerTransform.position) > m_lightList[i].range * 2f)
            {
                m_lightList[i].gameObject.SetActive(false);
            }
            else
            {
                m_lightList[i].gameObject.SetActive(true);
            }
        }
    }

    public void AddLight(Light l)
    {
        m_lightList.Add(l);
        var lr = l.range;

        for (int i = 0; i < m_ocludeeList.Count; i++)
        {
            if (i >= m_lightList.Count || m_lightList[i] == null) break;

            if (Vector3.Distance(l.transform.position, m_ocludeeList[i].transform.position) < lr)
            {
                m_ocludeeList[i].SetVisible(true);
                m_ocludeeList[i].inFixedLight = true;
            }
        }
    }

    public void AddOcludee(ObjectOcclusionOcludee o)
    {
        m_ocludeeList.Add(o);
        //m_ocludeeList.Sort(oc);

        for (int i = 0; i < m_lightList.Count; i++)
        {
            if (i >= m_lightList.Count || m_lightList[i] == null) break;

            var lr = m_lightList[i].range;

            if (Vector3.Distance(m_lightList[i].transform.position, o.transform.position) < lr)
            {
                o.SetVisible(true);
                o.inFixedLight = true;
            }
        }
    }

    public void RemoveOccludee(ObjectOcclusionOcludee o)
    {
        m_ocludeeList.Remove(o);
    }
}
