# -*- coding: utf-8 -*-

import ctypes as ct
import sys

from .bindutils import define_function

try:
    if genGL:
        _generation = True
except NameError:
    _generation = False

if sys.maxsize > 2 ** 32:
    arch = '64'
else:
    arch = '32'


def MAKEINTRESOURCE(i):
    return ct.cast(LPVOID(i & 0xFFFF), LPCWSTR)


def LOWORD(lParam):
    return ct.c_int16(lParam & 0xffff).value


def HIWORD(lParam):
    return ct.c_int16(lParam >> 16).value

# Types
INT = ct.c_int
UINT = ct.c_uint
BOOL = INT
FLOAT = ct.c_float
if arch == '64':
    LONG_PTR = ct.c_longlong
    UINT_PTR = ct.c_ulonglong
    ULONG_PTR = ct.c_ulonglong
else:
    LONG_PTR = ct.c_long
    UINT_PTR = UINT
    ULONG_PTR = ct.c_ulong

VOID = None
ULONG = ct.c_ulong
WORD = ct.c_ushort
USHORT = ct.c_ushort
DWORD = ct.c_ulong
LPVOID = PVOID = ct.c_void_p
BYTE = ct.c_ubyte
LPARAM = LONG_PTR
LRESULT = LPARAM
LPARAM = LPARAM
WPARAM = UINT_PTR
WCHAR = ct.c_wchar
CHAR = ct.c_char
SHORT = ct.c_short
TCHAR = ct.c_wchar
LPCSTR = ct.POINTER(ct.c_char)
COLORREF = DWORD
LPCOLORREF = ct.POINTER(DWORD)

# Handles
HANDLE = PVOID
HINSTANCE = HANDLE
HICON = HANDLE
HCURSOR = HANDLE
HMODULE = HANDLE
HBRUSH = HANDLE
HMENU = HANDLE
HWND = HANDLE
HMONITOR = HANDLE
HDC = HANDLE
HGDIOBJ = HANDLE
HGLRC = HANDLE
HENHMETAFILE = HANDLE

LPCWSTR = ct.c_wchar_p
LPCTSTR = LPCWSTR

ATOM = WORD
LONG = ct.c_long

WNDPROC = ct.c_void_p #ct.WINFUNCTYPE(LRESULT, HWND, UINT, WPARAM, LPARAM)

POINTER = ct.POINTER


# Structures
class POINT(ct.Structure):
    _fields_ = [('x', LONG),
                ('y', LONG)]

POINTL = POINT

class WNDCLASS(ct.Structure):
    _fields_ = [('style', UINT),
                ('lpfnWndProc', WNDPROC),
                ('cbClsExtra', INT),
                ('cbWndExtra', INT),
                ('hInstance', HINSTANCE),
                ('hIcon', HICON),
                ('hCursor', HCURSOR),
                ('hbrBackground', HBRUSH),
                ('lpszMenuName', LPCTSTR),
                ('lpszClassName', LPCTSTR)]


class PIXELFORMATDESCRIPTOR(ct.Structure):
    _fields_ = [('nSize', WORD),
                ('nVersion', WORD),
                ('dwFlags', DWORD),
                ('iPixelType', BYTE),
                ('cColorBits', BYTE),
                ('cRedBits', BYTE),
                ('cRedShift', BYTE),
                ('cGreenBits', BYTE),
                ('cGreenShift', BYTE),
                ('cBlueBits', BYTE),
                ('cBlueShift', BYTE),
                ('cAlphaBits', BYTE),
                ('cAlphaShift', BYTE),
                ('cAccumBits', BYTE),
                ('cAccumRedBits', BYTE),
                ('cAccumGreenBits', BYTE),
                ('cAccumBlueBits', BYTE),
                ('cAccumAlphaBits', BYTE),
                ('cDepthBits', BYTE),
                ('cStencilBits', BYTE),
                ('cAuxBuffers', BYTE),
                ('iLayerType', BYTE),
                ('bReserved', BYTE),
                ('dwLayerMask', DWORD),
                ('dwVisibleMask', DWORD),
                ('dwDamageMask', DWORD)]

#def PIXELFORMATDESCRIPTOR():
#    pf = PIXELFORMATDESCRIPTOR_()
#    pf.nSize = ct.sizeof(pf)
#    return pf

class DISPLAY_DEVICE(ct.Structure):
    _fields_ = [('cb', DWORD),
                ('DeviceName', WCHAR*32),
                ('DeviceString', WCHAR*128),
                ('StateFlags', DWORD),
                ('DeviceID', WCHAR*128),
                ('DeviceKey', WCHAR*128)]

class _S(ct.Structure):
    _fields_ = [('dmOrientation', SHORT),
                ('dmPaperSize', SHORT),
                ('dmPaperLength', SHORT),
                ('dmPaperWidth', SHORT)]

class _U(ct.Union):
    _anonymous_ = ('s',)

    _fields_ = [('s', _S),
                ('dmPosition', POINTL)]

class _U2(ct.Union):
    _fields_ = [('dmDisplayFlags', DWORD),
                ('dmNup', DWORD)]

class DEVMODE(ct.Structure):
    _anonymous_ = ('u',
                   'u2')

    _fields_ = [('dmDeviceName', WCHAR*32),
                ('dmSpecVersion', WORD),
                ('dmDriverVersion', WORD),
                ('dmSize', WORD),
                ('dmDriverExtra', WORD),
                ('dmFields', DWORD),
                ('u', _U),
                ('dmScale', SHORT),
                ('dmCopies', SHORT),
                ('dmDefaultSource', SHORT),
                ('dmPrintQuality', SHORT),
                ('dmColor', SHORT),
                ('dmDuplex', SHORT),
                ('dmYResolution', SHORT),
                ('dmTTOption', SHORT),
                ('dmCollate', SHORT),
                ('dmFormName', WCHAR*32),
                ('dmLogPixels', WORD),
                ('dmBitsPerPel', DWORD),
                ('dmPelsWidth', DWORD),
                ('dmPelsHeight', DWORD),
                ('u2', _U2),
                ('dmDisplayFrequency', DWORD),
                ('dmICMMethod', DWORD),
                ('dmICMIntent', DWORD),
                ('dmMediaType', DWORD),
                ('dmDitherType', DWORD),
                ('dmReserved1', DWORD),
                ('dmReserved2', DWORD),
                ('dmPanningWidth', DWORD),
                ('dmPanningHeight', DWORD)]


