using System;
using System.Collections;
using System.Drawing;
using System.Xml;

namespace Map_Extractor
{
    public class Parameters
    {
        private static string _SourcePath = "";
        public static string SourcePath { get { return _SourcePath; } set { _SourcePath = value; } }

        private static string _DestinationPath = "";
        public static string DestinationPath { get { return _DestinationPath; } set { _DestinationPath = value; } }

        private static int _SourceMap = -1;
        public static int SourceMap { get { return _SourceMap; } set { _SourceMap = value; } }

        private static int _DestinationMap = -1;
        public static int DestinationMap { get { return _DestinationMap; } set { _DestinationMap = value; } }

        private static bool _CopyStatics = true;
        public static bool CopyStatics { get { return _CopyStatics; } set { _CopyStatics = value; } }

        private static bool _EntireMap = true;
        public static bool EntireMap { get { return _EntireMap; } set { _EntireMap = value; } }

        private static Rectangle _SourceArea = new Rectangle(-1, -1, -1, -1);
        public static Rectangle SourceArea { get { return _SourceArea; } set { _SourceArea = value; } }

        private static Point _DestinationLocation = new Point(-1, -1);
        public static Point DestinationLocation { get { return _DestinationLocation; } set { _DestinationLocation = value; } }

        private static Hashtable _ItemConversions = new Hashtable();
        public static Hashtable ItemConversions { get { return _ItemConversions; } set { _ItemConversions = value; } }

        public static void LoadParameters()
        {
            if (!System.IO.File.Exists("params.xml"))
                return;

            XmlDocument doc = new XmlDocument();
            doc.Load("params.xml");

            XmlElement root = doc["Extractor"];

            if (root == null)
                return;

            SourcePath = ReadString(root["source"], "path");
            SourceMap = ReadInt32(root["source"], "index");
            EntireMap = ReadBoolean(root["source"], "copyall", true);

            int x = ReadInt32(root["source"], "x");
            int y = ReadInt32(root["source"], "y");
            int w = ReadInt32(root["source"], "width");
            int h = ReadInt32(root["source"], "height");
            SourceArea = new Rectangle(x, y, w, h);

            DestinationPath = ReadString(root["destination"], "path");
            DestinationMap = ReadInt32(root["destination"], "index");
            
            x = ReadInt32(root["destination"], "x");
            y = ReadInt32(root["destination"], "y");
            DestinationLocation = new Point(x, y);

            CopyStatics = ReadBoolean(root["statics"], "copy", true);

            XmlElement conv = root["itemconversion"];

            if (conv != null)
            {
                foreach (XmlElement xmlConvert in conv.SelectNodes("convert"))
                {
                    UInt16 oldId = ReadUInt16(xmlConvert, "oldid");
                    UInt16 newId = ReadUInt16(xmlConvert, "newid");

                    ItemConversions[oldId] = newId;
                }
            }
        }

        public static void SaveParameters()
        {
            try
            {
                XmlTextWriter writer = new XmlTextWriter("params.xml", System.Text.Encoding.UTF8);

                writer.Formatting = Formatting.Indented;
                writer.WriteStartDocument();

                writer.WriteStartElement("Extractor");

                if (SourcePath != "" || SourceMap != -1)
                {
                    writer.WriteStartElement("source");

                    if (SourcePath != "")
                    {
                        writer.WriteStartAttribute("path");
                        writer.WriteValue(SourcePath);
                        writer.WriteEndAttribute();
                    }

                    if (SourceMap != -1)
                    {
                        writer.WriteStartAttribute("index");
                        writer.WriteValue(SourceMap);
                        writer.WriteEndAttribute();
                    }

                    writer.WriteStartAttribute("copyall");
                    writer.WriteValue(EntireMap);
                    writer.WriteEndAttribute();

                    if (SourceArea.X != -1)
                    {
                        writer.WriteStartAttribute("x");
                        writer.WriteValue(SourceArea.X);
                        writer.WriteEndAttribute();
                    }

                    if (SourceArea.Y != -1)
                    {
                        writer.WriteStartAttribute("y");
                        writer.WriteValue(SourceArea.Y);
                        writer.WriteEndAttribute();
                    }

                    if (SourceArea.Width != -1)
                    {
                        writer.WriteStartAttribute("width");
                        writer.WriteValue(SourceArea.Width);
                        writer.WriteEndAttribute();
                    }

                    if (SourceArea.Height != -1)
                    {
                        writer.WriteStartAttribute("height");
                        writer.WriteValue(SourceArea.Height);
                        writer.WriteEndAttribute();
                    }

                    writer.WriteEndElement();
                }

                if (DestinationPath != "" || DestinationMap != -1)
                {
                    writer.WriteStartElement("destination");

                    if (DestinationPath != "")
                    {
                        writer.WriteStartAttribute("path");
                        writer.WriteValue(DestinationPath);
                        writer.WriteEndAttribute();
                    }

                    if (DestinationMap != -1)
                    {
                        writer.WriteStartAttribute("index");
                        writer.WriteValue(DestinationMap);
                        writer.WriteEndAttribute();
                    }

                    if (DestinationLocation.X != -1)
                    {
                        writer.WriteStartAttribute("x");
                        writer.WriteValue(DestinationLocation.X);
                        writer.WriteEndAttribute();
                    }

                    if (DestinationLocation.Y != -1)
                    {
                        writer.WriteStartAttribute("y");
                        writer.WriteValue(DestinationLocation.Y);
                        writer.WriteEndAttribute();
                    }

                    writer.WriteEndElement();
                }

                writer.WriteStartElement("statics");

                writer.WriteStartAttribute("copy");
                writer.WriteValue(CopyStatics);
                writer.WriteEndAttribute();

                writer.WriteEndElement();

                if (ItemConversions.Count > 0)
                {
                    writer.WriteStartElement("itemconversion");

                    foreach (DictionaryEntry entry in ItemConversions)
                    {
                        writer.WriteStartElement("convert");

                        writer.WriteStartAttribute("oldid");
                        writer.WriteValue(entry.Key.ToString());
                        writer.WriteEndAttribute();

                        writer.WriteStartAttribute("newid");
                        writer.WriteValue(entry.Value.ToString());
                        writer.WriteEndAttribute();

                        writer.WriteEndElement();
                    }

                    writer.WriteEndElement();
                }

                writer.WriteEndElement();

                writer.WriteEndDocument();

                writer.Close();
            }
            catch { }
        }

        protected static string GetAttribute(XmlElement xml, string attribute)
        {
            if (xml == null)
                return null;
            else if (xml.HasAttribute(attribute))
                return xml.GetAttribute(attribute);
            else
                return null;
        }

        protected static string ReadString(XmlElement xml, string attribute)
        {
            return GetAttribute(xml, attribute);
        }

        protected static int ReadInt32(XmlElement xml, string attribute)
        {
            string s = GetAttribute(xml, attribute);

            if (s == null)
                return -1;

            try
            {
                return XmlConvert.ToInt32(s);
            }
            catch { }

            return 9999;
        }

        protected static UInt16 ReadUInt16(XmlElement xml, string attribute)
        {
            string s = GetAttribute(xml, attribute);

            if (s == null)
                return 65535;

            try
            {
                return XmlConvert.ToUInt16(s);
            }
            catch { }

            return 65535;
        }

        protected static bool ReadBoolean(XmlElement xml, string attribute, bool defaultValue)
        {
            string s = GetAttribute(xml, attribute);

            if (s == null)
                return defaultValue;

            try
            {
                return XmlConvert.ToBoolean(s);
            }
            catch { }

            return defaultValue;
        }
    }
}
