using System;
using System.Drawing;
using System.Windows.Forms;

namespace GFATask
{
    public partial class Hooks
    {
        #region Mouse
        public static void Mouse_Up(MouseHook.MSLLHOOKSTRUCT mousestruct)
        {
            //Rectangle scaledbounds = new Rectangle((int)(Forms.Main.DesktopBounds.X * Win32API.GetScalingFactor(Screen.FromControl(Forms.Main))), (int)(Forms.Main.DesktopBounds.Y * Win32API.GetScalingFactor(Screen.FromControl(Forms.Main))), (int)(Forms.Main.Width * Win32API.GetScalingFactor(Screen.FromControl(Forms.Main))), (int)(Forms.Main.Height * Win32API.GetScalingFactor(Screen.FromControl(Forms.Main))));
            Rectangle scaledbounds = new Rectangle((int)(Forms.Main.DesktopBounds.X), (int)(Forms.Main.DesktopBounds.Y), (int)(Forms.Main.Width), (int)(Forms.Main.Height));
            //Rectangle scaledbounds = new Rectangle((int)(Forms.Main.Bounds.X * Win32API.GetScalingFactor(Screen.FromControl(Forms.Main))), (int)(Forms.Main.Bounds.Y * Win32API.GetScalingFactor(Screen.FromControl(Forms.Main))), (int)(Forms.Main.Width * Win32API.GetScalingFactor(Screen.FromControl(Forms.Main))), (int)(Forms.Main.Height * Win32API.GetScalingFactor(Screen.FromControl(Forms.Main))));
            Rectangle scaledappgroupbounds = new Rectangle((int)(Forms.AppButtonGroup.DesktopBounds.X * Win32API.GetScalingFactor(Screen.FromControl(Forms.AppButtonGroup))), (int)(Forms.AppButtonGroup.DesktopBounds.Y * Win32API.GetScalingFactor(Screen.FromControl(Forms.AppButtonGroup))), (int)(Forms.AppButtonGroup.Width * Win32API.GetScalingFactor(Screen.FromControl(Forms.AppButtonGroup))), (int)(Forms.AppButtonGroup.Height * Win32API.GetScalingFactor(Screen.FromControl(Forms.AppButtonGroup))));
            Rectangle scaledboundswithoutgrip = new Rectangle(scaledbounds.X + Forms.Main.GripSize - Forms.Main.BorderWidth, scaledbounds.Y, scaledbounds.Width - Forms.Main.GripSize, scaledbounds.Height - Forms.Main.GripSize + Forms.Main.BorderWidth);
            bool mouseover = scaledbounds.Contains(mousestruct.Location);
            bool mouseoverappgroup = scaledappgroupbounds.Contains(mousestruct.Location);
            bool countMAX = XObjects.Delay.Count == XObjects.Delay.MaxCounts;

            if (Forms.Main.SysContextMenu.Visible || Forms.Info.Visible || Forms.Settings.Visible || Forms.Groups.Visible || Forms.AppCreator.Visible || Forms.Administration.Visible || XObjects.ContextMenuStrip.Visible)
                return;

            if (Config.User.NecessaryClick)
            {
                if (scaledboundswithoutgrip.Contains(Cursor.Position))
                {
                    XObjects.Delay.Waiting = new Delay.DelayTime(Config.User.NecessaryClick ? 0 : Config.User.Delay.Show, Config.User.Delay.Hide);
                    XObjects.Delay.Increase();
                }
            }

            if (!mouseoverappgroup && Forms.AppButtonGroup.Visible)
            {
                Forms.AppButtonGroup.Hide();
                if (!mouseover)
                {
                    XObjects.Delay.Decrease();
                }
            }
            else if (!mouseover && Forms.Main.SysContextMenu.Visible)
                XObjects.Delay.Decrease();
        }

