// 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.GUI.Figure;
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 ReportCountryType.Austria:
					this.SetAustriaPlot();
					break;

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

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

				case 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(PlotEngineType.Synchronous);
            this.Plot1.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(PlotEngineType.Synchronous);
            this.Plot2.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(PlotEngineType.Synchronous);
            this.Plot1.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(PlotEngineType.Synchronous);
            this.Plot2.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 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(PlotEngineType.Synchronous);
			this.Plot1.AddDataSet(this.Original);
            this.Plot1.Title = "Rawdata of the spectrum";
			this.Plot1.XLabel = "Wavelength / nm";
			this.Plot1.YLabel = "Absorbance";
			this.Plot1.FitView();
			this.Plot1.ProcessChanges();

			this.Plot2 = new NPlotEngine(PlotEngineType.Synchronous);
            this.Plot2.Title = "Comparison of processed spectrum and database entry";
			this.Plot2.AddDataSet(this.Backprojection);
            if (this.ReportInfo.IsMatch == true)
				this.Plot2.AddDataSet(this.MatchBackProjection);
			this.Plot2.XLabel = "Wavelength / nm";
			this.Plot2.YLabel = "f(Absorbance)";
			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(PlotEngineType.Synchronous);
            this.Plot1.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(PlotEngineType.Synchronous);
            this.Plot2.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();
			}
		}

		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(PlotEngineType.Synchronous);
			this.Plot1.AddDataSet(this.Original);
			this.Plot1.XLabel = Catalog.GetString("Wavelength / nm");
			this.Plot1.YLabel = Catalog.GetString("Absorbance");
			this.Plot1.FitView();
			this.Plot1.ProcessChanges();

			this.Plot2 = new NPlotEngine(PlotEngineType.Synchronous);
			this.Plot2.AddDataSet(this.Backprojection);
            if (this.ReportInfo.IsMatch == true)
				this.Plot2.AddDataSet(this.MatchBackProjection);
			this.Plot2.XLabel = Catalog.GetString("Wavelength / nm");
			this.Plot2.YLabel = Catalog.GetString("f(Absorbance)");
			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;}
	}
}

