// 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.IO;
using System.Reflection;

using Gtk;

using Hiperscan.Common.I18n;
using Hiperscan.Spectroscopy.IdentServer;
using Hiperscan.Unix;


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 static ResultListDialog Start(Gtk.Window parent, Configurations.ReportCountryType country, ApoIdentResultSet result, string test_id)
        {
            return new ResultListDialog(parent, country, result, test_id);
        }


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

            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.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, Configurations.ReportCountryType country, ApoIdentResultSet result, string test_id)
        {
            try
            {
                RankingList.Generic ranking_list= null;
                switch (country)
                {

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

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

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

                    case Configurations.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);

            Uri uri = new Uri("file://" + path.Replace("\\", "/"));
            Console.WriteLine("Open URI: " + uri);
            
            try
            {
                if (File.Exists(path) == false)
                    throw new Exception(String.Format(Catalog.GetString("Cannot find file '{0}'."), path));
                Process.OpenUri(uri);
            }
            catch (Exception ex)
            {
                string message = String.Format(Catalog.GetString("Cannot open ULR '{0}': {1}"),
                                              uri, ex.Message);

                MessageDialog mdlg = new MessageDialog(parent,
                                                       DialogFlags.Modal,
                                                       Gtk.MessageType.Error,
                                                       ButtonsType.Ok,
                                                       message)
                {
                    IconList = ApoIdentStock.FinderIcons
                };
                mdlg.Run();
                mdlg.Destroy();  
                Console.WriteLine("Erro while showing help for result list: {0}.", message);
            }
        }
    }
}
