using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using System.Collections.Generic;

namespace MonoGame.FourEngine.Resources
{
    public class Font : Sprite
    {
        public string Alphabet { get; protected set; }
        public Dictionary<int, string> WidthMap { get; protected set; }

        private Dictionary<char, int> _width;
        private Dictionary<char, Point> _positions;

        public Font(FontDefinition def) : base(def)
        {
            Alphabet = def.Alphabet;
            WidthMap = def.WidthMap; 

            _width = new Dictionary<char, int>();
            foreach (var mapping in WidthMap)
                foreach (var c in mapping.Value)
                    _width[c] = mapping.Key;

            var col = 0;
            var row = 0;
            _positions = new Dictionary<char, Point>();
            var columns = Texture.Width / Size.X;
            foreach (var c in Alphabet)
            {
                _positions.Add(c, new Point(col, row));
                col++;
                if (col == columns)
                {
                    col = 0;
                    row++;
                }
            }
        }

        public int MeasureText(string text)
        {
            if (string.IsNullOrWhiteSpace(text))
                return 0;
            var size = 0;
            foreach (var c in text.Replace("\r", string.Empty))
            {
                if (c == ' ')
                {
                    size += _width['_'];
                    continue;
                }

                // IMPORTANT: SKIP IF NOT PRESENT
                if (!_width.ContainsKey(c)) continue; 

                size += _width[c];
            }
            return size;
        }

        public void DrawText(SpriteBatch batch, string text, Point position, Color color)
        {
            if (string.IsNullOrWhiteSpace(text))
                return;
            var offset = Point.Zero;
            // TODO: fix
            // Fix what? Is ok now? I don't know...
            foreach (var c in text)
            {
                if (c == '\r') continue;
                if (c == '\n')
                {
                    offset += new Point(-offset.X, Size.Y);
                    continue;
                }
                if (c == ' ')
                {
                    offset += new Point(_width['_'], 0);
                    continue;
                }

                // IMPORTANT: SKIP IF NOT PRESENT
                if (!_width.ContainsKey(c)) continue;

                var pos = _positions[c];

                var frame = this[pos];
                frame.Draw(batch, position + offset, color);

                offset += new Point(_width[c], 0);
            }
        }
    }

    public class FontDefinition : SpriteDefinition
    {
        public string Alphabet { get; set; }
        public Dictionary<int, string> WidthMap { get; set; }
    }
}