class RECT(ct.Structure):
    _fields_ = [('left', LONG),
                ('top', LONG),
                ('right', LONG),
                ('bottom', LONG)]

class MONITORINFOEX(ct.Structure):
    _fields_ = [('cbSize', DWORD),
                ('rcMonitor', RECT),
                ('rcWork', RECT),
                ('dwFlags', DWORD),
                ('szDevice',TCHAR*32)]


class MSG(ct.Structure):
    _fields_ = [('hwnd', HWND),
                ('message', UINT),
                ('wParam', WPARAM),
                ('lParam', LPARAM),
                ('time', DWORD),
                ('pt', POINT)]

class RAWINPUTDEVICE(ct.Structure):
    _fields_ = [('usUsagePage', USHORT),
                ('usUsage', USHORT),
                ('dwFlags', DWORD),
                ('hwndTarget', HWND)]



class LAYERPLANEDESCRIPTOR(ct.Structure):
    _fields_ = [('nSize', WORD),
                ('nVersion', WORD),
                ('dwFlags', DWORD),
                ('iPixelType', BYTE),
                ('cColorBits', BYTE),
                ('cRedBits', BYTE),
                ('cRedShift', BYTE),
                ('cGreenBits', BYTE),
                ('cGreenShift', BYTE),
                ('cBlueBits', BYTE),
                ('cBlueShift', BYTE),
                ('cAlphaBits', BYTE),
                ('cAlphaShift', BYTE),
                ('cAccumBits', BYTE),
                ('cAccumRedBits', BYTE),
                ('cAccumGreenBits', BYTE),
                ('cAccumBlueBits', BYTE),
                ('cAccumAlphaBits', BYTE),
                ('cDepthBits', BYTE),
                ('cStencilBits', BYTE),
                ('cAuxBuffers', BYTE),
                ('iLayerType', BYTE),
                ('bReserved', BYTE),
                ('crTransparent', COLORREF)]

class POINTFLOAT(ct.Structure):
    _fields_ = [('x', FLOAT),
                ('y', FLOAT)]

class GLYPHMETRICSFLOAT(ct.Structure):
    _fields_ =  [('gmfBlackBoxX', FLOAT),
                 ('gmfBlackBoxY', FLOAT),
                 ('gmfptGlyphOrigin', POINTFLOAT),
                 ('gmfCellIncX', FLOAT),
                 ('gmfCellIncY', FLOAT)]

PGLYPHMETRICSFLOAT = LPGLYPHMETRICSFLOAT = ct.POINTER(GLYPHMETRICSFLOAT)
PPOINTFLOAT = ct.POINTER(POINTFLOAT)
PLAYERPLANEDESCRIPTOR = POINTER(LAYERPLANEDESCRIPTOR)
PRAWINPUTDEVICE = LPRAWINPUTDEVICE = POINTER(RAWINPUTDEVICE)
LPCRECT = LPRECT = POINTER(RECT)
LPMSG = POINTER(MSG)
LPPOINT = POINTER(POINT)

# Need to check for code generation because WINFUNCTYPE is only in windows.
if _generation:
    MONITORENUMPROC = ct.c_void_p
    TIMERPROC = ct.c_void_p
    PROC = ct.c_void_p
else:
    MONITORENUMPROC = ct.WINFUNCTYPE(BOOL, HMONITOR, HDC, POINTER(RECT), LPARAM)
    TIMERPROC = ct.WINFUNCTYPE(VOID, HWND, UINT, UINT_PTR, DWORD)
    PROC = ct.WINFUNCTYPE(INT)


# Dll names
user32 = "user32"
gdi32 = "gdi32"
kernel32 = 'kernel32'

# Message Box

# Return values
IDOK = 1
IDCANCEL = 2
IDABORT = 3
IDRETRY = 4
IDIGNORE = 5
IDYES = 6
IDNO = 7
IDTRYAGAIN = 10
IDCONTINUE = 11

# Buttons
MB_ABORTRETRYIGNORE = 0x00000002
MB_CANCELTRYCONTINUE = 0x00000006
MB_HELP = 0x00004000
MB_OK = 0x00000000
MB_OKCANCEL = 0x00000001
MB_RETRYCANCEL = 0x00000005
MB_YESNO = 0x00000004
MB_YESNOCANCEL = 0x00000003

# Icons
MB_ICONEXCLAMATION = 0x00000030
MB_ICONWARNING = 0x00000030
MB_ICONINFORMATION = 0x00000030
MB_ICONASTERISK = 0x00000030
MB_ICONQUESTION = 0x00000030
MB_ICONSTOP = 0x00000030
MB_ICONERROR = 0x00000030
MB_ICONHAND = 0x00000030

# Default selected button
MB_DEFBUTTON1 = 0x00000000
MB_DEFBUTTON2 = 0x00000100
MB_DEFBUTTON3 = 0x00000200
MB_DEFBUTTON3 = 0x00000300

# Focus modes for associated window
MB_APPLMODAL = 0x00000000
MB_SYSTEMMODAL = 0x00001000
MB_TASKMODAL = 0x00002000

# Other
MB_DEFAULT_DESKTOP_ONLY = 0x00020000
MB_RIGHT = 0x00080000
MB_RTLREADING = 0x00100000
MB_SETFOREGROUND = 0x00010000
MB_TOPMOST = 0x00040000
MB_SERVICE_NOTIFICATION = 0x00200000

