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

namespace Hiperscan.Extensions.ApoIdent
{
    public class DetailsPlot
    {
        public DetailsPlot (ReportInfo report_info, bool use_i18n)
        {
            this.ReportInfo = report_info;

            this.Original          = this.ReportInfo.Spectrum.Absorbance;
            this.Backprojection     = this.ReportInfo.Backprojection;

            if  (this.ReportInfo.IsMatch == true)
            {
                this.MatchBackProjection = this.ReportInfo.MatchBackProjection;
                this.Difference = this.Backprojection - this.MatchBackProjection;
            }


            if (use_i18n == true)
            {
                this.SetI18nPlot();
            }
            else
            {
                switch (this.ReportInfo.ReportCountry)
                {

                case Configurations.ReportCountryType.Austria:
                    this.SetAustriaPlot();
                    break;

                case Configurations.ReportCountryType.Germany:
                    this.SetGermanyPlot();
                    break;

                case Configurations.ReportCountryType.GreatBritain:
                    this.SetGreatBritainPlot();
                    break;

                case Configurations.ReportCountryType.Switzerland:
                    this.SetSwitzerlandPlot();
                    break;

                default:
                        throw new NotImplementedException("Unknown report country: " +  this.ReportInfo.ReportCountry);

                }
            }        
        }


        private void SetGermanyPlot()
        {
            this.Original.Label         = "Probenspektrum";
            this.Original.Color           = Color.Blue;
            this.Backprojection.Label   = "Rückprojektion des Probenspektrums";
            this.Backprojection.Color   = Color.Blue;
            this.Backprojection.Id      = "0_backprojection";

            if (this.ReportInfo.IsMatch == true)
            {    
                this.MatchBackProjection.Label    = "Rückprojektion des Referenzspektrums";
                this.MatchBackProjection.Color     = Color.Red;
                this.MatchBackProjection.Id       = "1_match";
                this.Difference.Label             = "Differenz der Rückprojektionen*";
                this.Difference.Color             = Color.Green;
                this.Difference.LineStyle         = LineStyle.Dash;
                this.Difference.Id                = "2_difference";
            }


            this.Plot1 = new NPlotEngine.NPlotEngine(PlotEngineType.Synchronous)
            {
                Title = "Rohdaten des Probenspektrums"
            };
            this.Plot1.AddDataSet(this.Original);
            this.Plot1.XLabel = "Wellenlänge / nm";
            this.Plot1.YLabel = "Absorbanz";
            this.Plot1.FitView();
            this.Plot1.ProcessChanges();

            this.Plot2 = new NPlotEngine.NPlotEngine(PlotEngineType.Synchronous)
            {
                Title = "Vergleich von verarbeitetem Probenspektrum und Datenbankeintrag"
            };
            this.Plot2.AddDataSet(this.Backprojection);
            if (this.ReportInfo.IsMatch == true)
                this.Plot2.AddDataSet(this.MatchBackProjection);
            this.Plot2.XLabel = "Wellenlänge / nm";
            this.Plot2.YLabel = "f(Absorbanz)";
            this.Plot2.FitView();
            this.Plot2.ProcessChanges();

            if (this.ReportInfo.ShowDifferencePlot == true && this.ReportInfo.IsMatch == true)
            {
                this.Plot2.UseSecondAxes = true;
                this.Plot2.AddDataSet(this.Difference);
                double min = this.Difference.YMin();
                double max = this.Difference.YMax();
                this.Plot2.YMin = min - 2*(max-min);
                this.Plot2.YMax = max + 2*(max-min);
                this.Plot2.ProcessChanges();
                this.Plot2.YLabel = "Differenz*";
                this.Plot2.ProcessChanges();
            }
        }

