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

using Hiperscan.Spectroscopy;
using Hiperscan.Spectroscopy.IdentModule;
using Hiperscan.Unix;
using Hiperscan.I18n;


namespace Hiperscan.Extensions.ApoIdent
{

	public class ResultListTv : Gtk.TreeView
	{
		public delegate void DoubleClickedHandler(ResultListTv tv);
		public event         DoubleClickedHandler DoubleClicked;


		public ResultListTv() : base() {}

		protected override bool OnButtonPressEvent(Gdk.EventButton e)
		{
			if ((e.Button == 1) && (e.Type == Gdk.EventType.TwoButtonPress) && (this.DoubleClicked != null))
				this.DoubleClicked(this);

			return base.OnButtonPressEvent(e);
		}
	}

	public class ResultListDialog
	{

        public ResultListDialog(Gtk.Window parent, ReportCountryType country, ResultSet result, string test_id)
		{
			Dialog dialog = new Dialog(Catalog.GetString("Identification details"),
				parent, DialogFlags.Modal);

            if (result.IdentficationMode == ResultSet.IdentificationMode.WithSpecifiedSubstanceId)
			    dialog.AddButton(Stock.Help, ResponseType.Help);
			dialog.AddButton(Catalog.GetString("Show as Pdf"), ResponseType.Yes);
			dialog.AddButton(Stock.Close, ResponseType.Close);

			dialog.HasSeparator  = true;
			dialog.HeightRequest = 300;

			ResultListTv tv = new ResultListTv();
			tv.Selection.Mode = SelectionMode.Single;

			ListStore result_list = new ListStore (typeof(string), typeof(string), typeof(string), typeof(string), typeof(string), typeof(string), typeof(string), typeof(string), typeof(int), typeof(string));

			tv.RulesHint = true;
			tv.AppendColumn(Catalog.GetString("Ranking"),        new CellRendererText(), "text", 0, "foreground", 9);
			tv.AppendColumn(Catalog.GetString("Classification"), new CellRendererText(), "text", 1, "foreground", 9);
			tv.AppendColumn(Catalog.GetString("Sample ID"),      new CellRendererText(), "text", 2, "foreground", 9);
			tv.AppendColumn(Catalog.GetString("Significance"),   new CellRendererText(), "text", 3, "foreground", 9);
			tv.AppendColumn(Catalog.GetString("Confidence"),     new CellRendererText(), "text", 4, "foreground", 9);
			tv.AppendColumn(Catalog.GetString("Correlation"),    new CellRendererText(), "text", 5, "foreground", 9);
			tv.AppendColumn(Catalog.GetString("Distance"),       new CellRendererText(), "text", 6, "foreground", 9);
			tv.AppendColumn(Catalog.GetString("Evaluation"),     new CellRendererText(), "text", 7, "foreground", 9);
			
            string first_evaluation = (result.Rating * 100).ToString("f2") + "%";
            bool draw_green = false;
            bool show_number = false;

            if (result.IdentficationMode == ResultSet.IdentificationMode.BlindClassification)
            {
                if (result.ClassificationId != ResultSet.NO_ID && result.PositiveIdentified == true)
                    draw_green = true;

                if (result.ClassificationId != ResultSet.NO_ID)
                    show_number = true;
            }
            else
            {
                if (result.TruePositive == true)
                    draw_green = true;

                if (result.ClassificationMatch == true)
                    show_number = true;
            }
			
            for (int ranking = 0; ranking < result.PcaMatches.Count; ++ranking)
			{
				string color = "red";
                string evaluation = 0.ToString("f2") + "%";

                if (ranking == 0)
                {
                    if (draw_green)
                        color = "darkgreen";

                    if (show_number)
                        evaluation = first_evaluation;
                }

				NormalizedPCAMatch match = result.PcaMatches[ranking];
				result_list.AppendValues((ranking+1).ToString(),
				                         match.ClassificationName,
				                         match.SampleId,
				                         match.Significance.ToString("f4"),
				                         match.Confidence.ToString("f4"),
				                         match.Correlation.ToString("f4"),
				                         match.Distance.ToString("f1"),
				                         evaluation,
				                         ranking,
				                         color);
			}
			
			tv.Model = result_list;

			ScrolledWindow sw = new ScrolledWindow();
			sw.HscrollbarPolicy = PolicyType.Never;
			sw.VscrollbarPolicy = PolicyType.Automatic;
			sw.Add(tv);
			
			dialog.VBox.PackStart(sw);
			sw.ShowAll();
			
			dialog.ActionArea.Children[0].HasFocus = true;
			RankingList.Generic ranking_list = null;

            dialog.IconList = ApoIdentStock.FinderIcons;

			for (;;)
			{
				ResponseType response = (ResponseType) dialog.Run();

				if (response == ResponseType.Help)
				{
					
                    this.ShowHelpPDF("result_list.pdf", parent);
					continue;
				}

				if (response == ResponseType.Yes)
				{
					if (ranking_list != null)
						ranking_list.Delete();
					
                    ranking_list = this.ShowRankingListPdf(parent, country, result, test_id);
					ranking_list.Show();
					continue;
				}
				break;
			}

			dialog.Destroy();

			if (ranking_list != null)
				ranking_list.Delete();
		}

