// 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.Collections.Generic;
using System.Globalization;
using System.Xml;

using Hiperscan.Common.I18n;


namespace Hiperscan.Extensions.ApoIdent
{


    public partial class Configurations
    {
        public enum IdentificationMode
        {
            Local,
            Custom
        }

        public class IdentModulePreferences : Preferences<IdentModulePreferences>
        {
            public const string ACQUISITION_SETTINGS_TAG = "AcquisitionSettings";
            private const string IDENTIFICATION_MODE_TAG = "IdentificationMode";
            private const string URL_TAG = "Url";
            private const string TCP_PORT_TAG = "Tcp";

            private const string IDENT_SERVER_VERSION_TAG = "IdentServerVersion";
            private const string IDENT_SERVER_SUFFIX_TAG = "IdentServerSuffix";
            private const string ARCHIVE_DOKU_TAG = "ArchiveDocu";
            private const string REMEMBER_UPDATE_INFO_TAG = "RememberUpdateInfo";
            private const string LOCALE_TAG = "Location";
            private const string TEST_VERSION_TAG = "TestVersion";
            private const string UPDATE_VALIDATION_DOCU_TAG = "UpdateValidationDocu";
            private const string UPDATE_OTHER_PDFS_TAG = "UpdateSubstancePdfs";
            private const string UPDATE_CERTIFICATE_TAG = "UpdateCertificate";
            private const string UPDATE_IM_LICENSE_TAG = "UpdateIMLicenseText";
            private const string UPDATE_ADDITIONAL_TESTS_PDFS_TAG = "UpdateAdditionalTestsPdfs";
            private const string VALIDATED_CLASSIFIER_TAG = "ValidatedClassifier";
            private const string MANAGED_CLASSIFIER_TAG = "ManagedClassifier";

            public IdentModulePreferences() : base()
            {

            }

            public IdentModulePreferences(XmlNode identmodule_settings_node) : base(identmodule_settings_node)
            {

            }

            protected override void Init(XmlNode parent_node = null)
            {
                this.IdentificationMode = IdentificationMode.Local;
                this.Url = String.Empty;
                this.TcpPort = -1;
                this.IdentServerVersion = String.Empty;
                this.IdentServerSuffix = String.Empty;
                this.Locale = Hiperscan.Common.I18n.Locale.LocaleType.Unknown;
                this.ReleaseExpirationTime = DateTime.MaxValue;
                this.UpdateValidationDocu = false;
                this.UpdateSubstancePdfs = false;
                this.UpdateUpdateCertificate = false;
                this.UpdateAdditionalTestsPdfs = false;
                this.UpdateIMLicenceText = false;
                this.ValidatedClassifiers = new List<string>();
                this.TestVersion = null;
                this.ManagedClassifiers = new List<string>();

                base.Init(parent_node);
            }

