// Created with MonoDevelop
//
//    QuickStep: Acquire, view and identify spectra 
//    Copyright (C) 2022, 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.IO;
using System.Reflection;

using Hiperscan.Common.I18n;
using Hiperscan.Unix;
using Hiperscan.ApoIdentCore.Misc;
using Hiperscan.ApoIdentCore.SectionManager.Substance;
using Hiperscan.ApoIdentCore.SectionManager.Substance.SubstanceSelection;
using Hiperscan.ApoIdentCommon.ApoConfig.IO;
using Hiperscan.AnalysisModule;

namespace Hiperscan.ApoIdentCore
{
    public class DocumentManager
    {
        public event EventHandler ErrorOccurred = null;
        public event EventHandler PreShowSuggestion = null;

        public DocumentManager(CatalogLocale.LocaleType locale,  SubstanceManager substance_manager, ApoIdentFileSystem file_sytem)
        {
            this.FileSystem = file_sytem;
            this.UriManager = new UriManager(locale);
            this.SubstancePdfs = substance_manager.Pdfs;
            this.SubstanceCatalog = substance_manager.SubstancesCatalog;
        }

        public void ShowPDF(string file_name)
        {
            try
            {
                this.FileSystem.OpenPdf(file_name);
            }
            catch (Exception ex)
            {
                this.ErrorMessage = String.Format(Catalog.GetString("Cannot open file '{0}': {1}"),
                                                  file_name,
                                                  ex.Message);

                this.Exception = ex;
                this.ErrorOccurred?.Invoke(this, EventArgs.Empty);
            }
        }

        public void OpenUri(UriReferrerId id)
        {
            try
            {
                Process.OpenUri(UriManager.OnlineHelp(id, false));
            }
            catch (Exception ex)
            {
                this.ErrorMessage = String.Format(Catalog.GetString("Cannot open link {0}: {1}"),
                                                  id,
                                               ex.Message);

                this.Exception = ex;
                this.ErrorOccurred?.Invoke(this, EventArgs.Empty);
            }
        }

        public void ShowSubstancePdf(SubstancePdfs.PdfListType type)
        {
            try
            {
                this.SubstancePdfs.ShowSubstanceOverviewPdf(type);
            }
            catch (Exception ex)
            {
                this.ErrorMessage = String.Format(Catalog.GetString("Cannot open substance PDF ({0}): {1}"), 
                                                  type,
                                                  ex.Message);

                this.Exception = ex;
                this.ErrorOccurred?.Invoke(this, EventArgs.Empty);
            }
        }

        public void ShowAdditionalTests(AnalysisType analysis_type, string model_name = null)
        {
            try
            {
                this.SubstancePdfs.ShowAdditionalTestPdf(analysis_type, model_name);
            }
            catch (Exception ex)
            {
                this.ErrorMessage = String.Format(Catalog.GetString("Cannot open Additional Tests PDF: {0}"),
                                                  ex.Message);

                this.Exception = ex;
                this.ErrorOccurred?.Invoke(this, EventArgs.Empty);
            }
        }

        public void ShowValidationPdf(AnalysisType analysis_type, string model_class)
        {
            try
            {
                this.SubstancePdfs.ShowValidationPdf(analysis_type, model_class);
            }
            catch (Exception ex)
            {
                this.ErrorMessage = String.Format(Catalog.GetString("Cannot open validation documents ({0}): {1}"),
                                                  model_class,
                                                  ex.Message);

                this.Exception = ex;
                this.ErrorOccurred?.Invoke(this, EventArgs.Empty);
            }
        }

        public bool ShowUpadteCertificate(AnalysisType analysis_type)
        {
            try
            {
                this.SubstancePdfs.ShowUpdateCertificatePdf(analysis_type);
                return true;
            }
            catch(Exception ex)
            {
                this.ErrorMessage = String.Format(Catalog.GetString("Cannot open certification document: {0}"),
                                                  ex.Message);

                this.Exception = ex;
                return false;
            }
        }

        public void ShowSuggestionPdf()
        {
            try
            {
                AnalysisType analysis_type = this.SubstanceCatalog.AnalysisType;

                string link = this.SubstanceCatalog.Substance.PdfLinkAdditionalTest;

                if (analysis_type != AnalysisType.Quantification)
                    this.PreShowSuggestion?.Invoke(this, EventArgs.Empty);

                string model_class = null;
                if (analysis_type == AnalysisType.Quantification)
                {
                    model_class = link;
                    link = String.Empty;
                }

                string pdf_file = this.FileSystem.GetAdditionalTestFile(analysis_type, model_class);
                Hiperscan.PdfLib.Pdf.Open(pdf_file, link);
            }
            catch(Exception ex)
            {
                this.ErrorMessage = String.Format(Catalog.GetString("Cannot open Additional Tests document: {0}"),
                                                  ex.Message);

                this.Exception = ex;
                this.ErrorOccurred?.Invoke(this, EventArgs.Empty);
            }
        }

        public UriManager UriManager { get; private set; }
        public Exception Exception { get; private set; }
        public string ErrorMessage { get; private set; }
        private SubstancePdfs SubstancePdfs { get; set; }
        private SubstancesCatalog SubstanceCatalog { get; set; }
        private ApoIdentFileSystem FileSystem { get; set; }
    }
}