        public RankingList.Generic ShowRankingListPdf(Gtk.Window parent, ReportCountryType country, ResultSet result, string test_id)
		{
			try
			{
				RankingList.Generic ranking_list= null;
                switch (country)
				{

				case ReportCountryType.Germany:
                        ranking_list = new RankingList.Germany(result, test_id);
					break;

				case ReportCountryType.Austria:
                        ranking_list = new RankingList.Austria(result, test_id);
					break;

				case ReportCountryType.Switzerland:
                        ranking_list = new RankingList.Switzerland(result, test_id);
					break;

				case ReportCountryType.GreatBritain:
                        ranking_list = new RankingList.GreatBritain(result, test_id);
					break;

				default:
                        throw new NotImplementedException("Unknown report country: " + country);
				}

				return ranking_list;
			}
			catch(Exception ex)
			{
				string message = String.Format(Catalog.GetString("Cannot show ranking list: {0}"), ex.Message);

                MessageDialog mdlg = new MessageDialog(parent, 
                                                       DialogFlags.Modal,
                                                       Gtk.MessageType.Error, 
                                                       ButtonsType.Ok, 
                                                       message);

                mdlg.IconList = ApoIdentStock.FinderIcons;
				mdlg.Run();
				mdlg.Destroy();  
				Console.WriteLine("Erro while showing  ranking list: {0}.", message);
			}

			return null;
		}
		
        public void ShowHelpPDF(string file_name, Gtk.Window parent)
		{
			
			string path = Path.Combine("Resources", "Pdfs");
            path = Locale.ResourceFileRelativeToAssembly(Assembly.GetExecutingAssembly(), path, file_name, false);

			string url = "file://" + path.Replace("\\", "/");
			Console.WriteLine("Open URL: " + url);
			
			try
			{
				if (File.Exists(path) == false)
					throw new Exception(String.Format(Catalog.GetString("Cannot find file '{0}'."), path));
				System.Diagnostics.Process.Start(url);
			}
			catch(Exception ex)
			{
				string message = String.Format(Catalog.GetString("Cannot open ULR '{0}': {1}"),
					                          url, ex.Message);
				
							MessageDialog mdlg = new MessageDialog(parent, 
                                                                   DialogFlags.Modal,
                                                                   Gtk.MessageType.Error,
                                                                   ButtonsType.Ok,
                                                                   message);

                mdlg.IconList = ApoIdentStock.FinderIcons;
				mdlg.Run();
				mdlg.Destroy();  
				Console.WriteLine("Erro while showing help for result list: {0}.", message);
			}
		}
	}
}