            protected override void Read(XmlNode acquisition_settings_node)
            {
                try
                {
                    XmlNode identification_mode_node = acquisition_settings_node.SelectNodes(IdentModulePreferences.IDENTIFICATION_MODE_TAG)[0];
                    this.IdentificationMode = (IdentificationMode)Enum.Parse(typeof(IdentificationMode), identification_mode_node.InnerText, true);
                }
                catch (Exception) { }

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

                try
                {
                    XmlNode port_node = acquisition_settings_node.SelectNodes(IdentModulePreferences.TCP_PORT_TAG)[0];
                    this.TcpPort = Int32.Parse(port_node.InnerText);
                }
                catch (Exception) { }

                try
                {
                    XmlNode server_node = acquisition_settings_node.SelectNodes(IdentModulePreferences.IDENT_SERVER_VERSION_TAG)[0];
                    this.IdentServerVersion = server_node.InnerText;
                }
                catch (Exception) { }

                try
                {
                    XmlNode suffix_node = acquisition_settings_node.SelectNodes(IdentModulePreferences.IDENT_SERVER_SUFFIX_TAG)[0];
                    this.IdentServerSuffix = suffix_node.InnerText;
                }
                catch (Exception) { }

                try
                {
                    XmlNode location_node = acquisition_settings_node.SelectNodes(IdentModulePreferences.LOCALE_TAG)[0];
                    this.Locale = (Locale.LocaleType)Enum.Parse(typeof(Locale.LocaleType), location_node.InnerText);
                }
                catch (Exception) { }

                try
                {
                    XmlNode remember_node = acquisition_settings_node.SelectNodes(IdentModulePreferences.REMEMBER_UPDATE_INFO_TAG)[0];
                    this.ReleaseExpirationTime = DateTime.Parse(remember_node.InnerText, CultureInfo.InvariantCulture);
                }
                catch (Exception) { }

                try
                {
                    XmlNode update_validation_node = acquisition_settings_node.SelectNodes(IdentModulePreferences.UPDATE_VALIDATION_DOCU_TAG)[0];
                    this.UpdateValidationDocu = Boolean.Parse(update_validation_node.InnerText);
                }
                catch (Exception) { }

                try
                {
                    XmlNode update_substance_pdfs_node = acquisition_settings_node.SelectNodes(IdentModulePreferences.UPDATE_OTHER_PDFS_TAG)[0];
                    this.UpdateSubstancePdfs = Boolean.Parse(update_substance_pdfs_node.InnerText);
                }
                catch (Exception) { }

                try
                {
                    XmlNode update_certificate_node = acquisition_settings_node.SelectNodes(IdentModulePreferences.UPDATE_CERTIFICATE_TAG)[0];
                    this.UpdateUpdateCertificate = Boolean.Parse(update_certificate_node.InnerText);
                }
                catch (Exception) { }

                try
                {
                    XmlNode update_im_license_node = acquisition_settings_node.SelectNodes(IdentModulePreferences.UPDATE_IM_LICENSE_TAG)[0];
                    this.UpdateIMLicenceText = Boolean.Parse(update_im_license_node.InnerText);
                }
                catch (Exception)
                {
                    this.UpdateIMLicenceText = true;
                }

                try
                {
                    XmlNode update_additional_tests_node = acquisition_settings_node.SelectNodes(IdentModulePreferences.UPDATE_ADDITIONAL_TESTS_PDFS_TAG)[0];
                    this.UpdateAdditionalTestsPdfs = Boolean.Parse(update_additional_tests_node.InnerText);
                }
                catch (Exception) { }

                try
                {
                    XmlNodeList validated_classifier_nodes = acquisition_settings_node.SelectNodes(IdentModulePreferences.VALIDATED_CLASSIFIER_TAG);
                    foreach (XmlNode validated_clasiifier_node in validated_classifier_nodes)
                        this.ValidatedClassifiers.Add(validated_clasiifier_node.InnerText);
                }
                catch (Exception) { }

                try
                {
                    XmlNodeList test_version_nodes = acquisition_settings_node.SelectNodes(IdentModulePreferences.TEST_VERSION_TAG);
                    foreach (XmlNode test_version_node in test_version_nodes)
                        this.TestVersion = Boolean.Parse(test_version_node.InnerText);
                }
                catch (Exception) { }

                try
                {
                    XmlNodeList managed_classifier_nodes = acquisition_settings_node.SelectNodes(IdentModulePreferences.MANAGED_CLASSIFIER_TAG);
                    foreach (XmlNode managed_clasiifier_node in managed_classifier_nodes)
                        this.ManagedClassifiers.Add(managed_clasiifier_node.InnerText);
                }
                catch (Exception) { }
            }

