using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.Marshalling;
using Microsoft.Win32.SafeHandles;

[assembly: DisableRuntimeMarshalling]

namespace PresenterConsole;

public static partial class WindowsFFI
{
  [StructLayout(LayoutKind.Sequential)]
  public struct Coord(short parX, short parY)
  {
    public short X = parX;
    public short Y = parY;
  }

  [StructLayout(LayoutKind.Explicit)]
  public struct CharUnion
  {
    [FieldOffset(0)] public char UnicodeChar;
    [FieldOffset(0)] public byte AsciiChar;
  }

  [StructLayout(LayoutKind.Explicit)]
  public struct CharInfo
  {
    [FieldOffset(0)] public CharUnion Char;
    [FieldOffset(2)] public short Attributes;
  }

  [StructLayout(LayoutKind.Sequential)]
  public struct SmallRect
  {
    public short Left;
    public short Top;
    public short Right;
    public short Bottom;
  }

  [LibraryImport("kernel32.dll", SetLastError = true, EntryPoint = "CreateFileW")]
  public static partial SafeFileHandle CreateFile(
    [MarshalAs(UnmanagedType.LPWStr)] string parFileName,
    uint parFileAccess,
    uint parFileShare,
    IntPtr parSecurityAttributes,
    FileMode parCreationDisposition,
    int parFlags,
    IntPtr parTemplate
  );

  [LibraryImport("kernel32.dll", SetLastError = true, EntryPoint = "WriteConsoleOutputW")]
  [return: MarshalAs(UnmanagedType.Bool)]
  public static partial bool WriteConsoleOutput(
    SafeFileHandle parHConsoleOutput,
    [MarshalUsing(CountElementName = nameof(parDwBufferSize))]
    CharInfo[] parLpBuffer,
    Coord parDwBufferSize,
    Coord parDwBufferCoord,
    ref SmallRect parLpWriteRegion
  );

  [LibraryImport("user32.dll", SetLastError = true, EntryPoint = "GetKeyboardState")]
  [return: MarshalAs(UnmanagedType.Bool)]
  public static partial bool GetKeyboardState(byte[] parKeyboardState);

  [LibraryImport("user32.dll", SetLastError = true, EntryPoint = "GetAsyncKeyState")]
  public static partial short GetAsyncKeyState(int parKeyCode);
}