        private void SetAustriaPlot()
        {
           
            this.Original.Label         = "Probenspektrum";
            this.Original.Color           = Color.Blue;
            this.Backprojection.Label   = "Rückprojektion des Probenspektrums";
            this.Backprojection.Color   = Color.Blue;
            this.Backprojection.Id      = "0_backprojection";

            if (this.ReportInfo.IsMatch == true)
            {    
                this.MatchBackProjection.Label    = "Rückprojektion des Referenzspektrums";
                this.MatchBackProjection.Color     = Color.Red;
                this.MatchBackProjection.Id       = "1_match";
                this.Difference.Label             = "Differenz der Rückprojektionen*";
                this.Difference.Color             = Color.Green;
                this.Difference.LineStyle         = LineStyle.Dash;
                this.Difference.Id                = "2_difference";
            }


            this.Plot1 = new NPlotEngine.NPlotEngine(PlotEngineType.Synchronous)
            {
                Title = "Rohdaten des Probenspektrums",
                XLabel = "Wellenlänge / nm",
                YLabel = "Absorbanz"
            };
            this.Plot1.AddDataSet(this.Original);
            this.Plot1.FitView();
            this.Plot1.ProcessChanges();

            this.Plot2 = new NPlotEngine.NPlotEngine(PlotEngineType.Synchronous)
            {
                Title = "Vergleich von verarbeitetem Probenspektrum und Datenbankeintrag",
                XLabel = "Wellenlänge / nm",
                YLabel = "f(Absorbanz)"
            };
            this.Plot2.AddDataSet(this.Backprojection);
            if (this.ReportInfo.IsMatch == true)
                this.Plot2.AddDataSet(this.MatchBackProjection);
            this.Plot2.FitView();
            this.Plot2.ProcessChanges();

            if (this.ReportInfo.ShowDifferencePlot == true && this.ReportInfo.IsMatch == true)
            {
                this.Plot2.UseSecondAxes = true;
                this.Plot2.AddDataSet(this.Difference);
                double min = this.Difference.YMin();
                double max = this.Difference.YMax();
                this.Plot2.YMin = min - 2*(max-min);
                this.Plot2.YMax = max + 2*(max-min);
                this.Plot2.ProcessChanges();
                this.Plot2.YLabel = "Differenz*";
                this.Plot2.ProcessChanges();
            }
        }

        private void SetGreatBritainPlot()
        {
            this.Original.Label         = "Sample spectrum";
            this.Original.Color           = Color.Blue;
            this.Backprojection.Label   = "Back-projection of sample spectrum";
            this.Backprojection.Color   = Color.Blue;
            this.Backprojection.Id      = "0_backprojection";

            if (this.ReportInfo.IsMatch == true)
            {    
                this.MatchBackProjection.Label    = "Back-projection of reference spectrum";
                this.MatchBackProjection.Color     = Color.Red;
                this.MatchBackProjection.Id       = "1_match";
                this.Difference.Label             = "Difference of back-projections*";
                this.Difference.Color             = Color.Green;
                this.Difference.LineStyle         = LineStyle.Dash;
                this.Difference.Id                = "2_difference";
            }


            this.Plot1 = new NPlotEngine.NPlotEngine(PlotEngineType.Synchronous)
            {
                Title = "Rawdata of the spectrum",
                XLabel = "Wavelength / nm",
                YLabel = "Absorbance"
            };
            this.Plot1.AddDataSet(this.Original);
            this.Plot1.FitView();
            this.Plot1.ProcessChanges();

            this.Plot2 = new NPlotEngine.NPlotEngine(PlotEngineType.Synchronous)
            {
                Title = "Comparison of processed spectrum and database entry",
                XLabel = "Wavelength / nm",
                YLabel = "f(Absorbance)"
            };
            this.Plot2.AddDataSet(this.Backprojection);
            if (this.ReportInfo.IsMatch == true)
                this.Plot2.AddDataSet(this.MatchBackProjection);
            this.Plot2.FitView();
            this.Plot2.ProcessChanges();

            if (this.ReportInfo.ShowDifferencePlot == true && this.ReportInfo.IsMatch == true)
            {
                this.Plot2.UseSecondAxes = true;
                this.Plot2.AddDataSet(this.Difference);
                double min = this.Difference.YMin();
                double max = this.Difference.YMax();
                this.Plot2.YMin = min - 2*(max-min);
                this.Plot2.YMax = max + 2*(max-min);
                this.Plot2.ProcessChanges();
                this.Plot2.YLabel = "Difference*";
                this.Plot2.ProcessChanges();
            }
        }

