using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Mox.Shared.Math;
using Mox.Shared.Serializer;

namespace Mox.Shared.Renderer
{
	public class Atlas
	{
		public class Brush
		{
			public string Name;
			public int Width;
			public int Height;
			public int X;
			public int Y;
			public int Id;
		}

		public class BrushSheet : Serializable
		{
			public override void Serialize(Serializer.Serializer _serializer)
			{
				if (_serializer.StartChild(nameof(Brushes)))
				{
					if (_serializer.IsLoading)
					{
						Brushes = new List<Brush>();

						while (_serializer.StartChild(nameof(Brush)))
						{
							var brush = new Brush();
							_serializer.Serialize(ref brush.Name, nameof(Brush.Name), null);
							_serializer.Serialize(ref brush.Width, nameof(Brush.Width), 0);
							_serializer.Serialize(ref brush.Height, nameof(Brush.Height), 0);
							_serializer.Serialize(ref brush.X, nameof(Brush.X), 0);
							_serializer.Serialize(ref brush.Y, nameof(Brush.Y), 0);
							_serializer.Serialize(ref brush.Id, nameof(Brush.Id), 0);
							_serializer.EndChild();
							Brushes.Add(brush);
						}
					}
					_serializer.EndChild();
				}
			}

			public List<Brush> Brushes;
		}

		private Atlas(Dictionary<string, SubImage> _subImages)
		{
			SubImages = _subImages;
		}

		public static async Task<Atlas> Create(string _sAtlasName)
		{
			var sAtlasPath = _sAtlasName + ".json";
			var brushSheet = new BrushSheet();
			brushSheet.Serialize(new XmlSerializerLoad(await IOHelper.GetText(sAtlasPath)));
			var imageIds = brushSheet.Brushes.Select(b => b.Id).Distinct();
			var images = new Dictionary<int, ImageBase>();

			foreach (var id in imageIds)
			{
				var sImagePath = _sAtlasName + id + ".png";
				var image = await RendererBase.Instance.CreateImage(sImagePath);
				images[id] = image;
			}

			var subImages = new Dictionary<string, SubImage>();
			foreach (var brush in brushSheet.Brushes)
			{
				var image = images[brush.Id];
				subImages[brush.Name] = new SubImage(image) { Rect = new Rect(brush.X, brush.Y, brush.Width, brush.Height) };
			}

			return new Atlas(subImages);
		}

		public readonly Dictionary<string, SubImage> SubImages;
	}
}
