#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member

using System;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;

namespace Volpe.Cafe.Utils.Win32Native
{
    /// <summary>
    /// *** WARNING -- USE WITH CAUTION *** <br/>
    /// Use provided wrappers in <see cref="Win32"/> class whenever possible.<br/>
    /// <br/>
    /// Defines unsafe native win32 methods.
    /// </summary>
    [SuppressUnmanagedCodeSecurity]
    public class UnsafeNativeMethods
    {
        /// <summary>
        /// Sends the specified message to a window or windows. The SendMessage function calls the window procedure for
        /// the specified window and does not return until the window procedure has processed the message.
        /// </summary>
        /// <param name="hWnd">
        ///     A handle to the window whose window procedure will receive the message. If this parameter is
        ///     HWND_BROADCAST ((HWND)0xffff), the message is sent to all top-level windows in the system, including
        ///     disabled or invisible unowned windows, overlapped windows, and pop-up windows; but the message is not
        ///     sent to child windows.
        ///     <br/><br/>
        ///     Message sending is subject to UIPI. The thread of a process can send messages only to message queues of
        ///     threads in processes of lesser or equal integrity level.
        /// </param>
        /// <param name="wMsg">The message to be sent.</param>
        /// <param name="wParam">Additional message-specific information.</param>
        /// <param name="lParam">Additional message-specific information.</param>
        /// <returns>
        /// The return value specifies the result of the message processing; it depends on the message sent.
        /// </returns>
        /// <remarks>
        /// For more info see Microsoft docs:<br/>
        /// https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-sendmessage
        /// </remarks>
        [DllImport(ExternDll.User32, CharSet = CharSet.Auto)]
        [ResourceExposure(ResourceScope.None)]
        public static extern int SendMessage(IntPtr hWnd, int wMsg, IntPtr wParam, IntPtr lParam);

        /// <inheritdoc cref="SendMessage(IntPtr, int, IntPtr, IntPtr)"/>
        [DllImport(ExternDll.User32, CharSet = CharSet.Auto)]
        [ResourceExposure(ResourceScope.None)]
        public static extern int SendMessage(IntPtr hWnd, WM wMsg, IntPtr wParam, IntPtr lParam);

        /// <inheritdoc cref="SendMessage(IntPtr, int, IntPtr, IntPtr)"/>
        [DllImport(ExternDll.User32, CharSet = CharSet.Auto)]
        [ResourceExposure(ResourceScope.None)]
        public static extern int SendMessage(IntPtr hWnd, EM wMsg, IntPtr wParam, IntPtr lParam);

        [DllImport(ExternDll.WinMM, CharSet = CharSet.Auto)]
        public static extern int timeBeginPeriod(uint period);
        [DllImport(ExternDll.WinMM, CharSet = CharSet.Auto)]
        public static extern int timeEndPeriod(uint period);

        /// <summary>
        /// Retrieves the device context (DC) for the entire window, including title bar, menus, and scroll bars. A
        /// window device context permits painting anywhere in a window, because the origin of the device context is
        /// the upper-left corner of the window instead of the client area.
        /// </summary>
        /// <param name="hWnd">
        ///     A handle to the window with a device context that is to be retrieved.
        ///     If this value is NULL, GetWindowDC retrieves the device context for the primary display monitor.
        /// </param>
        /// <returns>
        /// If the function succeeds, the return value is a handle to a device context for the specified window.
        /// If the function fails, the return value is NULL, indicating an error or an invalid hWnd parameter.
        /// </returns>
        /// <remarks>
        /// For more info see Microsoft docs:<br/>
        /// https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getwindowdc
        /// </remarks>
        [DllImport(ExternDll.User32, CharSet = CharSet.Auto)]
        [ResourceExposure(ResourceScope.Process)]
        public static extern IntPtr GetWindowDC(IntPtr hWnd);

        /// <summary>
        /// Releases a device context (DC), freeing it for use by other applications. The effect of the ReleaseDC
        /// function depends on the type of DC. It frees only common and window DCs. It has no effect on class or
        /// private DCs.
        /// </summary>
        /// <param name="hWnd">A handle to the window whose DC is to be released.</param>
        /// <param name="hDC">A handle to the DC to be released.</param>
        /// <returns>
        /// The return value indicates whether the DC was released. If the DC was released, the return value is 1.
        /// If the DC was not released, the return value is 0.
        /// </returns>
        /// <remarks>
        /// For more info see Microsoft docs:<br/>
        /// https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-releasedc
        /// </remarks>
        [DllImport(ExternDll.User32, CharSet = CharSet.Auto)]
        [ResourceExposure(ResourceScope.None)]
        public static extern int ReleaseDC(IntPtr hWnd, IntPtr hDC);

    }
}