# Window Style
CS_VREDRAW = 0x0001
CS_HREDRAW = 0x0002
CS_DBLCLKS = 0x0008
CS_OWNDC = 0x0020
CS_CLASSDC = 0x0040
CS_PARENTDC = 0x0080
CS_NOCLOSE = 0x0200
CS_SAVEBITS = 0x0800
CS_BYTEALIGNCLIENT = 0x1000
CS_BYTEALIGNWINDOW = 0x2000
CS_GLOBALCLASS = 0x4000
CS_DROPSHADOW = 0x00020000

# Window Messages
WM_NULL = 0x0000
WM_CREATE = 0x0001
WM_DESTROY = 0x0002
WM_MOVE = 0x0003
WM_SIZE = 0x0005
WM_ACTIVATE = 0x0006
WM_SETFOCUS = 0x0007
WM_KILLFOCUS = 0x0008
WM_ENABLE = 0x000A
WM_SETREDRAW = 0x000B
WM_SETTEXT = 0x000C
WM_GETTEXT = 0x000D
WM_GETTEXTLENGTH = 0x000E
WM_PAINT = 0x000F
WM_CLOSE = 0x0010
WM_QUERYENDSESSION = 0x0011
WM_QUERYOPEN = 0x0013
WM_ENDSESSION = 0x0016
WM_QUIT = 0x0012
WM_ERASEBKGND = 0x0014
WM_SYSCOLORCHANGE = 0x0015
WM_SHOWWINDOW = 0x0018
WM_WININICHANGE = 0x001A
WM_SETTINGCHANGE = WM_WININICHANGE
WM_DEVMODECHANGE = 0x001B
WM_ACTIVATEAPP = 0x001C
WM_FONTCHANGE = 0x001D
WM_TIMECHANGE = 0x001E
WM_CANCELMODE = 0x001F
WM_SETCURSOR = 0x0020
WM_MOUSEACTIVATE = 0x0021
WM_CHILDACTIVATE = 0x0022
WM_QUEUESYNC = 0x0023
WM_GETMINMAXINFO = 0x0024
WM_PAINTICON = 0x0026
WM_ICONERASEBKGND = 0x0027
WM_NEXTDLGCTL = 0x0028
WM_SPOOLERSTATUS = 0x002A
WM_DRAWITEM = 0x002B
WM_MEASUREITEM = 0x002C
WM_DELETEITEM = 0x002D
WM_VKEYTOITEM = 0x002E
WM_CHARTOITEM = 0x002F
WM_SETFONT = 0x0030
WM_GETFONT = 0x0031
WM_SETHOTKEY = 0x0032
WM_GETHOTKEY = 0x0033
WM_QUERYDRAGICON = 0x0037
WM_COMPAREITEM = 0x0039
WM_GETOBJECT = 0x003D
WM_COMPACTING = 0x0041
WM_COMMNOTIFY = 0x0044
WM_WINDOWPOSCHANGING = 0x0046
WM_WINDOWPOSCHANGED = 0x0047
WM_POWER = 0x0048
WM_NOTIFY = 0x004E
WM_INPUTLANGCHANGEREQUEST = 0x0050
WM_INPUTLANGCHANGE = 0x0051
WM_TCARD = 0x0052
WM_HELP = 0x0053
WM_USERCHANGED = 0x0054
WM_NOTIFYFORMAT = 0x0055
WM_CONTEXTMENU = 0x007B
WM_STYLECHANGING = 0x007C
WM_STYLECHANGED = 0x007D
WM_DISPLAYCHANGE = 0x007E
WM_GETICON = 0x007F
WM_SETICON = 0x0080
WM_NCCREATE = 0x0081
WM_NCDESTROY = 0x0082
WM_NCCALCSIZE = 0x0083
WM_NCHITTEST = 0x0084
WM_NCPAINT = 0x0085
WM_NCACTIVATE = 0x0086
WM_GETDLGCODE = 0x0087
WM_SYNCPAINT = 0x0088
WM_NCMOUSEMOVE = 0x00A0
WM_NCLBUTTONDOWN = 0x00A1
WM_NCLBUTTONUP = 0x00A2
WM_NCLBUTTONDBLCLK = 0x00A3
WM_NCRBUTTONDOWN = 0x00A4
WM_NCRBUTTONUP = 0x00A5
WM_NCRBUTTONDBLCLK = 0x00A6
WM_NCMBUTTONDOWN = 0x00A7
WM_NCMBUTTONUP = 0x00A8
WM_NCMBUTTONDBLCLK = 0x00A9
WM_NCXBUTTONDOWN = 0x00AB
WM_NCXBUTTONUP = 0x00AC
WM_NCXBUTTONDBLCLK = 0x00AD
WM_INPUT_DEVICE_CHANGE = 0x00FE
WM_INPUT = 0x00FF
WM_KEYFIRST = 0x0100
WM_KEYDOWN = 0x0100
WM_KEYUP = 0x0101
WM_CHAR = 0x0102
WM_DEADCHAR = 0x0103
WM_SYSKEYDOWN = 0x0104
WM_SYSKEYUP = 0x0105
WM_SYSCHAR = 0x0106
WM_SYSDEADCHAR = 0x0107
WM_UNICHAR = 0x0109
WM_KEYLAST = 0x0109
UNICODE_NOCHAR = 0xFFFF
WM_KEYLAST = 0x0108
WM_IME_STARTCOMPOSITION = 0x010D
WM_IME_ENDCOMPOSITION = 0x010E
WM_IME_COMPOSITION = 0x010F
WM_IME_KEYLAST = 0x010F
WM_INITDIALOG = 0x0110
WM_COMMAND = 0x0111
WM_SYSCOMMAND = 0x0112
WM_TIMER = 0x0113
WM_HSCROLL = 0x0114
WM_VSCROLL = 0x0115
WM_INITMENU = 0x0116
WM_INITMENUPOPUP = 0x0117
WM_GESTURE = 0x0119
WM_GESTURENOTIFY = 0x011A
WM_MENUSELECT = 0x011F
WM_MENUCHAR = 0x0120
WM_ENTERIDLE = 0x0121
WM_MENURBUTTONUP = 0x0122
WM_MENUDRAG = 0x0123
WM_MENUGETOBJECT = 0x0124
WM_UNINITMENUPOPUP = 0x0125
WM_MENUCOMMAND = 0x0126
WM_CHANGEUISTATE = 0x0127
WM_UPDATEUISTATE = 0x0128
WM_QUERYUISTATE = 0x0129
WM_CTLCOLORMSGBOX = 0x0132
WM_CTLCOLOREDIT = 0x0133
WM_CTLCOLORLISTBOX = 0x0134
WM_CTLCOLORBTN = 0x0135
WM_CTLCOLORDLG = 0x0136
WM_CTLCOLORSCROLLBAR = 0x0137
WM_CTLCOLORSTATIC = 0x0138
MN_GETHMENU = 0x01E1
WM_MOUSEFIRST = 0x0200
WM_MOUSEMOVE = 0x0200
WM_LBUTTONDOWN = 0x0201
WM_LBUTTONUP = 0x0202
WM_LBUTTONDBLCLK = 0x0203
WM_RBUTTONDOWN = 0x0204
WM_RBUTTONUP = 0x0205
WM_RBUTTONDBLCLK = 0x0206
WM_MBUTTONDOWN = 0x0207
WM_MBUTTONUP = 0x0208
WM_MBUTTONDBLCLK = 0x0209
WM_MOUSEWHEEL = 0x020A
WM_XBUTTONDOWN = 0x020B
WM_XBUTTONUP = 0x020C
WM_XBUTTONDBLCLK = 0x020D
WM_MOUSEHWHEEL = 0x020E
WM_PARENTNOTIFY = 0x0210
WM_ENTERMENULOOP = 0x0211
WM_EXITMENULOOP = 0x0212
WM_NEXTMENU = 0x0213
WM_SIZING = 0x0214
WM_CAPTURECHANGED = 0x0215
WM_MOVING = 0x0216
WM_POWERBROADCAST = 0x0218
WM_DEVICECHANGE = 0x0219
WM_MDICREATE = 0x0220
WM_MDIDESTROY = 0x0221
WM_MDIACTIVATE = 0x0222
WM_MDIRESTORE = 0x0223
WM_MDINEXT = 0x0224
WM_MDIMAXIMIZE = 0x0225
WM_MDITILE = 0x0226
WM_MDICASCADE = 0x0227
WM_MDIICONARRANGE = 0x0228
WM_MDIGETACTIVE = 0x0229
WM_MDISETMENU = 0x0230
WM_ENTERSIZEMOVE = 0x0231
WM_EXITSIZEMOVE = 0x0232
WM_DROPFILES = 0x0233
WM_MDIREFRESHMENU = 0x0234
WM_POINTERDEVICECHANGE = 0x238
WM_POINTERDEVICEINRANGE = 0x239
WM_POINTERDEVICEOUTOFRANGE = 0x23A
WM_TOUCH = 0x0240
WM_NCPOINTERUPDATE = 0x0241
WM_NCPOINTERDOWN = 0x0242
WM_NCPOINTERUP = 0x0243
WM_POINTERUPDATE = 0x0245
WM_POINTERDOWN = 0x0246
WM_POINTERUP = 0x0247
WM_POINTERENTER = 0x0249
WM_POINTERLEAVE = 0x024A
WM_POINTERACTIVATE = 0x024B
WM_POINTERCAPTURECHANGED = 0x024C
WM_TOUCHHITTESTING = 0x024D
WM_POINTERWHEEL = 0x024E
WM_POINTERHWHEEL = 0x024F
WM_IME_SETCONTEXT = 0x0281
WM_IME_NOTIFY = 0x0282
WM_IME_CONTROL = 0x0283
WM_IME_COMPOSITIONFULL = 0x0284
WM_IME_SELECT = 0x0285
WM_IME_CHAR = 0x0286
WM_IME_REQUEST = 0x0288
WM_IME_KEYDOWN = 0x0290
WM_IME_KEYUP = 0x0291
WM_MOUSEHOVER = 0x02A1
WM_MOUSELEAVE = 0x02A3
WM_NCMOUSEHOVER = 0x02A0
WM_NCMOUSELEAVE = 0x02A2
WM_WTSSESSION_CHANGE = 0x02B1
WM_TABLET_FIRST = 0x02c0
WM_TABLET_LAST = 0x02df
WM_CUT = 0x0300
WM_COPY = 0x0301
WM_PASTE = 0x0302
WM_CLEAR = 0x0303
WM_UNDO = 0x0304
WM_RENDERFORMAT = 0x0305
WM_RENDERALLFORMATS = 0x0306
WM_DESTROYCLIPBOARD = 0x0307
WM_DRAWCLIPBOARD = 0x0308
WM_PAINTCLIPBOARD = 0x0309
WM_VSCROLLCLIPBOARD = 0x030A
WM_SIZECLIPBOARD = 0x030B
WM_ASKCBFORMATNAME = 0x030C
WM_CHANGECBCHAIN = 0x030D
WM_HSCROLLCLIPBOARD = 0x030E
WM_QUERYNEWPALETTE = 0x030F
WM_PALETTEISCHANGING = 0x0310
WM_PALETTECHANGED = 0x0311
WM_HOTKEY = 0x0312
WM_PRINT = 0x0317
WM_PRINTCLIENT = 0x0318
WM_APPCOMMAND = 0x0319
WM_THEMECHANGED = 0x031A
WM_CLIPBOARDUPDATE = 0x031D
WM_DWMCOMPOSITIONCHANGED = 0x031E
WM_DWMNCRENDERINGCHANGED = 0x031F
WM_DWMCOLORIZATIONCOLORCHANGED = 0x0320
WM_DWMWINDOWMAXIMIZEDCHANGE = 0x0321
WM_DWMSENDICONICTHUMBNAIL = 0x0323
WM_DWMSENDICONICLIVEPREVIEWBITMAP = 0x0326
WM_GETTITLEBARINFOEX = 0x033F
WM_HANDHELDFIRST = 0x0358
WM_HANDHELDLAST = 0x035F
WM_AFXFIRST = 0x0360
WM_AFXLAST = 0x037F
WM_PENWINFIRST = 0x0380
WM_PENWINLAST = 0x038F
WM_APP = 0x8000
WM_USER = 0x0400