            public override void WriteToXml(XmlDocument doc, XmlNode parent)
            {
                XmlNode acquisition_settings_node_node = doc.CreateElement(IdentModulePreferences.ACQUISITION_SETTINGS_TAG);
                parent.AppendChild(acquisition_settings_node_node);

                XmlNode identification_mode_node = doc.CreateElement(IdentModulePreferences.IDENTIFICATION_MODE_TAG);
                identification_mode_node.InnerText = this.IdentificationMode.ToString();
                acquisition_settings_node_node.AppendChild(identification_mode_node);

                XmlNode url_node = doc.CreateElement(IdentModulePreferences.URL_TAG);
                url_node.InnerText = this.Url;
                acquisition_settings_node_node.AppendChild(url_node);

                XmlNode port_node = doc.CreateElement(IdentModulePreferences.TCP_PORT_TAG);
                port_node.InnerText = this.TcpPort.ToString();
                acquisition_settings_node_node.AppendChild(port_node);

                XmlNode server_node = doc.CreateElement(IdentModulePreferences.IDENT_SERVER_VERSION_TAG);
                server_node.InnerText = this.IdentServerVersion;
                acquisition_settings_node_node.AppendChild(server_node);

                XmlNode suffix_node = doc.CreateElement(IdentModulePreferences.IDENT_SERVER_SUFFIX_TAG);
                suffix_node.InnerText = this.IdentServerSuffix;
                acquisition_settings_node_node.AppendChild(suffix_node);

                XmlNode locale_node = doc.CreateElement(IdentModulePreferences.LOCALE_TAG);
                locale_node.InnerText = this.Locale.ToString();
                acquisition_settings_node_node.AppendChild(locale_node);

                XmlNode remember_node = doc.CreateElement(IdentModulePreferences.REMEMBER_UPDATE_INFO_TAG);
                remember_node.InnerText = this.ReleaseExpirationTime.ToString(CultureInfo.InvariantCulture);
                acquisition_settings_node_node.AppendChild(remember_node);

                XmlNode validation_docu_node = doc.CreateElement(IdentModulePreferences.UPDATE_VALIDATION_DOCU_TAG);
                validation_docu_node.InnerText = this.UpdateValidationDocu.ToString();
                acquisition_settings_node_node.AppendChild(validation_docu_node);

                XmlNode other_pdfs_node = doc.CreateElement(IdentModulePreferences.UPDATE_OTHER_PDFS_TAG);
                other_pdfs_node.InnerText = this.UpdateSubstancePdfs.ToString();
                acquisition_settings_node_node.AppendChild(other_pdfs_node);

                XmlNode update_certificate_node = doc.CreateElement(IdentModulePreferences.UPDATE_CERTIFICATE_TAG);
                update_certificate_node.InnerText = this.UpdateUpdateCertificate.ToString();
                acquisition_settings_node_node.AppendChild(update_certificate_node);

                XmlNode update_im_license_node = doc.CreateElement(IdentModulePreferences.UPDATE_IM_LICENSE_TAG);
                update_im_license_node.InnerText = this.UpdateIMLicenceText.ToString();
                acquisition_settings_node_node.AppendChild(update_im_license_node);

                XmlNode update_additional_tests_node = doc.CreateElement(IdentModulePreferences.UPDATE_ADDITIONAL_TESTS_PDFS_TAG);
                update_additional_tests_node.InnerText = this.UpdateAdditionalTestsPdfs.ToString();
                acquisition_settings_node_node.AppendChild(update_additional_tests_node);

                foreach (string validated_classifier in this.ValidatedClassifiers)
                {
                    XmlNode validated_classifier_node = doc.CreateElement(IdentModulePreferences.VALIDATED_CLASSIFIER_TAG);
                    validated_classifier_node.InnerText = validated_classifier;
                    acquisition_settings_node_node.AppendChild(validated_classifier_node);
                }

                if (this.TestVersion != null)
                {
                    XmlNode test_version_node = doc.CreateElement(IdentModulePreferences.TEST_VERSION_TAG);
                    test_version_node.InnerText = this.TestVersion.ToString();
                    acquisition_settings_node_node.AppendChild(test_version_node);
                }

                foreach (string managed_classifier in this.ManagedClassifiers)
                {
                    XmlNode managed_classifier_node = doc.CreateElement(IdentModulePreferences.MANAGED_CLASSIFIER_TAG);
                    managed_classifier_node.InnerText = managed_classifier;
                    acquisition_settings_node_node.AppendChild(managed_classifier_node);
                }
            }

            public override IdentModulePreferences Clone()
            {
                IdentModulePreferences tmp = new IdentModulePreferences();
                tmp.IdentificationMode = this.IdentificationMode;
                tmp.Url = this.Url;
                tmp.TcpPort = this.TcpPort;

                tmp.IdentServerVersion = this.IdentServerVersion;
                tmp.IdentServerSuffix = this.IdentServerSuffix;
                tmp.Locale = this.Locale;

                tmp.ReleaseExpirationTime = this.ReleaseExpirationTime;
                tmp.UpdateValidationDocu = this.UpdateValidationDocu;
                tmp.UpdateSubstancePdfs = this.UpdateSubstancePdfs;
                this.UpdateIMLicenceText = this.UpdateIMLicenceText;
                tmp.UpdateUpdateCertificate = this.UpdateUpdateCertificate;
                tmp.UpdateAdditionalTestsPdfs = this.UpdateAdditionalTestsPdfs;

                tmp.ValidatedClassifiers = new List<string>(this.ValidatedClassifiers);
                tmp.ManagedClassifiers = new List<string>(this.ManagedClassifiers);

                return tmp;
            }

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

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

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

                return false;
            }


            public IdentificationMode IdentificationMode { get; set; }
            public string Url { get; set; }
            public int TcpPort { get; set; }
            public string IdentServerVersion { get; set; }
            public DateTime ReleaseExpirationTime { get; set; }
            public Locale.LocaleType Locale { get; set; }
            public string IdentServerSuffix { get; set; }
            public bool UpdateValidationDocu { get; set; }
            public bool UpdateSubstancePdfs { get; set; }
            public bool UpdateUpdateCertificate { get; set; }
            public bool UpdateAdditionalTestsPdfs { get; set; }
            public bool UpdateIMLicenceText { get; set; }
            public List<string> ValidatedClassifiers { get; set; }
            public bool? TestVersion { get; set; }
            public List<string> ManagedClassifiers { get; set; }
        }
    }
}

