﻿using System;
using System.Collections.Generic;
using System.Text;

namespace Oni.Level
{
    internal class LevelDatReader
    {
        private InstanceDescriptor onlv;
        private BinaryReader dat;
        private Level level;

        public static Level Read(InstanceDescriptor onlv, BinaryReader dat)
        {
            LevelDatReader reader = new LevelDatReader();
            reader.onlv = onlv;
            reader.dat = dat;
            reader.level = new Level();
            reader.Read();
            return reader.level;
        }

        private void Read()
        {
            InstanceDescriptor akev;
            InstanceDescriptor oboa;
            InstanceDescriptor onsk;
            InstanceDescriptor aisa;
            InstanceDescriptor onoa;
            InstanceDescriptor envp;
            InstanceDescriptor crsa;

            level.Name = dat.ReadString(64);
            akev = dat.ReadInstance();
            oboa = dat.ReadInstance();
            dat.Skip(12);
            onsk = dat.ReadInstance();
            dat.Skip(4);
            aisa = dat.ReadInstance();
            dat.Skip(12);
            onoa = dat.ReadInstance();
            envp = dat.ReadInstance();
            dat.Skip(644);
            crsa = dat.ReadInstance();
        }

        private void ReadOBOA(InstanceDescriptor oboa)
        {
            List<PhyObject> objects = new List<PhyObject>();

            using (BinaryReader reader = oboa.OpenRead())
            {
                reader.Skip(22);
                int count = reader.ReadUInt16();

                for (int i = 0; i < count; i++)
                {
                    InstanceDescriptor m3ga = reader.ReadInstance();
                    InstanceDescriptor oban = reader.ReadInstance();
                    InstanceDescriptor envp = reader.ReadInstance();
                    PhyObjectFlags flags = (PhyObjectFlags)reader.ReadInt32();
                    reader.Skip(4);
                    int doorId = reader.ReadInt32();
                    PhyType phyType = (PhyType)reader.ReadInt32();
                    int scriptId = reader.ReadInt32();
                    Vector3 position = reader.ReadVector3();
                    Quaternion rotation = reader.ReadQuaternion();
                    float scale = reader.ReadSingle();
                    Matrix matrix = reader.ReadMatrix4x3();
                    string name = reader.ReadString(64);
                    string fileName = reader.ReadString(64);

                    if ((flags & PhyObjectFlags.Used) == 0)
                        continue;
                }
            }
        }

        private void ReadENVP(InstanceDescriptor envp)
        {
            List<EnvParticle> objects = new List<EnvParticle>();

            using (BinaryReader reader = envp.OpenRead())
            {
                reader.Skip(22);
                int count = reader.ReadUInt16();

                for (int i = 0; i < count; i++)
                {
                    string className = reader.ReadString(64);
                    string name = reader.ReadString(48);
                    Matrix matrix = reader.ReadMatrix4x3();
                    Vector2 decalScale = reader.ReadVector2();
                    reader.Skip(40);
                }
            }
        }

        private class DatObjectQuads
        {
            public uint ObjectId;
            public int[] QuadIndices;
        }

        private void ReadONOA(InstanceDescriptor onoa)
        {
            List<DatObjectQuads> objects = new List<DatObjectQuads>();
            List<InstanceDescriptor> indices = new List<InstanceDescriptor>();

            using (BinaryReader reader = onoa.OpenRead())
            {
                reader.Skip(20);
                int count = reader.ReadInt32();

                for (int i = 0; i < count; i++)
                {
                    uint id = reader.ReadUInt32();
                    InstanceDescriptor idxa = reader.ReadInstance();

                    DatObjectQuads obj = new DatObjectQuads();
                    obj.ObjectId = id;
                    objects.Add(obj);
                    indices.Add(idxa);
                }
            }

            for (int i = 0; i < objects.Count; i++)
            {
                using (BinaryReader reader = indices[i].OpenRead())
                {
                    reader.Skip(20);
                    objects[i].QuadIndices = reader.ReadInt32VarArray();
                }
            }
        }

        private void ReadAISA(InstanceDescriptor aisa)
        {
            List<ScriptCharacter> chars = new List<ScriptCharacter>();

            using (BinaryReader reader = aisa.OpenRead())
            {
                reader.Skip(22);
                int count = reader.ReadUInt16();

                for (int i = 0; i < count; i++)
                {
                    string name = reader.ReadString(32);
                    int id = reader.ReadUInt16();
                    int flagId = reader.ReadUInt16();
                    reader.Skip(2);
                    int teamId = reader.ReadUInt16();
                    InstanceDescriptor oncc = reader.ReadInstance();
                    reader.Skip(32);
                    reader.Skip(4);
                    string createScript = reader.ReadString(32);
                    string dieScript = reader.ReadString(32);
                    string enemyScript = reader.ReadString(32);
                    string alarmScript = reader.ReadString(32);
                    string hurtScript = reader.ReadString(32);
                    string lowHealthScript = reader.ReadString(32);
                    string lowAmmoScript = reader.ReadString(32);
                    string noPathScript = reader.ReadString(32);
                    InstanceDescriptor onwc = reader.ReadInstance();
                    int ammo = reader.ReadUInt16();
                    reader.Skip(10);
                }
            }
        }
    }
}
