; ------------------------------------------------------
; Constants
DIALOG_OK               equ     2
DIALOG_CANCEL           equ     1

; ------------------------------------------------------
; Variables
                        .data
_Serif_Font             dd      0

_Dialog_Template        DLGTEMPLATE <>
                        DLGTEMPLATE <>
                        DLGTEMPLATE <>

_hChkFullScreen         dd      0
_hChkVSync              dd      0
_hCbAntiAliasing        dd      0
_hBtnOk                 dd      0
_hBtnCancel             dd      0
_Dialog_Result          dd      0

                        .code

; ------------------------------------------------------
; Name: Dialog_Get_X_Unit
; Desc: Set the text of a control
Control_SetText         proc    hWnd:HWND, TextToSet:dword
                        mov     eax, hWnd
                        .if     eax != NULL
                                invoke  SendMessage, eax, WM_SETTEXT, 0, TextToSet
                        .endif
                        ret
Control_SetText         endp

; -----------------------------------------------------------------------
; Name: Control_SetSerif8
; Desc: Set MS Sans Serif size 8 font for a control
Control_SetSerif8       proc    hWnd:HWND
                        mov     eax, hWnd
                        .if     eax != NULL
                                invoke  SendMessage, eax, WM_SETFONT, _Serif_Font, NULL
                        .endif
                        ret
Control_SetSerif8       endp

; -----------------------------------------------------------------------
; Name: Control_Close()
; Desc: Close a windows object
Control_Close           proc    hWnd:HWND
                        mov     eax, hWnd
                        .if     eax != NULL
                                invoke  SendMessage, eax, WM_CLOSE, 0, NULL
                        .endif
                        ret
Control_Close           endp

; ------------------------------------------------------
; Name: Dialog_Get_X_Unit
; Desc: Retrieve X unit for dialog based resources
Dialog_Get_X_Unit       proc
                        invoke  GetDialogBaseUnits
                        and     eax, 0ffffh
                        .if     eax == 0
                                inc     eax
                        .endif
                        ret
Dialog_Get_X_Unit       endp

; ------------------------------------------------------
; Name: Dialog_Get_Y_Unit
; Desc: Retrieve Y unit for dialog based resources
Dialog_Get_Y_Unit       proc
                        invoke  GetDialogBaseUnits
                        and     eax, 0ffff0000h
                        cdq
                        mov     ecx, 010000h
                        idiv    ecx
                        .if     eax == 0
                                inc     eax
                        .endif
                        ret
Dialog_Get_Y_Unit       endp

; ------------------------------------------------------
; Name: Dialog_X_Pixel_To_Unit
; Desc: Convert a resource object coordinate from pixels to dialogs unit on X axis
Dialog_X_Pixel_To_Unit  proc    XCoord:dword, XUnit:dword
                        .if     XUnit != 0
                                mov     eax, XCoord
                                shl     eax, 2
                                cdq
                                mov     ecx, XUnit
                                idiv    ecx
                        .else
                                mov     eax, XCoord
                                shl     eax, 2
                        .endif
                        ret
Dialog_X_Pixel_To_Unit  endp

; ------------------------------------------------------
; Name: Dialog_Y_Pixel_To_Unit
; Desc: Convert a resource object coordinate from pixels to dialogs unit on Y axis
Dialog_Y_Pixel_To_Unit  proc    YCoord:dword, YUnit:dword
                        .if     YUnit != 0
                                mov     eax, YCoord
                                shl     eax, 3
                                cdq
                                mov     ecx, YUnit
                                idiv    ecx
                        .else
                                mov     eax, YCoord
                                shl     eax, 3
                        .endif
                        ret
Dialog_Y_Pixel_To_Unit  endp

; -----------------------------------------------------------------------
; Name: Dialog_Create
; Desc: Create a modal dialog
Dialog_Create           proc    Left:dword, Top:dword, _Width:dword, Height:dword, hParent:dword, DiagProc:dword, ExtraStyle:dword, Centered:dword
                        local   BaseDialogX:dword
                        local   BaseDialogY:dword

                        .if     Left == -1
                                invoke  GetSystemMetrics, SM_CXSCREEN
                                sub     eax, _Width
                                shr     eax, 1
                                mov     Left, eax
                        .endif
                        .if     Top == -1
                                invoke  GetSystemMetrics, SM_CYSCREEN
                                sub     eax, Height
                                shr     eax, 1
                                mov     Top, eax
                        .endif
                        invoke  Dialog_Get_X_Unit
                        mov     BaseDialogX, eax
                        invoke  Dialog_Get_Y_Unit
                        mov     BaseDialogY, eax
                        mov     _Dialog_Template.dwExtendedStyle, 0
                        
                        invoke  Dialog_X_Pixel_To_Unit, Left, BaseDialogX
                        mov     _Dialog_Template.x, ax
                        invoke  Dialog_Y_Pixel_To_Unit, Top, BaseDialogY
                        mov     _Dialog_Template.y, ax
                        invoke  Dialog_X_Pixel_To_Unit, _Width, BaseDialogX
                        mov     _Dialog_Template.lx, ax
                        invoke  Dialog_Y_Pixel_To_Unit, Height, BaseDialogY
                        mov     _Dialog_Template.ly, ax
                        mov     eax, ExtraStyle
                        or      eax, 4 or WS_VISIBLE or DS_3DLOOK or DS_NOIDLEMSG or DS_SETFOREGROUND or DS_MODALFRAME
                        .if     Centered == TRUE
                                or      eax, DS_CENTER
                        .endif
                        mov     _Dialog_Template.style, eax
                        mov     _Dialog_Template.cdit, 0
                        invoke  GetForegroundWindow
                        mov     _Dialog_Result, 0
                        invoke  DialogBoxIndirectParam, g_window.init.application.hInstance, addr _Dialog_Template, eax, DiagProc, 0
                        mov     eax, _Dialog_Result
                        ret