CW_USEDEFAULT = 0x80000000

SIZE_RESTORED = 0
SIZE_MINIMIZED = 1
SIZE_MAXIMIZED = 2
SIZE_MAXSHOW = 3
SIZE_MAXHIDE = 4

# ShowWindow
SW_HIDE = 0
SW_SHOWNORMAL = 1
SW_NORMAL = 1
SW_SHOWMINIMIZED = 2
SW_SHOWMAXIMIZED = 3
SW_MAXIMIZE = 3
SW_SHOWNOACTIVATE = 4
SW_SHOW = 5
SW_MINIMIZE = 6
SW_SHOWMINNOACTIVE = 7
SW_SHOWNA = 8
SW_RESTORE = 9
SW_SHOWDEFAULT = 10
SW_FORCEMINIMIZE = 11
SW_MAX = 11

# GetStockObject
WHITE_BRUSH = 0
LTGRAY_BRUSH = 1
GRAY_BRUSH = 2
DKGRAY_BRUSH = 3
BLACK_BRUSH = 4
NULL_BRUSH = 5
HOLLOW_BRUSH = NULL_BRUSH
WHITE_PEN = 6
BLACK_PEN = 7
NULL_PEN = 8
OEM_FIXED_FONT = 10
ANSI_FIXED_FONT = 11
ANSI_VAR_FONT = 12
SYSTEM_FONT = 13
DEVICE_DEFAULT_FONT = 14
DEFAULT_PALETTE = 15
SYSTEM_FIXED_FONT = 16

