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

namespace Hiperscan.Extensions.ApoIdent
{
    public partial class Configurations
    {
        public class ScannerPreferences : Preferences<ScannerPreferences>
        {
            public const string SCANNER_SETTINGS_TAG = "ScannerSettings";
            private const string START_SEQUENCE_TAG = "StartSequence";
            private const string END_SEQUENCE_TAG = "EndSequence";
            private const string GDK_SIGN_TAG = "GdkSign";
            private const string SCAN_VERSION_TAG = "ScanVersion";


            public ScannerPreferences() : base()
            {

            }

            public ScannerPreferences(XmlNode gui_settings_node) : base(gui_settings_node)
            {
            }

            protected override void Init(XmlNode parent_node = null)
            {
                this.StartKeys = this.DefaultStartKeys;
                this.EndKeys = this.DefaultEndKeys;
                this.ScanVersion = new Version(3, 0);

                base.Init(parent_node);
            }

            protected override void Read(XmlNode parent_node)
            {
                try
                {
                    XmlNode start_node = parent_node.SelectNodes(ScannerPreferences.START_SEQUENCE_TAG)[0];
                    XmlNodeList signs = start_node.SelectNodes(ScannerPreferences.GDK_SIGN_TAG);


                    this.StartKeys = new Gdk.Key[signs.Count];
                    for (int i = 0; i < signs.Count; i++)
                        this.StartKeys[i] = (Gdk.Key)Enum.Parse(typeof(Gdk.Key), signs[i].InnerText);
                }
                catch (Exception)
                {
                    this.StartKeys = this.DefaultStartKeys;
                }

                try
                {
                    XmlNode end_node = parent_node.SelectNodes(ScannerPreferences.END_SEQUENCE_TAG)[0];
                    XmlNodeList signs = end_node.SelectNodes(ScannerPreferences.GDK_SIGN_TAG);


                    this.EndKeys = new Gdk.Key[signs.Count];
                    for (int i = 0; i < signs.Count; i++)
                        this.EndKeys[i] = (Gdk.Key)Enum.Parse(typeof(Gdk.Key), signs[i].InnerText);
                }
                catch (Exception)
                {
                    this.EndKeys = this.DefaultEndKeys;
                }

                this.ReadScanVersion(parent_node);
            }

            private void ReadScanVersion(XmlNode parent_node)
            {
                Version version = new Version(1, 0);
                try
                {
                    XmlNode version_node = parent_node.SelectNodes(ScannerPreferences.SCAN_VERSION_TAG)[0];
                    version = new Version(version_node.InnerText);
                }
                catch(Exception)
                {
                }

                if (this.ScanVersion == version)
                    return;

                //Here code for any changes of version

                this.StartKeys = this.DefaultStartKeys;
                this.EndKeys = this.DefaultEndKeys;
                this.ForceWriting = true;
            }

            public override void WriteToXml(XmlDocument doc, XmlNode parent)
            {
                XmlNode scanner_settings_node = doc.CreateElement(ScannerPreferences.SCANNER_SETTINGS_TAG);
                parent.AppendChild(scanner_settings_node);


                XmlNode start_sequence_node = doc.CreateElement(ScannerPreferences.START_SEQUENCE_TAG);
                scanner_settings_node.AppendChild(start_sequence_node);
                foreach (Gdk.Key key in this.StartKeys)
                {
                    XmlNode sign_node = doc.CreateElement(ScannerPreferences.GDK_SIGN_TAG);
                    sign_node.InnerText = key.ToString();
                    start_sequence_node.AppendChild(sign_node);
                }

                XmlNode end_sequence_node = doc.CreateElement(ScannerPreferences.END_SEQUENCE_TAG);
                scanner_settings_node.AppendChild(end_sequence_node);
                foreach (Gdk.Key key in this.EndKeys)
                {
                    XmlNode sign_node = doc.CreateElement(ScannerPreferences.GDK_SIGN_TAG);
                    sign_node.InnerText = key.ToString();
                    end_sequence_node.AppendChild(sign_node);
                }

                XmlNode version_node = doc.CreateElement(ScannerPreferences.SCAN_VERSION_TAG);
                version_node.InnerText = this.ScanVersion.ToString();
                scanner_settings_node.AppendChild(version_node);
            }

            public override ScannerPreferences Clone()
            {
                ScannerPreferences tmp = new ScannerPreferences();

                tmp.StartKeys = new Gdk.Key[this.StartKeys.Length];
                for (int i = 0; i < this.StartKeys.Length; i++)
                    tmp.StartKeys[i] = this.StartKeys[i];

                tmp.EndKeys = new Gdk.Key[this.EndKeys.Length];
                for (int i = 0; i < this.EndKeys.Length; i++)
                    tmp.EndKeys[i] = this.EndKeys[i];

                return tmp;
            }

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

                if (this.Stashed.StartKeys.Length != this.StartKeys.Length)
                    return true;

                for (int i = 0; i < this.StartKeys.Length; i++)
                {
                    if (this.Stashed.StartKeys[i] != this.StartKeys[i])
                        return false;
                }

                if (this.Stashed.EndKeys.Length != this.EndKeys.Length)
                    return true;

                for (int i = 0; i < this.EndKeys.Length; i++)
                {
                    if (this.Stashed.EndKeys[i] != this.EndKeys[i])
                        return false;
                }

                return false;
            }

            private Gdk.Key[] DefaultStartKeys
            {
                get
                {
                    return new Gdk.Key[]
                    {
                        Gdk.Key.Control_L,
                        Gdk.Key.b,
                    };
                }
            }

            private Gdk.Key[] DefaultEndKeys
            {
                get
                {
                    return new Gdk.Key[]
                    {
                        Gdk.Key.Return,
                    };
                }
            }

            public Gdk.Key[] StartKeys { get; set; } = null;
            public Gdk.Key[] EndKeys { get; set; } = null;
            public Version ScanVersion { get; set; }
        }

    }
}
