// Created with MonoDevelop
//
//    QuickStep: Acquire, view and identify spectra 
//    Copyright (C) 2018 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.Threading;
using Gtk;
using Hiperscan.Common;
using Hiperscan.Unix;
using HollyLibrary;
using Glade;
using System.Text.RegularExpressions;

namespace Hiperscan.Extensions.ApoIdent
{
    public partial class FinderWindow
    {
        private void InitializeFinderWindow()
        {
            Console.WriteLine("\tFinderWindow...");

            if (ApoIdentEnvs.TouchScreenModeOn)
                TouchscreenMode.InitTouchRCStyles();
         
            FinderWindow.current_instance = this;
            Glade.XML gui = new Glade.XML(null, "ApoIdent.Resources.Glade.FinderWindow.glade", "finder_window", "Hiperscan");
            gui.Autoconnect(this);

            this.CurrentTopLeveLWindow      = this;

			this.quickstep_button.StockId   = ApoIdentStock.QUICKSTEP;
			this.empty_image.Stock          = ApoIdentStock.START;
			this.start_image.Stock          = ApoIdentStock.START;
            this.finder_window.IconList     = ApoIdentStock.FinderIcons;
            this.finder_window.Title = "QuickStep " + Plugin.name + " " + this.host.MainWindowTitelExtension;

            this.empty_die_label.ModifyFg(Gtk.StateType.Normal, new Gdk.Color(209, 32,35));
            this.start_label.ModifyFg(Gtk.StateType.Normal, new Gdk.Color(209, 32,35));

            this.finder_window.SetWmclass(Plugin.name.ToLower(), 
                                          Plugin.name.ToLower());

            this.summarized_info_linkbutton.HasTooltip = false;
                                           
            CellRendererSubstanceCategory.Init();
            CellRendererInfo.Init();
            this.InitBackgroundImage();
            this.InitializeRegexEntries();
            this.InitHelpMenue();
            this.InitExpiryDateComboboxes();
            this.SetWindowSize();
            this.InitSubstanceSearchEntry();

            this.GtkUsernameValue = this.Config.GuiSettings.LastUser;
            this.GtkSupplierValue = this.Config.GuiSettings.LastSupplier;

            this.finder_window.Shown += this.OnFinderWindowShown; 
            this.finder_window.ExposeEvent += this.OnDrawBackgroundImage;
            this.finder_table.SizeAllocated += this.OnDrawMainArea;

            this.finder_window.ShowAll();

            if (ApoIdentEnvs.TouchScreenModeOn)
                this.IntitializeTouchscreenMode();
        }
      
        private void SetWindowSize()
        {
            if (this.Config.GuiSettings.WindowMaximized == true)
            {
                this.finder_window.Maximize();
            }
            else
            {
                if (this.Config.GuiSettings.WindowWidth > 0)
                {
                    this.finder_window.DefaultWidth  = this.Config.GuiSettings.WindowWidth;
                    this.finder_window.DefaultHeight = this.Config.GuiSettings.WindowHeight;
                }
            }
        }



