﻿using System;
using System.Collections.Generic;
using Oni.Imaging;

namespace Oni.Motoko
{
    internal static class TextureDatReader
    {
        public static Texture ReadInfo(InstanceDescriptor txmp)
        {
            var texture = new Texture
            {
                Name = txmp.Name
            };

            using (var reader = txmp.OpenRead(128))
            {
                texture.Flags = (TextureFlags)reader.ReadInt32();
                texture.Width = reader.ReadInt16();
                texture.Height = reader.ReadInt16();
                texture.Format = (TextureFormat)reader.ReadInt32();
                reader.Skip(8);

                if (txmp.IsMacFile)
                    reader.Skip(4);

                reader.Skip(4);
            }

            return texture;
        }

        public static Texture Read(InstanceDescriptor txmp)
        {
            var texture = new Texture
            {
                Name = txmp.Name
            };

            int rawOffset;

            using (var reader = txmp.OpenRead(128))
            {
                texture.Flags = (TextureFlags)reader.ReadInt32();
                texture.Width = reader.ReadInt16();
                texture.Height = reader.ReadInt16();
                texture.Format = (TextureFormat)reader.ReadInt32();
                reader.Skip(8);

                if (txmp.IsMacFile)
                    reader.Skip(4);

                rawOffset = reader.ReadInt32();
            }

            using (var rawReader = txmp.GetSepReader(rawOffset))
                ReadSurfaces(texture, rawReader);

            return texture;
        }

        private static void ReadSurfaces(Texture texture, BinaryReader reader)
        {
            var format = texture.Format.ToSurfaceFormat();
            int width = texture.Width;
            int height = texture.Height;
            bool hasMipMaps = (texture.Flags & TextureFlags.HasMipMaps) != 0;

            do
            {
                var surface = new Surface(width, height, format);
                reader.Read(surface.Data, 0, surface.Data.Length);
                texture.Surfaces.Add(surface);

                width = Math.Max(width >> 1, 1);
                height = Math.Max(height >> 1, 1);

            } while (hasMipMaps && (width > 1 || height > 1));
        }
    }
}
