﻿using System.Collections.Generic;
using System.Xml;
using Oni.Metadata;

namespace Oni.Objects
{
    internal class ObjectEvent
    {
        private ObjectEventType action;
        private int targetId;
        private string script;

        public ObjectEvent()
        {
        }

        private ObjectEvent(BinaryReader reader)
        {
            action = (ObjectEventType)reader.ReadInt16();

            if (action == ObjectEventType.Script)
                script = reader.ReadString(32);
            else if (action != ObjectEventType.None)
                targetId = reader.ReadUInt16();
        }

        public ObjectEventType Action => action;
        public int TargetId => targetId;
        public string Script => script;

        public static ObjectEvent[] ReadEventList(BinaryReader reader)
        {
            var events = new ObjectEvent[reader.ReadUInt16()];

            for (int i = 0; i < events.Length; i++)
                events[i] = new ObjectEvent(reader);

            return events;
        }

        public static void WriteEventList(BinaryWriter writer, ObjectEvent[] events)
        {
            if (events == null)
            {
                writer.WriteUInt16(0);
                return;
            }

            writer.WriteUInt16(events.Length);

            for (int i = 0; i < events.Length; i++)
            {
                writer.WriteUInt16((ushort)events[i].action);

                if (events[i].action == ObjectEventType.Script)
                    writer.Write(events[i].script, 32);
                else if (events[i].action != ObjectEventType.None)
                    writer.WriteUInt16(events[i].targetId);
            }
        }

        public static ObjectEvent[] ReadEventList(XmlReader xml)
        {
            var events = new List<ObjectEvent>();

            if (xml.IsStartElement("Events") && xml.IsEmptyElement)
            {
                xml.ReadStartElement();
                return events.ToArray();
            }

            xml.ReadStartElement("Events");

            while (xml.IsStartElement())
            {
                var evt = new ObjectEvent();

                evt.action = MetaEnum.Parse<ObjectEventType>(xml.LocalName);

                switch (evt.action)
                {
                    case ObjectEventType.None:
                        break;
                    case ObjectEventType.Script:
                        evt.script = xml.GetAttribute("Function");
                        break;
                    default:
                        evt.targetId = XmlConvert.ToInt16(xml.GetAttribute("TargetId"));
                        break;
                }

                events.Add(evt);
                xml.Skip();
            }

            xml.ReadEndElement();

            return events.ToArray();
        }
    }
}