Dialog_Create           endp

; -----------------------------------------------------------------------
; Name: CheckBox_Create
; Desc: Create a checkbox control
CheckBox_Create         proc    Left:dword, Top:dword, _Width:dword, Height:dword, hParent:HWND, Text:dword, CtrlID:dword, ExtraStyle:dword
                        local   hWnd:HWND

                        mov     eax, WS_TABSTOP or WS_VISIBLE or WS_CHILD or BS_LEFT or BS_VCENTER or BS_AUTOCHECKBOX
                        or      eax, ExtraStyle
                        invoke  CreateWindowEx, WS_EX_TRANSPARENT, CSTR("BUTTON"), Text, eax, Left, Top, _Width, Height, hParent, CtrlID, g_window.init.application.hInstance, NULL
                        mov     hWnd, eax
                        .if     eax != NULL
                                invoke  Control_SetSerif8, hWnd
                        .endif
                        mov     eax, hWnd
                        ret
CheckBox_Create         endp

; -----------------------------------------------------------------------
; Name: CheckBox_GetState
; Desc: Retrieve click state of a checkbox
CheckBox_GetState       proc    hWnd:HWND
                        invoke  SendMessage, hWnd, BM_GETCHECK, 0, NULL
                        ret
CheckBox_GetState       endp

; -----------------------------------------------------------------------
; Name: CheckBox_SetState
; Desc: Set click state of a checkbox
CheckBox_SetState       proc    hWnd:HWND, CheckedState:dword
                        invoke  SendMessage, hWnd, BM_SETCHECK, CheckedState, NULL
                        ret
CheckBox_SetState       endp

; -----------------------------------------------------------------------
; Name: Button_Create
; Desc: Create a button control
Button_Create           proc    Left:dword, Top:dword, _Width:dword, Height:dword, hParent:HWND, Text:dword, CtrlID:dword, ExtraStyle:dword
                        local   hWnd:HWND

                        mov     eax, WS_TABSTOP or WS_VISIBLE or WS_CHILD or BS_PUSHBUTTON
                        or      eax, ExtraStyle
                        invoke  CreateWindowEx, WS_EX_NOPARENTNOTIFY, CSTR("BUTTON"), Text, eax, Left, Top, _Width, Height, hParent, CtrlID, g_window.init.application.hInstance, NULL
                        mov     hWnd, eax
                        .if     eax != NULL
                                invoke  Control_SetSerif8, hWnd
                        .endif
                        mov     eax, hWnd
                        ret
Button_Create           endp

; -----------------------------------------------------------------------
; Name: Control_Close()
; Desc: Create a combobox control
ComboBox_Create         proc    Left:dword, Top:dword, _Width:dword, Height:dword, hParent:HWND, Text:dword, CtrlID:dword, ExtraStyle:dword
                        local   hWnd:HWND

                        mov     eax, WS_TABSTOP or WS_VSCROLL or WS_VISIBLE or WS_CHILD or CBS_NOINTEGRALHEIGHT or CBS_AUTOHSCROLL
                        or      eax, ExtraStyle
                        invoke  CreateWindowEx, 0, CSTR("COMBOBOX"), NULL, eax, Left, Top, _Width, Height, hParent, CtrlID, g_window.init.application.hInstance, NULL
                        mov     hWnd, eax
                        .if     eax != NULL
                                invoke  Control_SetSerif8, hWnd
                                invoke  Control_SetText, hWnd, Text
                        .endif
                        mov     eax, hWnd
                        ret
ComboBox_Create         endp

; -----------------------------------------------------------------------
; Name: DialogProc()
; Desc: Add an item to a combobox control
ComboBox_AddItem        proc    hwnd:HWND, ItemText:dword, ItemIndex:dword
                        invoke  SendMessage, hwnd, CB_INSERTSTRING, ItemIndex, ItemText
                        ret
