using MonoGame.FourEngine.Resources;
using System.Linq;
using System.Xml.Linq;
using System.Collections.Generic;
using System;

namespace MonoGame.FourEngine.Tiled
{
    public class Map
    {
        public MapOrientation Orientation { get; private set; }

        private List<Tileset> _tilesets;
        private List<LayerBase> _layers;

        public Map(MapDefinition def) : this(def.FileName)
        { }

        public Map(string fileName)
            => LoadMap(fileName);

        public IEnumerable<Entity> GetEntities(int mapLayer = 0)
        {
            for (var i = 0; i < _layers.Count; i++)
            {
                var layer = _layers[i];
                foreach (var entity in layer.GetEntities(_tilesets, i, Orientation))
                {
                    if (mapLayer != default)
                    {
                        foreach (var component in entity.Components)
                            component.Layer += mapLayer;
                    }
                    yield return entity;
                }
            }
        }

        private void LoadMap(string fileName)
        {
            var xdoc = ReadTiledFile(fileName);
            _tilesets = Tileset.Parse(xdoc.Descendants("tileset")).ToList();
            _layers = LayerBase.Parse(xdoc.Descendants("layer", "objectgroup")).ToList();
        }

        private XDocument ReadTiledFile(string fileName)
        {
            XDocument xdoc;
            using (var stream = ServiceLocator.ResourceLoader.GetStream(fileName))
                xdoc = XDocument.Load(stream);
            var xMap = xdoc.Element("map");
            if (Enum.TryParse<MapOrientation>(xMap.Attribute("orientation").Value, true, out var orientation))
                Orientation = orientation;
            return xdoc;
        }
    }

    public class MapDefinition : IResourceDefinition
    {
        public string FileName { get; set; }
    }

    public enum MapOrientation
    {
        Orthogonal, Isometric
    }
}