// 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.Drawing;
using Gtk;
using Hiperscan.ApoIdentCore;
using Hiperscan.NPlotEngine;
using Hiperscan.Spectroscopy;
using Hiperscan.Unix;

namespace Hiperscan.Extensions.ApoIdent
{
    public class ResultPlotDialog
    {
        public static void Run(Gtk.Window parent, AppControl control)
        {
            new ResultPlotDialog(parent, control).Run();
        }

        private ResultPlotDialog(Gtk.Window parent_window, AppControl control)
        {

            Hiperscan.Spectroscopy.DataSet original = null;
            Hiperscan.Spectroscopy.DataSet backproj = null;
            Hiperscan.Spectroscopy.DataSet matchbp = null;
            Hiperscan.Spectroscopy.DataSet difference = null;

            original = control.MeasuringManager.ProcessedSpectrum.Absorbance;
            backproj = control.ResultManager.IdentificationResult.SpectrumBackProjection;

            if (control.ResultManager.IdentificationIsTruePositive)
            {
                matchbp = control.ResultManager.IdentificationResult.MatchBackProjection;
                difference = backproj - matchbp;
            }

            original.Label = Catalog.GetString("Sample spectrum");
            original.Color = Color.Blue;
            backproj.Label = Catalog.GetString("Back-projection of sample spectrum");
            backproj.Color = Color.Blue;
            backproj.Id = "0_backprojection";

            if (control.ResultManager.IdentificationIsTruePositive == true)
            {
                matchbp.Label = Catalog.GetString("Back-projection of reference spectrum");
                matchbp.Color = Color.Red;
                matchbp.Id = "1_match";
                difference.Label = Catalog.GetString("Difference of back-projections*");
                difference.Color = Color.Green;
                difference.LineStyle = LineStyle.Dash;
                difference.Id = "2_difference";
            }

            this.dialog = new Dialog(Catalog.GetString("Absorbance Spectra"), parent_window, DialogFlags.Modal)
            {
                IconList = ApoIdentStock.FinderIcons
            };

            this.dialog.AddButton(Stock.Close, ResponseType.Close);
            this.dialog.WindowPosition = WindowPosition.CenterAlways;
            this.dialog.HasSeparator = true;
            this.dialog.WidthRequest = (int)(780 * 1.4);
            this.dialog.HeightRequest = (int)(400 * 1.4);

            this.plot1 = new NPlotEngine.NPlotEngine(PlotEngineType.Synchronous);
            this.plot1.BackgroundColor = new Gdk.Color(255, 255, 255);
            DataSet ds = new DataSet(original);
            ds.Label = original.Label;
            ds.Color = original.Color;
            this.plot1.AddDataSet(ds);
            this.plot1.Title = Catalog.GetString("Rawdata of the spectrum");
            this.plot1.XLabel = Catalog.GetString("Wavelength / nm");
            this.plot1.YLabel = Catalog.GetString("Absorbance");
            this.plot1.FitView();
            this.plot1.ProcessChanges();

            this.plot2 = new NPlotEngine.NPlotEngine(PlotEngineType.Synchronous);
            this.plot2.BackgroundColor = new Gdk.Color(255, 255, 255);
            this.plot2.AddDataSet(backproj);
            this.plot2.Title = Catalog.GetString("Comparison of processed spectrum and database entry");
            if (control.ResultManager.IdentificationIsTruePositive == true)
                this.plot2.AddDataSet(matchbp);
            this.plot2.XLabel = Catalog.GetString("Wavelength / nm");
            this.plot2.YLabel = Catalog.GetString("f(Absorbance)");
            this.plot2.FitView();
            this.plot2.ProcessChanges();

            if (control.ProfileManager.CurrentProfile.ShowDifference == true && control.ResultManager.IdentificationIsTruePositive)
            {
                this.plot2.UseSecondAxes = true;
                this.plot2.AddDataSet(difference);
                double min = difference.YMin();
                double max = difference.YMax();
                this.plot2.YMin = min - 2 * (max - min);
                this.plot2.YMax = max + 2 * (max - min);
                this.plot2.ProcessChanges();
                this.plot2.YLabel = Catalog.GetString("Difference*");
                this.plot2.ProcessChanges();
            }

            HBox hbox = new HBox(true, 5);
            hbox.PackStart(this.plot1.GtkWidget, true, true, 0);
            hbox.PackStart(this.plot2.GtkWidget, true, true, 0);

            this.dialog.VBox.PackStart(hbox);

            hbox.ShowAll();
        }

        private void Run()
        {
            this.dialog.IconList = ApoIdentStock.FinderIcons;

            GuiDesigner.SetSchema(this.dialog);
            dialog.Run();

            dialog.Destroy();

            ((IDisposable)plot1).Dispose();
            ((IDisposable)plot2).Dispose();
        }

        private Dialog dialog { get; set; }
        private IPlotEngine plot1 { get; set; }
        private IPlotEngine plot2 { get; set; }
    }
}
