using Microsoft.Xna.Framework;
using MonoGame.FourEngine.Resources;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Xml.Linq;

namespace MonoGame.FourEngine.Tiled
{
    internal class Tileset
    {
        public int FirstGid { get; private set; }
        public Point TileSize { get; private set; }
        public int Spacing { get; private set; }
        public int Margin { get; private set; }
        public int TileCount { get; private set; }
        public int Columns { get; private set; }
        public string ImageSource { get; private set; }

        public bool ContainsIndex(int gid)
            => gid >= FirstGid
            && gid < FirstGid + TileCount;

        public TiledEntity CreateEntity(int x, int y, int frameindex, int tilesetGid, int layer)
        {
            var def = new SpriteDefinition
            {
                FileName = ImageSource,
                Size = TileSize,
                Spacing = new Point(Spacing),
                Margin = new Point(Margin)
            };
            frameindex -= tilesetGid;
            var entity = new TiledEntity(def);
            entity.SpriteComponent.Frame = new Point(frameindex % Columns, frameindex / Columns);
            entity.SpriteComponent.Layer = layer;
            return entity;
        }

        public static Tileset Parse(XElement xElement)
        {
            var xImage = xElement.Descendants("image").FirstOrDefault();
            return new Tileset
            {
                FirstGid = int.Parse(xElement.Attribute("firstgid").Value, CultureInfo.InvariantCulture),
                TileSize = new Point(
                      int.Parse(xElement.Attribute("tilewidth").Value, CultureInfo.InvariantCulture),
                      int.Parse(xElement.Attribute("tileheight").Value, CultureInfo.InvariantCulture)),
                Spacing = int.Parse(xElement.AttributeOrZero("spacing").Value, CultureInfo.InvariantCulture),
                Margin = int.Parse(xElement.AttributeOrZero("margin").Value, CultureInfo.InvariantCulture),
                TileCount = int.Parse(xElement.Attribute("tilecount").Value, CultureInfo.InvariantCulture),
                Columns = int.Parse(xElement.Attribute("columns").Value, CultureInfo.InvariantCulture),
                ImageSource = xImage.Attribute("source").Value.Split('/').Last()
            };
        }

        public static IEnumerable<Tileset> Parse(IEnumerable<XElement> xElements)
            => xElements.Select(x => Parse(x));
    }
}