        private void InitializeRegexEntries()
        {

			this.user_regexentry = new RegexEntry(ApoIdentStock.TRANSPARENCY, Stock.DialogWarning);
            this.user_alignment.Child = this.user_regexentry;
            this.user_regexentry.Entry.MaxLength = 75;
            this.user_regexentry.Regex = new Regex(@"\w{1}");
            this.user_regexentry.ErrorMessage =  Catalog.GetString("This input field is mandatory.");
            this.user_regexentry.Entry.Changed += OnUserReportInfoChanged;

			this.supplier_regexentry = new RegexEntry(ApoIdentStock.TRANSPARENCY, Stock.DialogWarning);
            this.supplier_alignment.Child = this.supplier_regexentry;
            this.supplier_regexentry.Entry.MaxLength = 75;
            this.supplier_regexentry.Regex = new Regex(@"\w{1}");
            this.supplier_regexentry.ErrorMessage =  Catalog.GetString("This input field is mandatory.");
            this.supplier_regexentry.Entry.Changed += this.OnSupplierReportInfoChanged;

			this.pzn_regexentry = new RegexEntry(ApoIdentStock.TRANSPARENCY, Stock.DialogWarning);
            this.pzn_alignment.Child = this.pzn_regexentry;
            this.pzn_regexentry.Entry.MaxLength = 35;
            this.pzn_regexentry.Regex = new Regex(@"(^(\d{1}[- ]?){6,17}\d{1}$)|(^.{0}$)");
            this.pzn_regexentry.ErrorMessage = Catalog.GetString("The correct input for this field is a number with 7-18 digits.");
            this.pzn_regexentry.Entry.Changed += this.OnPznReportInfoChanged;

			this.corr_fac_regexentry = new RegexEntry(ApoIdentStock.TRANSPARENCY, Stock.DialogWarning);
            this.corr_fac_alignment.Child = this.corr_fac_regexentry;
            this.corr_fac_regexentry.Entry.MaxLength = 20;
             this.corr_fac_regexentry.Entry.Changed += this.OnCorrFacReportInfoChanged;

			this.batch_regexentry = new RegexEntry(ApoIdentStock.TRANSPARENCY, Stock.DialogWarning);
            this.batch_alignment.Child = batch_regexentry;
            this.batch_regexentry.Entry.MaxLength = 20;
            this.batch_regexentry.Regex = new Regex(@"\w{1}");
            this.batch_regexentry.ErrorMessage = Catalog.GetString("This input field is mandatory.");
            this.batch_regexentry.Entry.Changed += this.OnBatchReportInfoChanged;

			this.comment_regentry = new RegexEntry(ApoIdentStock.TRANSPARENCY, ApoIdentStock.TRANSPARENCY);
            this.comment_alignment.Child = this.comment_regentry;
            this.comment_regentry.Entry.MaxLength = 150;
            this.comment_regentry.Entry.Changed += this.OnCommentReportInfoChanged;

            this.batch_regexentry.Entry.FocusOutEvent += (sender, e) =>
            {
                this.OldBatchNumber = this.GtkBatchValue; 
            };

            this.InitializeEntryCompletion();
        }
            
        private void InitExpiryDateComboboxes()
        {
            ListStore store = new ListStore(typeof(string));
            CellRendererText text = new CellRendererText();
            this.expiry_date_year_combo.Clear();
            this.expiry_date_year_combo.PackStart(text, false);
            this.expiry_date_year_combo.SetAttributes(text, "text", 0);
            this.expiry_date_year_combo.Model = store;

            this.expiry_date_year_combo.AppendText("-");
            for (int ix=0; ix < 12; ++ix)
            {
                this.expiry_date_year_combo.AppendText((DateTime.Now.Year + ix).ToString());
            }

            this.expiry_date_month_combo.Active = 0;
            this.expiry_date_year_combo.Active = 0;
        }

        private void InitSubstanceSearchEntry()
        {
            Console.WriteLine("Init auto completion substance search entry ...");
            InlineEntryCompletion completion = new InlineEntryCompletion();

            CellRendererSubstanceCategory substance_cell  = new CellRendererSubstanceCategory();
            substance_cell.Xpad = 5;

            Gtk.CellRendererText text_cell = new Gtk.CellRendererText();
            text_cell.Xpad = 5;

            completion.PackStart(substance_cell, false);
            completion.AddAttribute(substance_cell, CellRendererSubstanceCategory.GLIB_PROPERTY, 0);

            completion.PackStart(text_cell, false);     
            completion.TextColumn = 1;

            completion.MatchFunc = this.MatchSpecimen;

            ListStore store = new ListStore(typeof(SubstanceCategory), typeof(string), typeof(SubstanceListAutoCompletionEntry));
            completion.Model = store;
            completion.InlineSelection = false;
            this.substance_search_entry.Completion = completion;
        }



        private void OnFinderWindowShown(object sender, EventArgs e)
        {
            this.SetScrollBars();
            this.InitApoIdentDesign();
            this.InitAnimationViewport();
            this.AdjustConfigSection();
        }

        private void InitApoIdentDesign()
        {
            this.design_left_viewport.ModifyBg(StateType.Normal, HIPERSCAN_RED);
            this.design_right_viewport.ModifyBg(StateType.Normal, HIPERSCAN_RED);
            this.design_top_viewport.ModifyBg(StateType.Normal, HIPERSCAN_RED);
            this.design_bottom_viewport.ModifyBg(StateType.Normal, HIPERSCAN_RED);
            this.tool_design_viewport.ModifyBg(StateType.Normal, HIPERSCAN_RED);

            this.lhs_toolbar.ModifyBg(StateType.Normal, HIPERSCAN_RED);

            this.main_viewport.ModifyBg(StateType.Normal, HIPERSCAN_WHITE);
            this.tool_viewport.ModifyBg(StateType.Normal, HIPERSCAN_WHITE);
            this.status_viewport.ModifyBg(StateType.Normal, HIPERSCAN_WHITE);
            this.result_viewport.ModifyBg(StateType.Normal, HIPERSCAN_WHITE);

            this.DefaultEntryBgColor    = this.substance_search_entry.Style.Base(StateType.Normal);
            this.NotMeasurableColor     = new Gdk.Color(255, 192, 192);
            this.ClassificationColor    = new Gdk.Color(255, 255, 128);
            this.MeasurableColor        = new Gdk.Color(192, 255, 192);
            this.UserDefinedColor       = new Gdk.Color(192, 192, 192);
        }



