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

namespace MonoGame.FourEngine.Tiled
{
    public class TiledObject : ComponentWrapper
    {
        public string Name { get; set; }
        public string Type { get; set; }

        // TODO: Other types
        public Dictionary<string, int> IntProperties { get; set; } = new Dictionary<string, int>();
        public Dictionary<string, string> StringProperties { get; set; } = new Dictionary<string, string>();

        protected virtual void ParseImpl(XElement xElement)
        {
            Name = xElement.AttributeOrEmpty("name").Value;
            Type = xElement.AttributeOrEmpty("type").Value;
            Position = new Point(
                    (int)float.Parse(xElement.Attribute("x").Value, CultureInfo.InvariantCulture),
                    (int)float.Parse(xElement.Attribute("y").Value, CultureInfo.InvariantCulture));
            Width = int.Parse(xElement.AttributeOrZero("width").Value, CultureInfo.InvariantCulture);
            Height = int.Parse(xElement.AttributeOrZero("height").Value, CultureInfo.InvariantCulture);

            var properties = xElement.ElementOrNull("properties")?.Descendants("property").ToList();
            if (properties != null)
            {
                var intProperties = properties.Where(x => x.AttributeOrEmpty("type").Value == "int").ToList();
                if (intProperties.Any())
                    IntProperties = intProperties
                        .ToDictionary(
                            x => x.AttributeOrEmpty("name").Value,
                            x => int.Parse(x.AttributeOrZero("value").Value));

                // Don't ask me why is type == string.Empty for strings...
                var stringProperties = properties.Where(x => x.AttributeOrEmpty("type").Value == string.Empty).ToList();
                if (stringProperties.Any())
                    StringProperties = stringProperties
                        .ToDictionary(
                            x => x.AttributeOrEmpty("name").Value,
                            x => x.AttributeOrZero("value").Value);
            }
        }

        public static TiledObject Parse(XElement xElement)
        {
            TiledObject @object;
            if (xElement.Descendants("polyline").FirstOrDefault() is XElement xPolyline)
            {
                @object = new TiledPolylineObject(xPolyline);
            }
            else
            {
                @object = new TiledObject();
            }
            @object.ParseImpl(xElement);
            return @object;
        }
    }
}