using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Windows;
using System.Windows.Interop;

namespace com.muldersoft.slunkcrypt.gui.utils
{
    public static class WindowHelper
    {
        private static readonly IEnumerable<bool> enableTopmost = Array.AsReadOnly(new bool[] { true, false });

        public static void BringWindowToTop(this Window window)
        {
            if (!ReferenceEquals(window, null))
            {
                try
                {
                    WindowInteropHelper interopHelper = new WindowInteropHelper(window);
                    NativeMethods.BringWindowToTop(interopHelper.Handle);
                    if (!NativeMethods.SetForegroundWindow(interopHelper.Handle))
                    {
                        foreach (bool flag in enableTopmost)
                        {
                            window.Topmost = flag;
                        }
                    }
                }
                catch { }
            }
        }

        public static void DisableMaximizeButton(this Window window)
        {
            if (!ReferenceEquals(window, null))
            {
                const int GWL_STYLE = -16;
                const ulong WS_MAXIMIZEBOX = 0x10000;
                try
                {
                    WindowInteropHelper interopHelper = new WindowInteropHelper(window);
                    ulong value = NativeMethods.GetWindowLongPtr(interopHelper.Handle, GWL_STYLE);
                    if (value != 0UL)
                    {
                        NativeMethods.SetWindowLongPtr(interopHelper.Handle, GWL_STYLE, value & (~WS_MAXIMIZEBOX));
                    }
                }
                catch { }
            }
        }

        private static class NativeMethods
        {
            private const string DLL_USER32 = "user32.dll";

            [DllImport(DLL_USER32, CharSet = CharSet.Unicode, EntryPoint = "BringWindowToTop", ExactSpelling = true)]
            public static extern bool BringWindowToTop(IntPtr hWnd);

            [DllImport(DLL_USER32, CharSet = CharSet.Unicode, EntryPoint = "SetForegroundWindow", ExactSpelling = true)]
            public static extern bool SetForegroundWindow(IntPtr hWnd);

            [DllImport(DLL_USER32, CharSet = CharSet.Unicode, EntryPoint = "GetWindowLongW", ExactSpelling = true)]
            private static extern UIntPtr GetWindowLongPtr32(IntPtr hWnd, int nIndex);

            [DllImport(DLL_USER32, CharSet = CharSet.Unicode, EntryPoint = "GetWindowLongPtrW", ExactSpelling = true)]
            private static extern UIntPtr GetWindowLongPtr64(IntPtr hWnd, int nIndex);

            [DllImport(DLL_USER32, CharSet = CharSet.Unicode, EntryPoint = "SetWindowLongW", ExactSpelling = true)]
            private static extern UIntPtr SetWindowLongPtr32(IntPtr hWnd, int nIndex, UIntPtr dwNewLong);

            [DllImport(DLL_USER32, CharSet = CharSet.Unicode, EntryPoint = "SetWindowLongPtrW", ExactSpelling = true)]
            private static extern UIntPtr SetWindowLongPtr64(IntPtr hWnd, int nIndex, UIntPtr dwNewLong);

            public static ulong GetWindowLongPtr(IntPtr hWnd, int nIndex)
            {
                if (IntPtr.Size >= 8)
                {
                    return GetWindowLongPtr64(hWnd, nIndex).ToUInt64();
                }
                else
                {
                    return GetWindowLongPtr32(hWnd, nIndex).ToUInt64();
                }
            }

            public static void SetWindowLongPtr(IntPtr hWnd, int nIndex, ulong dwNewLong)
            {
                if (IntPtr.Size >= 8)
                {
                    SetWindowLongPtr64(hWnd, nIndex, new UIntPtr(dwNewLong));
                }
                else
                {
                    SetWindowLongPtr32(hWnd, nIndex, new UIntPtr(dwNewLong));
                }
            }
        }
    }
}
