// Created with MonoDevelop
//
//    QuickStep: Acquire, view and identify spectra 
//    Copyright (C) 2022 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.Reflection;
using Gtk;
using Hiperscan.Unix;
using Hiperscan.ApoIdentCore;
using Hiperscan.ApoIdentCore.Misc;
using Hiperscan.ApoIdentCore.GuiControl;
using Hiperscan.GtkExtensions.StandardDialogs;
using Hiperscan.AnalysisModule;
using Hiperscan.ApoIdentCommon.ApoConfig;

namespace Hiperscan.Extensions.ApoIdent
{
    public class ApoIdentAboutDialog : Gtk.AboutDialog
    {
        public static void Run(Gtk.Window parent, AppControl control)
        {
            var tmp = new ApoIdentAboutDialog(parent, control);
            tmp.ShowAll();
            tmp.Run();
            tmp.Destroy();
        }

        private ApoIdentAboutDialog(Gtk.Window parent, AppControl control)
        {
            this.Control = control;
            this.CreateWidgets();
            this.AddDefaultInfos(parent);
            this.AddDeviceInfos();
            this.AddSupportInfos();
        }

        private void CreateWidgets()
        {
            if (this.BothInstalled)
                this.CreateBothWidgets();
            else
                this.CreateSingleWidgets();
        }

        private void CreateSingleWidgets()
        {
            this.CurrentAnalysisType = AnalysisType.None;
            if (this.Control.GlobalStates.IsOnlyIdentModuleAvailable)
                this.CurrentAnalysisType = AnalysisType.Identification;
            if (this.Control.GlobalStates.IsOnlyQuantifierModuleAvailable)
                this.CurrentAnalysisType = AnalysisType.Quantification;

            Gtk.VBox vbox_tmp = ((Gtk.VBox)this.VBox.Children[0]);
            List<Widget> widgets = new List<Widget>(vbox_tmp.Children);
            foreach (Widget widget in widgets)
                vbox_tmp.Remove(widget);

            VBox add_vbox = new VBox();
            widgets.Insert(3, add_vbox);
            foreach (Widget widget in widgets)
            {
                vbox_tmp.Add(widget);
                widget.ShowAll();
            }

            this.SingleServerLinkButton = new LinkButton(String.Empty, String.Empty);
            this.SingleServerLinkButton.Visible = true;
            this.SingleServerLinkButton.Clicked += this.OnModuleLinkButtonClicked;
            this.AddModuleInfos(this.CurrentAnalysisType, this.SingleServerLinkButton);
            Gtk.Alignment add_align = new Alignment(0.5f, 0.5f, 0f, 0f);
            add_align.Add(this.SingleServerLinkButton);
            add_vbox.Add(add_align);

            add_vbox.ShowAll();
            add_align.ShowAll();
            this.SingleServerLinkButton.ShowAll();

            this.ExtendetInfosLabel = new Gtk.Label(Catalog.GetString("White reference: ") + "Zenith");
            this.ExtendetInfosLabel.Justify = Justification.Center;
            add_vbox.Add(this.ExtendetInfosLabel);

            Widget action_area = this.ActionArea.Children[2];
            this.ActionArea.Remove(action_area);

            this.SingleCertificateLinkButton = new LinkButton("", Catalog.GetString("Certificate"));
            this.SingleCertificateLinkButton.Visible = this.CurrentAnalysisType != AnalysisType.None;
            this.SingleCertificateLinkButton.TooltipText = Catalog.GetString("Open update certificate");
            this.SingleCertificateLinkButton.Clicked += this.OnCertificateLinkButtonClicked;

            this.ActionArea.Add(this.SingleCertificateLinkButton);
            this.ActionArea.Add(action_area);

            this.ActionArea.ShowAll();
            action_area.ShowAll();
            this.SingleCertificateLinkButton.Show();
        }