        private void SetScrollBars()
        {
            this.main_scrolledwindow.VscrollbarPolicy = PolicyType.Never;
            this.main_scrolledwindow.HscrollbarPolicy = PolicyType.Never;

            if (this.finder_window.GdkWindow.Screen.Height < WindowSize.MIN_RESOLUTION_HEIGHT)
            {
                this.main_scrolledwindow.VscrollbarPolicy = PolicyType.Automatic;
            }

            if (this.finder_window.GdkWindow.Screen.Width < WindowSize.MIN_RESOLUTION_WIDTH)
            {
                this.main_alignment.Xscale = 1;
                this.main_scrolledwindow.HscrollbarPolicy = PolicyType.Automatic;
            }
        }


        private void AdjustConfigSection()
        {
            int max_width = this.config_label_button.Allocation.Width;

            if (this.class_label_button.Allocation.Width > max_width)
                max_width = this.class_label_button.Allocation.Width;

            if (this.substance_name_label_button.Allocation.Width > max_width)
                max_width = this.substance_name_label_button.Allocation.Width;

            if (this.latin_name_label_button.Allocation.Width > max_width)
                max_width = this.latin_name_label_button.Allocation.Width;

            this.config_label_button.WidthRequest           = max_width;
            this.class_label_button.WidthRequest            = max_width;
            this.substance_name_label_button.WidthRequest   = max_width;
            this.latin_name_label_button.WidthRequest       = max_width;

            this.config_alignment.WidthRequest = this.data_exchange_alignment.Allocation.Width;
        }

        private void InitAnimationViewport()
        {
            if (this.lhs_toolbar.Allocation.Width > 40 && this.FinderAnimation == null)
            {
                this.FinderAnimation = new Animation(this.design_drawingarea, 
                                                     this.design_button, 
                                                     this.animation_align, 
                                                     this.lhs_toolbar.Allocation.Width);
            }
        }

        private void InitBackgroundImage()
        {
            this.BackgroundImgage = new Gdk.Pixbuf(Assembly.GetExecutingAssembly(), "ApoIdent.Resources.Images.background.png");

            this.BackgroundSurface = new Cairo.ImageSurface(this.BackgroundImgage.Pixels, 
                                   Cairo.Format.ARGB32, 
                                   this.BackgroundImgage.Width, 
                                   this.BackgroundImgage.Height, 
                                   this.BackgroundImgage.Rowstride);
        }

        private void OnDrawBackgroundImage(object sender, EventArgs e)
        {
            Gdk.Window win = this.finder_window.GdkWindow;

            if (win == null)
                return;

            if(this.finder_window.Allocation.Width <= 1 || this.finder_window.Allocation.Height <= 1)
                return;

            Cairo.Context ctx = Gdk.CairoHelper.Create(win);
            ctx.Scale((double)this.finder_window.Allocation.Width / this.BackgroundImgage.Width,
                      (double)this.finder_window.Allocation.Height / this.BackgroundImgage.Height);
            this.BackgroundSurface.Show(ctx, 0, 0);
            ((IDisposable) ctx.GetTarget()).Dispose();                                      
            ((IDisposable) ctx).Dispose();
        }

        private void OnDrawMainArea(object sender, EventArgs e)
        {
            this.main_viewport.HeightRequest = this.finder_table.Allocation.Height;
            this.main_viewport.HeightRequest = -1;
            this.scroll_viewport.WidthRequest = this.finder_table.Allocation.Width;
            this.scroll_viewport.WidthRequest = -1;
        }
            

        private void InitializeGreetingWindow()
        {
            if (ApoIdentEnvs.SplashOn)
                this.greeting_window = new GreetingWindow(this);
        }

        private void ShowGreetingWindow()
        {
            if (this.greeting_window != null)
            {
                this.greeting_window.ShowAll();
                this.host.ProcessEvents();
                Thread.Sleep(50);
                this.host.ProcessEvents();               
            }
        }

        private void HideGreetingWindow()
        {
            if (this.greeting_window != null)
                this.greeting_window.HideAll();
        }

        private Gdk.Pixbuf BackgroundImgage             {get; set;}
        private Cairo.ImageSurface BackgroundSurface    {get; set;} 
    }
}