# Window Styles
WS_OVERLAPPED = 0x00000000
WS_POPUP = 0x80000000
WS_CHILD = 0x40000000
WS_MINIMIZE = 0x20000000
WS_VISIBLE = 0x10000000
WS_DISABLED = 0x08000000
WS_CLIPSIBLINGS = 0x04000000
WS_CLIPCHILDREN = 0x02000000
WS_MAXIMIZE = 0x01000000
WS_CAPTION = 0x00C00000
WS_BORDER = 0x00800000
WS_DLGFRAME = 0x00400000
WS_VSCROLL = 0x00200000
WS_HSCROLL = 0x00100000
WS_SYSMENU = 0x00080000
WS_THICKFRAME = 0x00040000
WS_GROUP = 0x00020000
WS_TABSTOP = 0x00010000
WS_MINIMIZEBOX = 0x00020000
WS_MAXIMIZEBOX = 0x00010000
WS_TILED = WS_OVERLAPPED
WS_ICONIC = WS_MINIMIZE
WS_SIZEBOX = WS_THICKFRAME

WS_OVERLAPPEDWINDOW = ( WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU |
        WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX )

WS_POPUPWINDOW = ( WS_POPUP | WS_BORDER | WS_SYSMENU )
WS_TILEDWINDOW = WS_OVERLAPPEDWINDOW
WS_CHILDWINDOW = WS_CHILD
WS_EX_DLGMODALFRAME = 0x00000001
WS_EX_NOPARENTNOTIFY = 0x00000004
WS_EX_TOPMOST = 0x00000008
WS_EX_ACCEPTFILES = 0x00000010
WS_EX_TRANSPARENT = 0x00000020
WS_EX_MDICHILD = 0x00000040
WS_EX_TOOLWINDOW = 0x00000080
WS_EX_WINDOWEDGE = 0x00000100
WS_EX_CLIENTEDGE = 0x00000200
WS_EX_CONTEXTHELP = 0x00000400
WS_EX_RIGHT = 0x00001000
WS_EX_LEFT = 0x00000000
WS_EX_RTLREADING = 0x00002000
WS_EX_LTRREADING = 0x00000000
WS_EX_LEFTSCROLLBAR = 0x00004000
WS_EX_RIGHTSCROLLBAR = 0x00000000
WS_EX_CONTROLPARENT = 0x00010000
WS_EX_STATICEDGE = 0x00020000
WS_EX_APPWINDOW = 0x00040000
WS_EX_OVERLAPPEDWINDOW = WS_EX_WINDOWEDGE | WS_EX_CLIENTEDGE
WS_EX_PALETTEWINDOW = WS_EX_WINDOWEDGE | WS_EX_TOOLWINDOW | WS_EX_TOPMOST
WS_EX_LAYERED = 0x00080000
WS_EX_NOINHERITLAYOUT = 0x00100000
WS_EX_LAYOUTRTL = 0x00400000
WS_EX_COMPOSITED = 0x02000000
WS_EX_NOACTIVATE = 0x08000000


def MAKEINTRESOURCE(i):
    return ct.cast(ct.c_void_p(i&0xFFFF), LPCWSTR)

def LOWORD(lParam):
    return ct.c_int16(lParam & 0xffff).value

def HIWORD(lParam):
    return ct.c_int16(lParam >> 16).value

MK_LBUTTON = 0x0001
MK_RBUTTON = 0x0002
MK_SHIFT = 0x0004
MK_CONTROL = 0x0008
MK_MBUTTON = 0x0010
MK_XBUTTON1 = 0x0020
MK_XBUTTON2 = 0x0040

# App icons
IDI_APPLICATION = MAKEINTRESOURCE(32512)
IDI_HAND = MAKEINTRESOURCE(32513)
IDI_QUESTION = MAKEINTRESOURCE(32514)
IDI_EXCLAMATION = MAKEINTRESOURCE(32515)
IDI_ASTERISK = MAKEINTRESOURCE(32516)
IDI_WINLOGO = MAKEINTRESOURCE(32517)
IDI_SHIELD = MAKEINTRESOURCE(32518)
IDI_WARNING = IDI_EXCLAMATION
IDI_ERROR = IDI_HAND
IDI_INFORMATION = IDI_ASTERISK

