﻿using System.Xml;
using Oni.Particles;

namespace Oni.Xml
{
    internal class OnieXmlExporter : RawXmlExporter
    {
        private OnieXmlExporter(BinaryReader reader, XmlWriter xml)
            : base(reader, xml)
        {
        }

        public static void Export(BinaryReader reader, XmlWriter xml)
        {
            var exporter = new OnieXmlExporter(reader, xml);
            exporter.Export();
        }

        private void Export()
        {
            Reader.Skip(8);
            var impacts = new string[Reader.ReadInt32()];
            var materials = new string[Reader.ReadInt32()];
            var particles = new ImpactEffectParticle[Reader.ReadInt32()];
            var sounds = new ImpactEffectSound[Reader.ReadInt32()];
            var effects = new ImpactEffect[Reader.ReadInt32()];
            Reader.Skip(4);

            for (int i = 0; i < impacts.Length; i++)
            {
                impacts[i] = Reader.ReadString(128);
                Reader.Skip(4);
            }

            for (int i = 0; i < materials.Length; i++)
            {
                materials[i] = Reader.ReadString(128);
                Reader.Skip(4);
            }

            for (int i = 0; i < impacts.Length; i++)
            {
                Reader.Skip(8);
            }

            for (int i = 0; i < particles.Length; i++)
            {
                particles[i] = new ImpactEffectParticle(Reader);
            }

            for (int i = 0; i < sounds.Length; i++)
            {
                sounds[i] = new ImpactEffectSound(Reader);
            }

            for (int i = 0; i < effects.Length; i++)
            {
                effects[i] = new ImpactEffect(Reader, impacts, materials, particles, sounds);
            }

            Xml.WriteStartElement("ImpactEffects");

            foreach (string impact in impacts)
            {
                Xml.WriteStartElement("Impact");
                Xml.WriteAttributeString("Name", impact);

                foreach (string material in materials)
                {
                    bool found = false;

                    foreach (ImpactEffect effect in effects)
                    {
                        if (effect.ImpactName == impact && effect.MaterialName == material)
                        {
                            found = true;
                            break;
                        }
                    }

                    if (!found)
                        continue;

                    Xml.WriteStartElement("Material");
                    Xml.WriteAttributeString("Name", material);

                    foreach (ImpactEffect effect in effects)
                    {
                        if (effect.ImpactName == impact && effect.MaterialName == material)
                        {
                            Xml.WriteStartElement("ImpactEffect");
                            effect.Write(Xml);
                            Xml.WriteEndElement();
                        }
                    }

                    Xml.WriteEndElement();
                }

                Xml.WriteEndElement();
            }

            Xml.WriteEndElement();
        }
    }
}
