using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using RecrownedAthenaeum.Data;
using RecrownedAthenaeum.SpecialTypes;
using System.IO;

namespace RecrownedAthenaeum.ContentReaders
{
    class TextureAtlasDataReader : ContentTypeReader<TextureAtlas>
    {
        protected override TextureAtlas Read(ContentReader input, TextureAtlas existingInstance)
        {
            TextureAtlasData atlasData = ReadTextureAtlasData(input);
            Texture2D atlasTexture = input.ContentManager.Load<Texture2D>(atlasData.textureName);

            TextureAtlas atlas = new TextureAtlas(atlasTexture, GenerateAtlasRegionsFromData(atlasData, atlasTexture));

            return atlas;
        }

        public TextureAtlasData ReadTextureAtlasData(BinaryReader reader)
        {
            string textureName = reader.ReadString();
            TextureAtlasData.AtlasRegionData[] regions = new TextureAtlasData.AtlasRegionData[reader.ReadInt32()];
            for (int i = 0; i < regions.Length; i++)
            {
                regions[i] = new TextureAtlasData.AtlasRegionData();
                regions[i].name = reader.ReadString();
                regions[i].bounds = new Rectangle(reader.ReadInt32(), reader.ReadInt32(), reader.ReadInt32(), reader.ReadInt32());
                if (reader.ReadBoolean())
                {
                    regions[i].ninePatchData = new NinePatchData(null, reader.ReadInt32(), reader.ReadInt32(), reader.ReadInt32(), reader.ReadInt32());
                }
            }

            TextureAtlasData atlasData = new TextureAtlasData(textureName, regions);

            return atlasData;
        }

        /// <summary>
        /// Generates region given <see cref="TextureAtlasData"/>.
        /// </summary>
        /// <param name="textureAtlasData">The data to generate the regions from.</param>
        /// <param name="atlasTexture">The texture containing the atlas.</param>
        /// <returns>An array of regions.</returns>
        public TextureAtlas.Region[] GenerateAtlasRegionsFromData(TextureAtlasData textureAtlasData,  Texture2D atlasTexture)
        {
            TextureAtlas.Region[] regions = new TextureAtlas.Region[textureAtlasData.regions.Length];
            for (int regionID = 0; regionID < regions.Length; regionID++)
            {
                TextureAtlasData.AtlasRegionData regionData = textureAtlasData.regions[regionID];
                NinePatch nPatch = null;
                if (regionData.ninePatchData != null)
                {
                    NinePatchData nPatchData = regionData.ninePatchData;
                    nPatch = new NinePatch(atlasTexture, nPatchData.left, nPatchData.right, nPatchData.bottom, nPatchData.bottom, regionData.bounds);
                }
                regions[regionID] = new TextureAtlas.Region(regionData.name, regionData.bounds, nPatch, atlasTexture);
            }

            return regions;
        }
    }
}