# Cursors
IDC_ARROW = MAKEINTRESOURCE(32512)
IDC_IBEAM = MAKEINTRESOURCE(32513)
IDC_WAIT = MAKEINTRESOURCE(32514)
IDC_CROSS = MAKEINTRESOURCE(32515)
IDC_UPARROW = MAKEINTRESOURCE(32516)
IDC_SIZENWSE = MAKEINTRESOURCE(32642)
IDC_SIZENESW = MAKEINTRESOURCE(32643)
IDC_SIZEWE = MAKEINTRESOURCE(32644)
IDC_SIZENS = MAKEINTRESOURCE(32645)
IDC_SIZEALL = MAKEINTRESOURCE(32646)
IDC_NO = MAKEINTRESOURCE(32648)
IDC_HAND = MAKEINTRESOURCE(32649)
IDC_APPSTARTING = MAKEINTRESOURCE(32650)
IDC_HELP = MAKEINTRESOURCE(32651)

PM_NOREMOVE = 0x0000
PM_REMOVE = 0x0001
PM_NOYIELD = 0x0002

# Pixel Types
PFD_TYPE_RGBA = 0
PFD_TYPE_COLORINDEX = 1

# Layer Types
PFD_MAIN_PLANE = 0
PFD_OVERLAY_PLANE = 1
PFD_UNDERLAY_PLANE = -1

# PIXELFORMATDESCRIPTER flags
PFD_DOUBLEBUFFER = 0x00000001
PFD_STEREO = 0x00000002
PFD_DRAW_TO_WINDOW = 0x00000004
PFD_DRAW_TO_BITMAP = 0x00000008
PFD_SUPPORT_GDI = 0x00000010
PFD_SUPPORT_OPENGL = 0x00000020
PFD_GENERIC_FORMAT = 0x00000040
PFD_NEED_PALETTE = 0x00000080
PFD_NEED_SYSTEM_PALETTE = 0x00000100
PFD_SWAP_EXCHANGE = 0x00000200
PFD_SWAP_COPY = 0x00000400
PFD_SWAP_LAYER_BUFFERS = 0x00000800
PFD_GENERIC_ACCELERATED = 0x00001000
PFD_SUPPORT_DIRECTDRAW = 0x00002000
PFD_DIRECT3D_ACCELERATED = 0x00004000
PFD_SUPPORT_COMPOSITION = 0x00008000

# ChoosePixelFormat Only flags
PFD_DEPTH_DONTCARE = 0x20000000
PFD_DOUBLEBUFFER_DONTCARE = 0x40000000
PFD_STEREO_DONTCARE = 0x80000000

# MonitorFromWindow
MONITOR_DEFAULTTONULL = 0x00000000
MONITOR_DEFAULTTOPRIMARY = 0x00000001
MONITOR_DEFAULTTONEAREST = 0x00000002

# GetSystemMetrics
SM_CXSCREEN = 0
SM_CYSCREEN = 1
SM_CXVSCROLL = 2
SM_CYHSCROLL = 3
SM_CYCAPTION = 4
SM_CXBORDER = 5
SM_CYBORDER = 6
SM_CXDLGFRAME = 7
SM_CYDLGFRAME = 8
SM_CYVTHUMB = 9
SM_CXHTHUMB = 10
SM_CXICON = 11
SM_CYICON = 12
SM_CXCURSOR = 13
SM_CYCURSOR = 14
SM_CYMENU = 15
SM_CXFULLSCREEN = 16
SM_CYFULLSCREEN = 17
SM_CYKANJIWINDOW = 18
SM_MOUSEPRESENT = 19
SM_CYVSCROLL = 20
SM_CXHSCROLL = 21
SM_DEBUG = 22
SM_SWAPBUTTON = 23
SM_RESERVED1 = 24
SM_RESERVED2 = 25
SM_RESERVED3 = 26
SM_RESERVED4 = 27
SM_CXMIN = 28
SM_CYMIN = 29
SM_CXSIZE = 30
SM_CYSIZE = 31
SM_CXFRAME = 32
SM_CYFRAME = 33
SM_CXMINTRACK = 34
SM_CYMINTRACK = 35
SM_CXDOUBLECLK = 36
SM_CYDOUBLECLK = 37
SM_CXICONSPACING = 38
SM_CYICONSPACING = 39
SM_MENUDROPALIGNMENT = 40
SM_PENWINDOWS = 41
SM_DBCSENABLED = 42
SM_CMOUSEBUTTONS = 43
SM_CXFIXEDFRAME = SM_CXDLGFRAME
SM_CYFIXEDFRAME = SM_CYDLGFRAME
SM_CXSIZEFRAME = SM_CXFRAME
SM_CYSIZEFRAME = SM_CYFRAME

SM_SECURE = 44
SM_CXEDGE = 45
SM_CYEDGE = 46
SM_CXMINSPACING = 47
SM_CYMINSPACING = 48
SM_CXSMICON = 49
SM_CYSMICON = 50
SM_CYSMCAPTION = 51
SM_CXSMSIZE = 52
SM_CYSMSIZE = 53
SM_CXMENUSIZE = 54
SM_CYMENUSIZE = 55
SM_ARRANGE = 56
SM_CXMINIMIZED = 57
SM_CYMINIMIZED = 58
SM_CXMAXTRACK = 59
SM_CYMAXTRACK = 60
SM_CXMAXIMIZED = 61
SM_CYMAXIMIZED = 62
SM_NETWORK = 63
SM_CLEANBOOT = 67
SM_CXDRAG = 68
SM_CYDRAG = 69
SM_SHOWSOUNDS = 70
SM_CXMENUCHECK = 71
SM_CYMENUCHECK = 72
SM_SLOWMACHINE = 73
SM_MIDEASTENABLED = 74
SM_MOUSEWHEELPRESENT = 75
SM_XVIRTUALSCREEN = 76
SM_YVIRTUALSCREEN = 77
SM_CXVIRTUALSCREEN = 78
SM_CYVIRTUALSCREEN = 79
SM_CMONITORS = 80
SM_SAMEDISPLAYFORMAT = 81
SM_IMMENABLED = 82
SM_CXFOCUSBORDER = 83
SM_CYFOCUSBORDER = 84
SM_TABLETPC = 86
SM_MEDIACENTER = 87
SM_STARTER = 88
SM_SERVERR2 = 89
SM_MOUSEHORIZONTALWHEELPRESENT = 91
SM_CXPADDEDBORDER = 92

