// Created with MonoDevelop
//
//    QuickStep: Acquire, view and identify spectra 
//    Copyright (C) 2017 Thomas Klose & Torsten Schache, Hiperscan GmbH Dresden, Germany
//
//    This program is free software: you can redistribute it and/or modify
//    it under the terms of the GNU General Public License as published by
//    the Free Software Foundation, either version 3 of the License, or
//    (at your option) any later version.
//
//    This program is distributed in the hope that it will be useful,
//    but WITHOUT ANY WARRANTY; without even the implied warranty of
//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//    GNU General Public License for more details.
//
//    You should have received a copy of the GNU General Public License
//    along with this program.  If not, see <http://www.gnu.org/licenses/>.

using System;
using System.Xml;

namespace Hiperscan.ApoIdentCommon.ApoConfig
{
    public enum DeviceSearchModes
    {
        Automatic,
        Custom
    }

    public class DeviceSettings : SettingsTemplate<DeviceSettings>
    {
        public const int DEFAULT_PORT = 49152;

        public const string DEVICE_SETTINGS_TAG = "DeviceSettings";
        private const string DEVICE_SEARCH_MODE_TAG = "DeviceSearchMode";
        private const string URL_TAG = "Url";
        private const string TCP_PORT_TAG = "Tcp";
        private const string LAST_URL_TAG = "LastUrl";
        private const string LAST_TCP_PORT_TAG = "LastTcp";

        public DeviceSettings() : base()
        {

        }

        public DeviceSettings(XmlNode device_settings_node) : base(device_settings_node)
        {

        }

        protected override void Init(XmlNode parent_node = null)
        {
            this.SearchMode = DeviceSearchModes.Automatic;
            this.Url = String.Empty;
            this.TcpPort = DeviceSettings.DEFAULT_PORT;

            base.Init(parent_node);
        }

        protected override void Read(XmlNode parent_node)
        {
            try
            {
                XmlNode device_search_mode_node = parent_node.SelectNodes(DeviceSettings.DEVICE_SEARCH_MODE_TAG)[0];
                this.SearchMode = (DeviceSearchModes)Enum.Parse(typeof(DeviceSearchModes), device_search_mode_node.InnerText, true);
            }
            catch (Exception) { }

            try
            {
                XmlNode url_node = parent_node.SelectNodes(DeviceSettings.URL_TAG)[0];
                this.Url = url_node.InnerText;
            }
            catch (Exception) { }

            try
            {
                XmlNode port_node = parent_node.SelectNodes(DeviceSettings.TCP_PORT_TAG)[0];
                this.TcpPort = Int32.Parse(port_node.InnerText);
                if (this.TcpPort < 1)
                    this.TcpPort = DeviceSettings.DEFAULT_PORT;
            }
            catch (Exception)
            {
                this.TcpPort = DeviceSettings.DEFAULT_PORT;
            }

            try
            {
                XmlNode mdns_url_node = parent_node.SelectNodes(DeviceSettings.LAST_URL_TAG)[0];
                this.LastUrl = mdns_url_node.InnerText;
            }
            catch (Exception) { }

            try
            {
                XmlNode mdns_port_node = parent_node.SelectNodes(DeviceSettings.LAST_TCP_PORT_TAG)[0];
                this.LastTcpPort = Int32.Parse(mdns_port_node.InnerText);
            }
            catch (Exception) { }
        }

        public override void WriteToXml(XmlDocument doc, XmlNode parent)
        {
            XmlNode device_settings_node = doc.CreateElement(DeviceSettings.DEVICE_SETTINGS_TAG);
            parent.AppendChild(device_settings_node);

            XmlNode device_search_node = doc.CreateElement(DeviceSettings.DEVICE_SEARCH_MODE_TAG);
            device_search_node.InnerText = this.SearchMode.ToString();
            device_settings_node.AppendChild(device_search_node);

            XmlNode url_node = doc.CreateElement(DeviceSettings.URL_TAG);
            url_node.InnerText = this.Url;
            device_settings_node.AppendChild(url_node);

            XmlNode port_node = doc.CreateElement(DeviceSettings.TCP_PORT_TAG);
            port_node.InnerText = this.TcpPort.ToString();
            device_settings_node.AppendChild(port_node);

            XmlNode mdns_url_node = doc.CreateElement(DeviceSettings.LAST_URL_TAG);
            mdns_url_node.InnerText = this.LastUrl;
            device_settings_node.AppendChild(mdns_url_node);

            XmlNode mdns_port_node = doc.CreateElement(DeviceSettings.LAST_TCP_PORT_TAG);
            mdns_port_node.InnerText = this.LastTcpPort.ToString();
            device_settings_node.AppendChild(mdns_port_node);
        }

        public override DeviceSettings Clone()
        {
            DeviceSettings tmp = new DeviceSettings();
            tmp.SearchMode = this.SearchMode;
            tmp.Url = this.Url;
            tmp.TcpPort = this.TcpPort;

            return tmp;
        }

        protected override bool SettingsChanged()
        {
            if (this.Stashed == null)
                return false;

            if (this.Stashed.SearchMode != this.SearchMode)
                return true;

            if (this.SearchMode == DeviceSearchModes.Custom)
            {
                return this.Stashed.Url != this.Url ||
                       this.Stashed.TcpPort != this.TcpPort;
            }

            return false;
        }

        public bool HasRemoteInfos
        {
            get
            {
                if (this.SearchMode == DeviceSearchModes.Custom)
                    return true;

                if (String.IsNullOrEmpty(this.LastUrl) == false)
                    return true;

                return false;
            }
        }

        public DeviceSearchModes SearchMode { get; set; }
        public string Url { get; set; }
        public int TcpPort { get; set; }

        public string LastUrl { get; set; }
        public int LastTcpPort { get; set; }
    }
}