ComboBox_AddItem        endp

; -----------------------------------------------------------------------
; Name: DialogProc()
; Desc: Add an item to a combobox control
ComboBox_SetIndex       proc    hWnd:HWND, Index:dword
                        invoke  SendMessage, hWnd, CB_SETCURSEL, Index, NULL
                        ret
ComboBox_SetIndex       endp

; -----------------------------------------------------------------------
; Name: DialogProc()
; Desc: Retrieve the current selected index of a combobox control
ComboBox_GetIndex       proc    hWnd:HWND
                        invoke  SendMessage, hWnd, CB_GETCURSEL, 0, NULL
                        ret
ComboBox_GetIndex       endp

; -----------------------------------------------------------------------
; Name: DialogProc()
; Desc: Create a label control
Label_Create            proc    Left:dword, Top:dword, _Width:dword, Height:dword, hParent:HWND, Text:dword, CtrlID:dword, ExtraStyle:dword
                        local   hWnd:HWND

                        mov     eax, WS_VISIBLE or WS_CHILD or SS_LEFT
                        or      eax, ExtraStyle
                        invoke  CreateWindowEx, 0, CSTR("STATIC"), Text, eax, Left, Top, _Width, Height, hParent, CtrlID, g_window.init.application.hInstance, NULL
                        mov     hWnd, eax
                        .if     eax != NULL
                                invoke  Control_SetSerif8, hWnd
                        .endif
                        ret
Label_Create            endp

; -----------------------------------------------------------------------
; Name: DialogProc()
; Desc: Messages handler for the dialog window
DialogProc              proc    hWndDlg:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
                        .if     uMsg == WM_INITDIALOG
                                invoke  Control_SetText, hWndDlg, addr _WindowName
                                invoke  Button_Create, 200 - 159, 100 - 24, 77, 23, hWndDlg, CSTR("Ok"), 1, BS_DEFPUSHBUTTON or WS_TABSTOP or WS_GROUP
                                mov     _hBtnOk, eax
                                invoke  Button_Create, 200 - 80, 100 - 24, 77, 23, hWndDlg, CSTR("Cancel"), 2, WS_TABSTOP or WS_GROUP
                                mov     _hBtnCancel, eax
                                invoke  Label_Create, 10, 13, 100, 15, hWndDlg, CSTR("Anti-Aliasing :"), 0, 0
                                invoke  ComboBox_Create, 90, 10, 100, 150, hWndDlg, NULL, 3, CBS_DROPDOWNLIST or WS_TABSTOP
                                mov     _hCbAntiAliasing, eax
                                invoke  ComboBox_AddItem, _hCbAntiAliasing, CSTR("(None)"), -1
                                invoke  ComboBox_AddItem, _hCbAntiAliasing, CSTR("x2"), -1
                                invoke  ComboBox_AddItem, _hCbAntiAliasing, CSTR("x4"), -1
                                invoke  ComboBox_AddItem, _hCbAntiAliasing, CSTR("x6"), -1
                                invoke  ComboBox_AddItem, _hCbAntiAliasing, CSTR("x8"), -1
                                invoke  ComboBox_SetIndex, _hCbAntiAliasing, 0
                                invoke  CheckBox_Create, 90, 37, 100, 15, hWndDlg, CSTR("Full Screen"), 4, WS_TABSTOP or WS_GROUP
                                mov     _hChkFullScreen, eax
                                invoke  CheckBox_Create, 90, 54, 100, 15, hWndDlg, CSTR("VSync"), 4, WS_TABSTOP or WS_GROUP
                                mov     _hChkVSync, eax
                                invoke  CheckBox_SetState, _hChkVSync, TRUE
                                mov     _Dialog_Result, DIALOG_CANCEL
                        .elseif uMsg == WM_COMMAND
                                mov     eax, lParam
                                .if     eax == _hBtnOk
                                        invoke  Control_Close, hWndDlg
                                        mov     _Dialog_Result, DIALOG_OK
                                        invoke  CheckBox_GetState, _hChkFullScreen
                                        mov     g_FullScreen, eax
                                        invoke  CheckBox_GetState, _hChkVSync
                                        mov     _VSync, eax
                                        mov     _Do_AntiAliasing, TRUE
                                        invoke  ComboBox_GetIndex, _hCbAntiAliasing
                                        shl     eax, 1
                                        mov     _Format_Multi_Samples, eax
                                        .if     eax == 0
                                                mov     _Do_AntiAliasing, FALSE
                                        .endif
                                        xor     eax,eax
                                        ret
                                .elseif eax == _hBtnCancel
                                        invoke  Control_Close, hWndDlg
                                        xor     eax,eax
                                        ret
                                .endif
                        .elseif uMsg == WM_CLOSE
                                invoke  EndDialog, hWndDlg, 0
                        .endif
                        xor     eax,eax
                        ret
DialogProc              endp