SM_REMOTESESSION = 0x1000
SM_SHUTTINGDOWN = 0x2000
SM_REMOTECONTROL = 0x2001
SM_CARETBLINKINGENABLED = 0x2002

DM_BITSPERPEL = 0x00040000
DM_PELSWIDTH = 0x00080000
DM_PELSHEIGHT = 0x00100000

CDS_FULLSCREEN = 0x00000004

ENUM_CURRENT_SETTINGS = -1

EDD_GET_DEVICE_INTERFACE_NAME = 0x00000001

# Key codes
VK_F1 = 0x70
VK_F2 = 0x71
VK_F3 = 0x72
VK_F4 = 0x73
VK_F5 = 0x74
VK_F6 = 0x75
VK_F7 = 0x76
VK_F8 = 0x77
VK_F9 = 0x78
VK_F10 = 0x79
VK_F11 = 0x7A
VK_F12 = 0x7B

VK_A = 0x41
VK_B = 0x42
VK_C = 0x43
VK_D = 0x44
VK_E = 0x45
VK_F = 0x46
VK_G = 0x47
VK_H = 0x48
VK_I = 0x49
VK_J = 0x4A
VK_K = 0x4B
VK_L = 0x4C
VK_M = 0x4D
VK_N = 0x4E
VK_O = 0x5F
VK_P = 0x50
VK_Q = 0x51
VK_R = 0x52
VK_S = 0x53
VK_T = 0x54
VK_U = 0x55
VK_V = 0x56
VK_W = 0x57
VK_X = 0x58
VK_Y = 0x59
VK_Z = 0x5A

VK_LEFT = 0x25
VK_UP = 0x26
VK_RIGHT = 0x27
VK_DOWN = 0x28

GWL_EXSTYLE = -20
GWL_STYLE = -16

# LoadImage Macros
IMAGE_BITMAP = 0
IMAGE_ICON = 1
IMAGE_CURSOR = 2

LR_DEFAULTCOLOR = 0x00000000
LR_MONOCHROME = 0x00000001
LR_COLOR = 0x00000002
LR_COPYRETURNORG = 0x00000004
LR_COPYDELETEORG = 0x00000008
LR_LOADFROMFILE = 0x00000010
LR_LOADTRANSPARENT = 0x00000020
LR_DEFAULTSIZE = 0x00000040
LR_VGACOLOR = 0x00000080
LR_LOADMAP3DCOLORS = 0x00001000
LR_CREATEDIBSECTION = 0x00002000
LR_COPYFROMRESOURCE = 0x00004000
LR_SHARED = 0x00008000

# Raw Input
RIM_INPUT = 0
RIM_INPUTSINK = 1

RIM_TYPEMOUSE = 0
RIM_TYPEKEYBOARD = 1
RIM_TYPEHID = 2

RI_MOUSE_LEFT_BUTTON_DOWN = 0x0001
RI_MOUSE_LEFT_BUTTON_UP = 0x0002
RI_MOUSE_RIGHT_BUTTON_DOWN = 0x0004
RI_MOUSE_RIGHT_BUTTON_UP = 0x0008
RI_MOUSE_MIDDLE_BUTTON_DOWN = 0x0010
RI_MOUSE_MIDDLE_BUTTON_UP = 0x0020

RI_MOUSE_BUTTON_1_DOWN = RI_MOUSE_LEFT_BUTTON_DOWN
RI_MOUSE_BUTTON_1_UP = RI_MOUSE_LEFT_BUTTON_UP
RI_MOUSE_BUTTON_2_DOWN = RI_MOUSE_RIGHT_BUTTON_DOWN
RI_MOUSE_BUTTON_2_UP = RI_MOUSE_RIGHT_BUTTON_UP
RI_MOUSE_BUTTON_3_DOWN = RI_MOUSE_MIDDLE_BUTTON_DOWN
RI_MOUSE_BUTTON_3_UP = RI_MOUSE_MIDDLE_BUTTON_UP

RI_MOUSE_BUTTON_4_DOWN = 0x0040
RI_MOUSE_BUTTON_4_UP = 0x0080
RI_MOUSE_BUTTON_5_DOWN = 0x0100
RI_MOUSE_BUTTON_5_UP = 0x0200

RI_MOUSE_WHEEL = 0x0400

MOUSE_MOVE_RELATIVE = 0
MOUSE_MOVE_ABSOLUTE = 1
MOUSE_VIRTUAL_DESKTOP = 0x02
MOUSE_ATTRIBUTES_CHANGED = 0x04
MOUSE_MOVE_NOCOALESCE = 0x08

RI_KEY_MAKE = 0
RI_KEY_BREAK = 1
RI_KEY_E0 = 2
RI_KEY_E1 = 4
RI_KEY_TERMSRV_SET_LED = 8
RI_KEY_TERMSRV_SHADOW = 0x10

RID_INPUT = 0x10000003
RID_HEADER = 0x10000005

RIDI_PREPARSEDDATA = 0x20000005
RIDI_DEVICENAME = 0x20000007
RIDI_DEVICEINFO = 0x2000000b

RIDEV_REMOVE = 0x00000001
RIDEV_EXCLUDE = 0x00000010
RIDEV_PAGEONLY = 0x00000020
RIDEV_NOLEGACY = 0x00000030
RIDEV_INPUTSINK = 0x00000100
RIDEV_CAPTUREMOUSE = 0x00000200
RIDEV_NOHOTKEYS = 0x00000200
RIDEV_APPKEYS = 0x00000400
RIDEV_EXINPUTSINK = 0x00001000
RIDEV_DEVNOTIFY = 0x00002000
RIDEV_EXMODEMASK = 0x000000F0


