// Created with MonoDevelop
//
//    QuickStep: Acquire, view and identify spectra 
//    Copyright (C) 2022, 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 Hiperscan.ApoIdentCore;

namespace Hiperscan.Extensions.ApoIdent
{
    public partial class ApoIdentApplication
    {
        private void InitMainWindow()
        {
            this.MainWindow.IconList = ApoIdentStock.FinderIcons;
            this.MainWindow.Title = "QuickStep " + ApoIdentInfo.NAME + " " + this.Host.MainWindowTitelExtension;

            ApoIdent.ApoIdentApplication.SetWmcClassName(this.MainWindow);

            this.MainWindow.ExposeEvent += this.OnDrawBackgroundImage;
            this.MainWindow.DeleteEvent += (o, args) =>
            {
                args.RetVal = true;
                this.Control.ExitApplicationByUser();
            };

            this.MainWindow.Realized += (sender, e) => this.SetWindowToFront(false);
            this.MainWindow.Realized += (sender, e) => this.MainWindow.QueueDraw();
            this.MainWindow.SizeRequested += (sender, e) => this.MainWindow.QueueDraw();
            this.MainWindow.FocusInEvent += this.OnMainWindowScanFocusedIn;
            this.MainWindow.FocusOutEvent += this.OnMainWindowScanFocusedOut;
        }

        private void SetWindowToFront(bool close_app)
        {
            if (Environment.OSVersion.Platform != PlatformID.Win32NT)
                return;

            try
            {
                string file = Assembly.GetExecutingAssembly().Location;
                file = Path.GetDirectoryName(file);
                file = Path.Combine(file, "ShowApoIdent.exe");
                System.Diagnostics.Process set_to_front = new System.Diagnostics.Process();
                set_to_front.StartInfo.FileName = file;
                set_to_front.StartInfo.CreateNoWindow = true;
                set_to_front.StartInfo.UseShellExecute = false;
                set_to_front.Start();
                set_to_front.WaitForExit();

                if (close_app)
                    Plugin.host.Quit();
            }
            catch (Exception)
            {
                if (close_app)
                    Environment.Exit(-2);
            }
        }

        private void CheckForRunningApoIdentInstances()
        {
            try
            {
                if (Environment.OSVersion.Platform != PlatformID.Win32NT)
                    return;

                if (Plugin.replace_gui == false)
                    return;


                System.Diagnostics.Process[] processes = System.Diagnostics.Process.GetProcessesByName("QuickStep");
                Console.WriteLine("Found {0} processes", processes.Length);

                System.Diagnostics.Process current_process = System.Diagnostics.Process.GetCurrentProcess();

                DateTime date = DateTime.MaxValue;
                System.Diagnostics.Process winner = null;

                foreach (System.Diagnostics.Process process in processes)
                {
                    if (process.StartTime < date)
                    {
                        date = process.StartTime;
                        winner = process;
                    }

                    if (current_process.Id == process.Id)
                        Console.WriteLine("This process started at: {0}", process.StartTime);
                    else
                        Console.WriteLine("The other process started at: {0}", process.StartTime);
                }

                if (current_process.Id != winner.Id)
                    this.SetWindowToFront(true);
            }
            catch (Exception ex)
            {
                Console.WriteLine("Error while checking instances: {0}", ex);
            }
        }

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

            if (win == null)
                return;

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

            double scal_x = (double)this.MainWindow.Allocation.Width /
                                        this.GuiDesigner.BackGround.Width;
            double scal_y = (double)this.MainWindow.Allocation.Height /
                                        this.GuiDesigner.BackGround.Height;

            Cairo.Context ctx = Gdk.CairoHelper.Create(win);

            ctx.Rectangle(0, 0, this.MainWindow.Allocation.Width, this.MainWindow.Allocation.Height);
            ctx.SetSourceColor(new Cairo.Color(1, 1, 1));
            ctx.Fill();

            double y_pos = 36.0 / 100 / scal_y * this.MainWindow.Allocation.Height;

            ctx.Scale(scal_x, scal_y);
            this.GuiDesigner.BackGround.Show(ctx, 0, y_pos);


            ((IDisposable)ctx.GetTarget()).Dispose();
            ((IDisposable)ctx).Dispose();
        }

        private Gtk.Window GetTmpWindow()
        {
            Gtk.Window window = new Gtk.Window("Invisible");
            window.Visible = false;
            window.Decorated = false;
            window.SetPosition(Gtk.WindowPosition.CenterAlways);
            window.NoShowAll = true;
            window.WidthRequest = 1;
            window.HeightRequest = 1;
            window.Show();
            window.Opacity = 0;
            window.KeepAbove = true;
            window.Present();

            return window;
        }

        private void OnMainWindowScanFocusedIn(object sender, EventArgs args)
        {
            this.Control.GlobalStates.IsTopLevelWindow = true;
        }

        private void OnMainWindowScanFocusedOut(object sender, EventArgs args)
        {
            this.Control.GlobalStates.IsTopLevelWindow = false;
        }

        public static void SetWmcClassName(Gtk.Window window)
        {
            window.SetWmclass(ApoIdentInfo.NAME.ToLower(), ApoIdentInfo.NAME.ToLower());
        }
    }
}
