using Cryville.EEW.Core.Map;
using System.Collections.Generic;
using System.Drawing;
using UnityEngine;
using Color = UnityEngine.Color;

namespace Cryville.EEW.Unity.Map.Element {
	class MultiPolygonElement : MapElement {
		[SerializeField] PolygonRenderer m_polygonRendererPrefab;
		readonly List<PolygonRenderer> _polygonRenderers = new();
		[SerializeField] LineRenderer m_lineRendererPrefab;
		readonly List<LineRenderer> _lineRenderers = new();

		RectangleF? m_AABB;
		public override RectangleF? AABB => m_AABB;

		[SerializeField]
		Color m_fillColor = Color.white;
		public Color FillColor {
			get => m_fillColor;
			set {
				if (m_fillColor == value) return;
				m_fillColor = value;
				foreach (var r in _polygonRenderers) {
					r.Color = value;
				}
			}
		}
		[SerializeField]
		Color m_borderColor = Color.white;
		public Color BorderColor {
			get => m_borderColor;
			set {
				if (m_borderColor == value) return;
				m_borderColor = value;
				foreach (var r in _lineRenderers) {
					r.Color = value;
				}
			}
		}
		[SerializeField]
		float m_borderWidth = 1;
		public float BorderWidth {
			get => m_borderWidth;
			set {
				if (m_borderWidth == value) return;
				m_borderWidth = value;
				foreach (var r in _lineRenderers) {
					r.Width = value * ComputedScale / 512;
				}
			}
		}

		protected override void OnSetScale() {
			foreach (var r in _lineRenderers) {
				r.Width = m_borderWidth * ComputedScale / 512;
			}
		}
		protected override void OnSetMaterial(Material material) {
			foreach (var r in _lineRenderers) {
				r.Material = Material;
				r.Color = m_borderColor;
			}
			foreach (var r in _polygonRenderers) {
				r.Material = Material;
				r.Color = m_fillColor;
			}
		}

		public void SetPolygons(IEnumerable<IEnumerable<IEnumerable<PointF>>> polygons, ref int order) {
			foreach (var r in _polygonRenderers) {
				Destroy(r.gameObject);
			}
			foreach (var r in _lineRenderers) {
				Destroy(r.gameObject);
			}
			_polygonRenderers.Clear();
			_lineRenderers.Clear();
			m_AABB = null;
			foreach (var polygon in polygons) {
				CreatePolygon(polygon, ref order);
			}
		}

		void CreatePolygon(IEnumerable<IEnumerable<PointF>> polygon, ref int order) {
			var polygonRenderer = Instantiate(m_polygonRendererPrefab);
			polygonRenderer.SetPolygon(polygon);
			polygonRenderer.Material = Material;
			polygonRenderer.Color = m_fillColor;
			polygonRenderer.transform.SetParent(transform, false);
			polygonRenderer.transform.localPosition = new(0, 0, OrderToZ(ref order));
			_polygonRenderers.Add(polygonRenderer);

			foreach (var loop in polygon) {
				_lineRenderers.Add(LineRenderer.Create(loop, OrderToZ(ref order), m_lineRendererPrefab, Material, m_borderColor, m_borderWidth, this, out var aabb));
				if (aabb is RectangleF b) {
					m_AABB = m_AABB is RectangleF a ? MapTileUtils.UnionTileAABBs(a, b) : b;
				}
			}
		}
	}
}