# Function Definitions
_messageBoxParams  = (HWND, LPCWSTR, LPCWSTR, UINT)
MessageBox = define_function( user32, 'MessageBoxW', ct.c_int, _messageBoxParams )

RegisterClass = define_function( user32, 'RegisterClassW', ATOM, (ct.POINTER(WNDCLASS),) )

_createWindowExParams = ( DWORD, LPCWSTR, LPCWSTR, DWORD, ct.c_int, ct.c_int,
                        ct.c_int, ct.c_int, HWND, HMENU, HINSTANCE, LPVOID)
CreateWindowEx = define_function(user32, 'CreateWindowExW', HWND, _createWindowExParams)

ShowWindow = define_function( user32, 'ShowWindow', BOOL, (HWND, ct.c_int) )

UpdateWindow = define_function( user32, 'UpdateWindow', BOOL, (HWND,) )

_getMessageParams = (ct.POINTER(MSG), HWND, UINT, UINT)
GetMessage = define_function( user32, 'GetMessageW', BOOL, _getMessageParams )

GetStockObject = define_function( gdi32, 'GetStockObject', HGDIOBJ, (ct.c_int,) )

TranslateMessage = define_function(user32, 'TranslateMessage', BOOL, (ct.POINTER(MSG),) )


DispatchMessage = define_function(user32, 'DispatchMessageW', LRESULT, (ct.POINTER(MSG),) )

_defWindowProcParams = ( HWND, UINT, WPARAM, LPARAM )
DefWindowProc = define_function( user32, 'DefWindowProcW', LRESULT, _defWindowProcParams)

LoadIcon = define_function( user32, 'LoadIconW', HICON, (HINSTANCE, LPCWSTR))

LoadCursor = define_function( user32, 'LoadCursorW', HCURSOR , (HINSTANCE, LPCTSTR))

_peekMessageParams = (ct.POINTER(MSG), HWND, UINT, UINT, UINT)
PeekMessage = define_function( user32, 'PeekMessageW', BOOL, _peekMessageParams )

GetDC = define_function( user32, 'GetDC', HDC, (HWND,) )

_choosePixelFormatParams = (HDC, ct.POINTER(PIXELFORMATDESCRIPTOR))
ChoosePixelFormat = define_function( gdi32, 'ChoosePixelFormat', ct.c_int, _choosePixelFormatParams )


_setPixelFormatParams = (HDC, ct.c_int, ct.POINTER(PIXELFORMATDESCRIPTOR))
SetPixelFormat = define_function( gdi32, 'SetPixelFormat', BOOL, _setPixelFormatParams )

SetForegroundWindow = define_function( user32, 'SetForegroundWindow', BOOL, (HWND,) )

SetFocus = define_function( user32, 'SetFocus', HWND, (HWND,) )

SwapBuffers = define_function( gdi32, 'SwapBuffers', BOOL, (HDC,) )

AdjustWindowRectEx = define_function( user32, 'AdjustWindowRectEx', BOOL, (LPRECT, DWORD, BOOL, DWORD) )

ValidateRect = define_function( user32, 'ValidateRect', BOOL, (HWND, ct.POINTER(RECT)) )

GetClientRect = define_function( user32, 'GetClientRect', BOOL, (HWND, LPRECT))
GetWindowRect = define_function( user32, 'GetWindowRect', BOOL, (HWND, LPRECT))

MoveWindow = define_function( user32, 'MoveWindow', BOOL, (HWND, ct.c_int, ct.c_int, ct.c_int, ct.c_int, BOOL))

MonitorFromWindow = define_function( user32, 'MonitorFromWindow', HMONITOR, (HWND, DWORD) )

MonitorFromRect = define_function( user32, 'MonitorFromRect', HMONITOR, (LPCRECT, DWORD) )

GetMonitorInfo = define_function( user32, 'GetMonitorInfoW', BOOL, (HMONITOR, ct.POINTER(MONITORINFOEX)) )

_enumDisplayMonitorsParams = (HDC, LPCRECT, MONITORENUMPROC, LPARAM)
EnumDisplayMonitors = define_function( user32, 'EnumDisplayMonitors', BOOL, _enumDisplayMonitorsParams )

ChangeDisplaySettings = define_function( user32, 'ChangeDisplaySettingsW', LONG,  (ct.POINTER(DEVMODE), DWORD) )

EnumDisplaySettings = define_function( user32, 'EnumDisplaySettingsW', BOOL,  (LPCWSTR, DWORD, ct.POINTER(DEVMODE)))

EnumDisplayDevices = define_function( user32, 'EnumDisplayDevicesW', BOOL,  (LPCWSTR, DWORD, ct.POINTER(DISPLAY_DEVICE), DWORD))

SetWindowLong = define_function( user32, 'SetWindowLongW', LONG,  (HWND, ct.c_int, LONG))

GetWindowLong = define_function( user32, 'GetWindowLongW', LONG,  (HWND, ct.c_int))

DestroyWindow = define_function(user32, 'DestroyWindow', BOOL, (HWND,))

_loadImageParams = (HINSTANCE, LPCTSTR, UINT, ct.c_int, ct.c_int, UINT)
LoadImage = define_function(user32, 'LoadImageW', HANDLE,  _loadImageParams)

GetModuleHandle = define_function(kernel32, 'GetModuleHandleW', HMODULE, (LPCTSTR,))

UnregisterClass = define_function(user32, 'UnregisterClassW', BOOL, (LPCTSTR, HINSTANCE))

_setTimerParams = (HWND, UINT_PTR, UINT, TIMERPROC)
SetTimer = define_function(user32, 'SetTimer', UINT_PTR, _setTimerParams)

KillTimer = define_function(user32, 'KillTimer', BOOL, (HWND, UINT_PTR))
