{.experimental: "codeReordering".}

import winim 

import tables
, lists

const 
  windoww_main_loop_break* = -1
  window_loop_continue* = 1
  window_unregister_message* = 32786

type
 Margins* = object
  up*: int
  down*: int
  left*: int
  right*: int
 
 Win32_Point* = object
  x*: int
  y*: int
 
 Win32_Command_ID* = distinct int 

 Win32_Event_Object = ref object of RootObj 

 Win32_Event* = ref object of Win32_Event_Object
  window*: Win32_Window
  mOrigin*: HWND
  mMsg*: UINT
  command_id*: Win32_Command_ID
  w_param*: WPARAM
  l_param*: LPARAM
  userData*: int
  skip*: bool
  propagationLevel*: int
  l_result*: LRESULT
  key_status*: array[256, int8] # use int8 so that we can test if it < 0
  mouse_Position*: Win32_Point
  client_Position*: Win32_Point
  
 # Event handler with event object as parameter.
 Win32_Event_Proc* = proc (event: Win32_Event)

 # Event handler without parameter.
 Win32_Event_Neat_Proc* = proc ()

 Win32_Message_Loop_Hook_Proc* = proc (msg: var MSG 
                                                                       , modal_hwnd: HWND
                                                                       ): int
     ## Hook procedure to the message loop. *modalHwnd* is not 0 if it is a modal
     ## window message loop instead of main loop. Returns > 0 to continue(skip) the loop,
     ## and returns < 0 to break(exit) the loop.
     ## 
 Win32_Hook_Proc* = proc ( self: Win32_Window
                                             , message: UINT
                                              , wParam: WPARAM
                                              , lParam: LPARAM
                                              ): bool

 Win32_Event_Connection* = object
  message: UINT
  id*: Win32_Command_ID
  handler*: Win32_Event_Proc
  neat_handler*: Win32_Event_Neat_Proc
  user_data*: int
  is_undeletable*: bool
 
 Win32_Drop_Target* = object
    lpVtbl*: ptr IDropTargetVtbl
    vtbl*: IDropTargetVtbl
    self*: Win32_Window
    effect*: DWORD

 Win32_Draggable_Info* = ref object
  is_enabled*: bool
  is_in_client*: bool
  is_dragging*: bool
  start_mouse_position*: Win32_Point
  start_position*: Win32_Point
  connection*: array[3,Win32_Event_Connection] # move, up, down
 
 Direction* = object
  up*: int
  down*: int
  left*: int
  right*: int

 Win32_Sizing_Info* = ref object
  border*: Direction
  dragging*: bool
  ready*: tuple[up, down, left, right: bool]
  offset*: Direction
  connection*: array[3,Win32_Event_Connection] # move, up, down

 Win32_Accelerator_Table* = ref object of RootObj
  handle*: HACCEL
  accels*: seq[ACCEL]
  was_modified*: bool

 Win32_Status_Bar* = ref object of Win32_Window
  filed_Numbers*: int
  widths*: array[256, int32]
  help_index*: int
  size_connection*: Win32_Event_Connection
 
 Win32_Gdi_Object* = ref object of RootObj
  handle*: HANDLE
  is_deletable*: bool

 Win32_Brush* = ref object of Win32_Gdi_Object
  color*: int32
  style*: DWORD
 
 Win32_Pen* = ref object of Win32_Gdi_Object
  color*: int32
  style*: DWORD
  width*: int
 
 Win32_Bitmap* = ref object of Win32_Gdi_Object
  width*: int
  height*: int
  depth*: int  
  
 Win32_Icon* = ref object of Win32_Gdi_Object
  width*: int
  height*: int
  
 Win32_Size* = object
  width*: int
  height*: int

 Win32_Cursor* = ref object of Win32_Gdi_Object
  width*: int
  height*: int
  hotspot*: Win32_Point
  has_icon_resource*: bool

 Win32_Font* = ref object of Win32_Gdi_Object
  point_size*: float
  family*: int
  weight*: int
  is_italic*: bool
  underline*: bool
  strikeout*: bool
  face_name*: string
  encoding*: int

 Win32_Menu_Item_Kind* = enum
  Normal
  Separator
  Check
  Radio
  Sub_Menu

 Win32_Menu_Base* = ref object of RootObj
  h_menu*: HMENU
 
 Win32_Menu_Item* = ref object of RootObj
  id*: Win32_Command_ID
  menu_item_kind*: Win32_Menu_Item_Kind
  text*: string
  help_string*: string
  bitmap*: Win32_Bitmap
  submenu*: Win32_Menu
  data*: int

 Win32_Menu* = ref object of Win32_Menu_Base
  bitmap*: Win32_Bitmap
  item_list*: seq[Win32_Menu_Item]
  is_deletable*: bool

 Win32_Toolbar_Tool* = ref object of RootObj
   bitmap*: Win32_Bitmap
   short_help*: string
   long_help*: string
   menu*: Win32_Menu

 Win32_Toolbar* = ref object of Win32_Window
  tools*: seq[Win32_Toolbar_Tool]
  size_connection*: Win32_Event_Connection
  command_connection*: Win32_Event_Connection
 

 Win32_Image_List* = ref object of RootObj
   handle*: HIMAGELIST

 Win32_Rebar* = ref object of Win32_Control
  controls*: seq[Win32_Control]
  image_list*: Win32_Image_List
  size_connection*: Win32_Event_Connection
  dragging*: bool
  can_min_max*: bool
  can_drag*: bool
 
 Win32_Control* = ref object of Win32_Window_Object

 Win32_Window_Object = object of RootObj
  hwnd*: HWND
  parent_window*: Win32_Window
  sub_windows*: seq[Win32_Window]
  data*: int
  class_name*: string
  is_registered*: bool
  system_connection_table*: Table[UINT, DoublyLinkedList[Win32_Event_Connection]]
  connection_table*: Table[UINT, DoublyLinkedList[Win32_Event_Connection]]
  margins*: Margins
  status_bar*: Win32_Status_Bar
  toolbars*: seq[Win32_Toolbar]
  rebar*: Win32_Rebar
  font*: Win32_Font
  background_color*: int32
  foreground_color*: int32
  background_brush*: Win32_Brush
  cursor*: Win32_Cursor
  overrided_cursor*: Win32_Cursor
  accelerator_table*: Win32_Accelerator_Table
  popup_menu*: Win32_Menu
  save_focus_hwnd*: HWND
  is_focusable*: bool
  mouse_In_window*: bool
  max_size*: Win32_Size
  min_size*: Win32_Size
  dummy_parent*: HWND
  tip_hwnd*: HWND
  sizing_info*: Win32_Sizing_Info
  draggable_info*: Win32_Draggable_Info
  drop_target*: ref Win32_Drop_Target
  hook_proc*: Win32_Hook_Proc
  
 
 Win32_Window* = ref object of Win32_Window_Object