        private void CreateBothWidgets()
        {
            Gtk.VBox vbox_tmp = ((Gtk.VBox)this.VBox.Children[0]);
            List<Widget> widgets = new List<Widget>(vbox_tmp.Children);
            foreach (Widget widget in widgets)
                vbox_tmp.Remove(widget);

            VBox add_vbox = new VBox();
            widgets.Insert(3, add_vbox);
            foreach (Widget widget in widgets)
            {
                vbox_tmp.Add(widget);
                widget.ShowAll();
            }

            Gtk.Table table = new Table(2, 2, false);
            table.RowSpacing = 2;
            table.ColumnSpacing = 10;
            Gtk.Alignment add_align = new Alignment(0.5f, 0.5f, 1f, 1f);
            add_align.Add(table);
            add_vbox.Add(add_align);

            Gtk.Alignment tmp = null;

            this.SingleServerLinkButton = new LinkButton(String.Empty, String.Empty);
            this.SingleServerLinkButton.Visible = true;
            this.SingleServerLinkButton.Clicked += this.OnModuleLinkButtonClicked;
            this.AddModuleInfos(AnalysisType.Identification, this.SingleServerLinkButton);
            tmp = new Alignment(1.0f, 0.5f, 0f, 0f);
            tmp.Add(this.SingleServerLinkButton);
            table.Attach(tmp, 0, 1, 0, 1);
            tmp.ShowAll();
            this.SingleServerLinkButton.ShowAll();

            this.SingleCertificateLinkButton = new LinkButton("", Catalog.GetString("Certificate"));
            this.SingleCertificateLinkButton.TooltipText = Catalog.GetString("Open update certificate");
            this.SingleCertificateLinkButton.Clicked += this.OnCertificateLinkButtonClicked;
            tmp = new Alignment(0f, 0.5f, 0f, 0f);
            tmp.Add(this.SingleCertificateLinkButton);
            table.Attach(tmp, 1, 2, 0, 1);
            tmp.ShowAll();
            this.SingleCertificateLinkButton.ShowAll();

            this.BothServerLinkButton = new LinkButton(String.Empty, String.Empty);
            this.BothServerLinkButton.Visible = true;
            this.BothServerLinkButton.Clicked += this.OnModuleLinkButtonClicked;
            this.AddModuleInfos(AnalysisType.Quantification, this.BothServerLinkButton);
            tmp = new Alignment(1.0f, 0.5f, 0f, 0f);
            tmp.Add(this.BothServerLinkButton);
            table.Attach(tmp, 0, 1, 1, 2);
            tmp.ShowAll();
            this.BothServerLinkButton.ShowAll();

            this.BothCertificateLinkButton = new LinkButton("", Catalog.GetString("Certificate"));
            this.BothCertificateLinkButton.TooltipText = Catalog.GetString("Open update certificate");
            this.BothCertificateLinkButton.Clicked += this.OnCertificateLinkButtonClicked;
            tmp = new Alignment(0f, 0.5f, 0f, 0f);
            tmp.Add(this.BothCertificateLinkButton);
            table.Attach(tmp, 1, 2, 1, 2);
            tmp.ShowAll();
            this.BothCertificateLinkButton.ShowAll();

            this.ExtendetInfosLabel = new Gtk.Label(Catalog.GetString("White reference: ") + "Zenith");
            this.ExtendetInfosLabel.Justify = Justification.Center;
            add_vbox.Add(this.ExtendetInfosLabel);
        }

        private void AddDefaultInfos(Gtk.Window parent)
        {
            this.TransientFor = parent;
            this.ProgramName = "QuickStep " + ApoIdentInfo.NAME;
            this.Version = ApoIdentInfo.FullVersion;
            this.Comments = ApoIdentInfo.DESCRIPTION;
            this.Copyright = ApoIdentInfo.COPYRIGHT;
            this.WrapLicense = true;
            this.License = ApoIdentInfo.lICENSE;
            this.Authors = ApoIdentInfo.AUTHORS;
            if (this.Control.GlobalStates.IsOnlyQuantifierModuleAvailable == false)
            {
                this.Website = this.Control.DocumentManager.UriManager.OnlineHelp(UriReferrerId.TeamViewer, true);
                this.WebsiteLabel = Catalog.GetString("Service Centre");
            }
            this.Logo = new Gdk.Pixbuf(Assembly.GetExecutingAssembly(), "ApoIdent.Resources.Images.logo.png");
        }