        public static void Mouse_Move(MouseHook.MSLLHOOKSTRUCT mousestruct)
        {
            if (XObjects.PausedDelay || Forms.Main.SysContextMenu.Visible || Forms.Info.Visible || Forms.AppButtonGroup.Visible || Forms.Settings.Visible || Forms.Groups.Visible || Forms.AppCreator.Visible || Forms.Administration.Visible || XObjects.ContextMenuStrip.Visible)
                return;

            // Wegen unbekannter Probleme versetzt sich der GFATask willkürlich in den Hintergrund. 
            // Bei jeder Mausbewegung wird der GFATask sofort wieder an oberste Ebene versetzt, sodass er über allen anderen Fenstern steht.
            Win32API.SetWindowPos(Forms.Main.Handle, HWDN.TOPMOST, 0, 0, 0, 0, SWP.NOSIZE | SWP.NOMOVE);

            //Rectangle scaledbounds = new Rectangle((int)(Forms.Main.DesktopBounds.X * Win32API.GetScalingFactor(Screen.FromControl(Forms.Main))), (int)(Forms.Main.DesktopBounds.Y * Win32API.GetScalingFactor(Screen.FromControl(Forms.Main))), (int)(Forms.Main.Width * Win32API.GetScalingFactor(Screen.FromControl(Forms.Main))), (int)(Forms.Main.Height * Win32API.GetScalingFactor(Screen.FromControl(Forms.Main))));
            Rectangle scaledbounds = new Rectangle((int)(Forms.Main.DesktopBounds.X), (int)(Forms.Main.DesktopBounds.Y), (int)(Forms.Main.Width), (int)(Forms.Main.Height));

            // Hier muss Cursor.Position angewendet werden, da die HookStruct-Position der Maus die Bewegung angibt und nicht an welchem Punkt sich die Maus aktuell auf dem Desktop befindet
            bool mouseover = scaledbounds.Contains(Cursor.Position);
            bool mouseover_withoutgrip = new Rectangle(scaledbounds.X + Forms.Main.GripSize - Forms.Main.BorderWidth, scaledbounds.Y, scaledbounds.Width - Forms.Main.GripSize, scaledbounds.Height - Forms.Main.GripSize + Forms.Main.BorderWidth).Contains(Cursor.Position);
            bool countMIN = XObjects.Delay.Count >= -1 && XObjects.Delay.Count <= 0;
            bool countMAX = XObjects.Delay.Count >= XObjects.Delay.MaxCounts;
            Delay.Prevent direction = XObjects.Delay.IsProcessing;

            // BUGFIX: Wenn der Mauszeiger kurz außerhalb des GFA-Task ist und sofort wieder einspringt, wird dieser nicht ausgeblendet
            if (mouseover && countMAX && !countMIN && direction == Delay.Prevent.Decrease)
            {
                XObjects.Delay.Waiting = new Delay.DelayTime(Config.User.NecessaryClick ? 0 : Config.User.Delay.Show, Config.User.Delay.Hide);
                XObjects.Delay.Increase();
            }
            // Wenn der Mausklick zum Einblenden benötigt wird, der Mauszeiger sich innerhalb des sichtbaren Fensters befindet und kein Delay durchgeführt wird
            else if (!Config.User.NecessaryClick && mouseover_withoutgrip && countMIN && direction == Delay.Prevent.None)
            {
                XObjects.Delay.Waiting = new Delay.DelayTime(Config.User.NecessaryClick ? 0 : Config.User.Delay.Show, Config.User.Delay.Hide);
                XObjects.Delay.Increase();
            }
            // Wenn der Mauszeiger nicht über dem GFA-Task ist, dieser komplett eingeblendet ist und kein Delay durchgeführt wird
            else if (!mouseover && countMAX && direction == Delay.Prevent.None)
            {
                XObjects.Delay.Decrease();
            }
            // Wenn der kein Mausklick zum Einblenden benötigt wird, der Mauszeiger sich innerhalb des GFA-Task befindet, dieser komplett eingeblendet ist und der Delay ausblendet
            else if (!Config.User.NecessaryClick && mouseover && countMAX && direction == Delay.Prevent.Decrease)
            {
                XObjects.Delay.Waiting = new Delay.DelayTime(Config.User.NecessaryClick ? 0 : Config.User.Delay.Show, Config.User.Delay.Hide);
                XObjects.Delay.Increase();
            }
            // Wenn der Mauszeiger sich nicht innerhalb des GFA-Task befindet, dieser komplett ausgeblendet ist und der Delay einblendet
            else if (!mouseover && countMIN && direction == Delay.Prevent.Increase)
            {
                XObjects.Delay.Decrease();
            }
            // Wenn der Mauszeiger sich innerhalb des sichtbaren Fensters befindet, der GFA-Task weder komplett ein- noch ausgeblendet ist und der GFA-Task sich im Ausblendprozess befindet
            else if (mouseover_withoutgrip && !countMIN && !countMAX && direction == Delay.Prevent.Decrease)
            {
                XObjects.Delay.Waiting = new Delay.DelayTime(0, Config.User.Delay.Hide);
                XObjects.Delay.Increase();
            }
            // Wenn der Mauszeiger nicht über dem GFA-Task ist, der GFA-Task weder komplett ein- noch ausgeblendet ist und der GFA-Task sich im Einblendprozess befindet
            else if (!mouseover && !countMIN && !countMAX && direction == Delay.Prevent.Increase)
            {
                XObjects.Delay.Decrease();
            }
        }

        #endregion


        #region KeyBoard
        public static void KeyBoard_Intercept_KeyPress(object sender, HotKeyEventArgs e)
        {
            var applist = Accessor.GetAppList(AppType.Menu);

            if (e.Modifier == Modifier.CTRL)
            {
                if (e.Key == Keys.F1)
                {
                    SystemApps.Info(out _);
                }
                if (e.Key == Keys.F2)
                {
                    SystemApps.Settings(out _);
                }
                if (e.Key == Keys.F3)
                {
                    SystemApps.Administration(out _);
                }
            }
        }
        #endregion
    }
}
