//Created by Neodrop
//neodrop@unity3d.ru
using System.Collections.Generic;
using UnityEngine;
//#pragma warning disable

public class AI_Range : MonoBehaviour
{

    public bool showRings = true;
    public List<AI_RangeMarker> markersComponents = new List<AI_RangeMarker>();

    public void CreateMarker()
    {
        Transform m = new GameObject("RangeMarker", typeof(AI_RangeMarker)).transform;
        m.rotation = transform.rotation;
        m.position = transform.position;
        AI_RangeMarker a_m = m.GetComponent<AI_RangeMarker>();
        a_m.holder = this;
        int number = markersComponents.Count;
        switch (number)
        {
            case 0:
                a_m.color = Color.red;
                break;
            case 1:
                a_m.color = Color.yellow;
                break;
            case 2:
                a_m.color = Color.green;
                break;
            case 3:
                a_m.color = Color.blue;
                break;
            case 4:
                a_m.color = Color.cyan;
                break;
            case 5:
                a_m.color = Color.magenta;
                break;
            default:
                a_m.color = Color.gray;
                break;
        }
        a_m.zoneName = "Zone " + number;
        markersComponents.Add(a_m);
        m.Translate(Vector3.forward * (markersComponents.Count), transform);
        m.parent = transform;
    }

    public List<string> ObjectInZoneSimple(Transform target)
    {
        if (!target) return new List<string>();
        int count = markersComponents.Count;
        List<string> zones = new List<string>();
        for (int i = 0; i < count; i++)
        {
            AI_RangeMarker marker = markersComponents[i];
            marker.anchorTarget.LookAt(new Vector3(target.position.x, marker.anchorTarget.position.y, target.position.z));
            if (PointInZone(target.position, marker))
            {
                marker.color = Color.magenta;
                zones.Add(marker.zoneName);
            }
            else marker.color = marker.colorBack;
        }
        return zones;
    }

    public List<string> ObjectInZoneBoxed(Transform target)
    {
        if (!target) return new List<string>();
        int count = markersComponents.Count;
        List<string> zones = new List<string>();
        for (int i = 0; i < count; i++)
        {
            AI_RangeMarker marker = markersComponents[i];
            marker.anchorTarget.LookAt(new Vector3(target.position.x, marker.anchorTarget.position.y, target.position.z));
            if (BoxInZone(target, marker))
            {
                marker.color = Color.magenta;
                zones.Add(marker.zoneName);
            }
            else marker.color = marker.colorBack;
        }
        return zones;
    }

    bool BoxInZone(Transform target, AI_RangeMarker marker)
    {
        MeshFilter[] filters = target.gameObject.GetComponentsInChildren<MeshFilter>();
        int count = filters.Length;
        for (int i = 0; i < count; i++)
        {
            Bounds box = filters[i].mesh.bounds;
            if (PointInZone(target.TransformPoint(box.max), marker)) return true;
            if (PointInZone(target.TransformPoint(box.min), marker)) return true;
        }
        return false;
    }

    bool PointInZone(Vector3 point, AI_RangeMarker marker)
    {
        if (Vector3.Distance(marker.anchorTarget.position, point) > marker.runtimeDistance) return false;
        if (marker.angleView == 360f) return true;
        Transform conductor = new GameObject().transform;
        conductor.position = marker.anchorTarget.position;
        conductor.LookAt(marker.transform);

        marker.anchorTarget.parent = marker.anchorLeft.parent = marker.anchorRight.parent = conductor;
        if (marker.anchorTarget.localEulerAngles.y > marker.anchorLeft.localEulerAngles.y ||
            marker.anchorTarget.localEulerAngles.y < marker.anchorRight.localEulerAngles.y)
        {
            marker.anchorTarget.parent = marker.anchorLeft.parent = marker.anchorRight.parent = null;
            Destroy(conductor.gameObject);
            return true;
        }

        marker.anchorTarget.parent = marker.anchorLeft.parent = marker.anchorRight.parent = null;
        Destroy(conductor.gameObject);
        return false;
    }
}