        private void AddModuleInfos(AnalysisType analysis_type, Gtk.LinkButton button)
        {
            string label_text = Catalog.GetString("Not installed"); ;
            string tool_tip_text = Catalog.GetString("Show License");

            if (analysis_type != AnalysisType.None)
            {
                RemoteSettings settings = this.Control.SubstanceManager.GetRemoteSettings(analysis_type);

                string name = analysis_type.GetProductName();

                tool_tip_text = String.Format(Catalog.GetString("Show {0} License"), name);

                label_text = name +  " " + Catalog.GetString("Version") + " ";
                label_text += settings.ModuleVersion + "-" + settings.ServerSuffix;
            }

            button.Label = label_text;
            button.TooltipText = tool_tip_text;
        }

        private void AddDeviceInfos()
        {
            if (this.Control.MeasuringManager.Finder.DeviceExists == false)
                return;

            this.ExtendetInfosLabel.Text += "\n";
            this.ExtendetInfosLabel.Text += String.Format(Catalog.GetString("Product: {0}"),
                                                          this.Control.MeasuringManager.Finder.ProductName);

            this.ExtendetInfosLabel.Text += "\n";
            this.ExtendetInfosLabel.Text += String.Format(Catalog.GetString("Connection: {0}"),
                                                          this.Control.MeasuringManager.Finder.ConnectionType);

            if (this.Control.MeasuringManager.Finder.Device.Info.IsRemote == true)
                this.ExtendetInfosLabel.Text += String.Format(" - {0}", this.Control.MeasuringManager.Finder.RemoteDeviceServerAddress);

            this.ExtendetInfosLabel.Text += "\n";
            this.ExtendetInfosLabel.Text += String.Format(Catalog.GetString("Serial number: {0}"), this.Control.MeasuringManager.Finder.Serial);
        }

        private void AddSupportInfos()
        {
            this.ExtendetInfosLabel.Text += "\n\n" + Catalog.GetString(@"info@hiperscan.com
+49 351 212 496 0");
        }

        private void OnModuleLinkButtonClicked(object sender, EventArgs e)
        {
            if (this.BothInstalled)
            {
                if (sender == this.SingleServerLinkButton)
                    this.CurrentAnalysisType = AnalysisType.Identification;
                else
                    this.CurrentAnalysisType = AnalysisType.Quantification;
            }

            IdentServerLicenseDialog.Run(this, this.Control, this.CurrentAnalysisType);
        }

        private void OnCertificateLinkButtonClicked(object sender, EventArgs e)
        {
            if (this.BothInstalled)
            {
                if (sender == this.SingleCertificateLinkButton)
                    this.CurrentAnalysisType = AnalysisType.Identification;
                else
                    this.CurrentAnalysisType = AnalysisType.Quantification;
            }

            UpdateArgs arg = this.Control.ShowUpdateCertificate(this.CurrentAnalysisType);

            if (arg != null)
            {
                ErrorDialog.Run(this, arg.DialogArgs);
            }
        }

        public bool BothInstalled
        {
            get
            {
                return this.Control.GlobalStates.IsIdentModuleAvailable &&
                           this.Control.GlobalStates.IsQuantifierModuleAvailable;
            }
        }

        private AnalysisType CurrentAnalysisType { get; set; }

        private AppControl Control { get; set; }

        private Gtk.Label ExtendetInfosLabel { get; set; }

        private Gtk.LinkButton SingleServerLinkButton { get; set; }
        private Gtk.LinkButton SingleCertificateLinkButton { get; set; }

        private Gtk.LinkButton BothServerLinkButton { get; set; }
        private Gtk.LinkButton BothCertificateLinkButton { get; set; }
    }
}