        private void SetSwitzerlandPlot()
        {
            this.Original.Label         = "Probenspektrum";
            this.Original.Color           = Color.Blue;
            this.Backprojection.Label   = "Rückprojektion des Probenspektrums";
            this.Backprojection.Color   = Color.Blue;
            this.Backprojection.Id      = "0_backprojection";

            if (this.ReportInfo.IsMatch == true)
            {    
                this.MatchBackProjection.Label    = "Rückprojektion des Referenzspektrums";
                this.MatchBackProjection.Color     = Color.Red;
                this.MatchBackProjection.Id       = "1_match";
                this.Difference.Label             = "Differenz der Rückprojektionen*";
                this.Difference.Color             = Color.Green;
                this.Difference.LineStyle         = LineStyle.Dash;
                this.Difference.Id                = "2_difference";
            }


            this.Plot1 = new NPlotEngine.NPlotEngine(PlotEngineType.Synchronous)
            {
                Title = "Rohdaten des Probenspektrums",
                XLabel = "Wellenlänge / nm",
                YLabel = "Absorbanz"
            };
            this.Plot1.AddDataSet(this.Original);
            this.Plot1.FitView();
            this.Plot1.ProcessChanges();

            this.Plot2 = new NPlotEngine.NPlotEngine(PlotEngineType.Synchronous)
            {
                Title  = "Vergleich von verarbeitetem Probenspektrum und Datenbankeintrag",
                XLabel = "Wellenlänge / nm",
                YLabel = "f(Absorbanz)"
            };
            this.Plot2.AddDataSet(this.Backprojection);
            if (this.ReportInfo.IsMatch == true)
                this.Plot2.AddDataSet(this.MatchBackProjection);
            this.Plot2.FitView();
            this.Plot2.ProcessChanges();

            if (this.ReportInfo.ShowDifferencePlot == true && this.ReportInfo.IsMatch == true)
            {
                this.Plot2.UseSecondAxes = true;
                this.Plot2.AddDataSet(this.Difference);
                double min = this.Difference.YMin();
                double max = this.Difference.YMax();
                this.Plot2.YMin = min - 2*(max-min);
                this.Plot2.YMax = max + 2*(max-min);
                this.Plot2.ProcessChanges();
                this.Plot2.YLabel = "Differenz*";
                this.Plot2.ProcessChanges();
            }
        }

        public void SetI18nPlot()
        {            
            this.Original.Label         = Catalog.GetString("Acquired spectrum");
            this.Original.Color           = Color.Blue;
            this.Backprojection.Label   = Catalog.GetString("Back projection of acquired spectrum");
            this.Backprojection.Color   = Color.Blue;
            this.Backprojection.Id      = "0_backprojection";

            if (this.ReportInfo.IsMatch == true)
            {    
                this.MatchBackProjection.Label    = Catalog.GetString("Back projection of reference spectrum");
                this.MatchBackProjection.Color     = Color.Red;
                this.MatchBackProjection.Id       = "1_match";
                this.Difference.Label = Catalog.GetString("Difference of back projections*");
                this.Difference.Color             = Color.Green;
                this.Difference.LineStyle         = LineStyle.Dash;
                this.Difference.Id                = "2_difference";
            }


            this.Plot1 = new NPlotEngine.NPlotEngine(PlotEngineType.Synchronous)
            {
                XLabel = Catalog.GetString("Wavelength / nm"),
                YLabel = Catalog.GetString("Absorbance")
            };
            this.Plot1.AddDataSet(this.Original);
            this.Plot1.FitView();
            this.Plot1.ProcessChanges();

            this.Plot2 = new NPlotEngine.NPlotEngine(PlotEngineType.Synchronous)
            {
                XLabel = Catalog.GetString("Wavelength / nm"),
                YLabel = Catalog.GetString("f(Absorbance)")
            };
            this.Plot2.AddDataSet(this.Backprojection);
            if (this.ReportInfo.IsMatch == true)
                this.Plot2.AddDataSet(this.MatchBackProjection);
            this.Plot2.FitView();
            this.Plot2.ProcessChanges();

            if (this.ReportInfo.ShowDifferencePlot == true && this.ReportInfo.IsMatch == true)
            {
                this.Plot2.UseSecondAxes = true;
                this.Plot2.AddDataSet(this.Difference);
                double min = this.Difference.YMin();
                double max = this.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();
            }
        }


        public void Dispose()
        {
            ((IDisposable)this.Plot1).Dispose();
            ((IDisposable)this.Plot2).Dispose();
        }

        public IPlotEngine Plot1            {get; private set;}
        public IPlotEngine Plot2            {get; private set;}

        private DataSet MatchBackProjection    {get; set;}
        private DataSet Difference            {get; set;}
        private DataSet Backprojection        {get; set;}
        private DataSet Original            {get; set;}

        private ReportInfo ReportInfo       {get; set;}
    }
}

