(* OCaml-Win32
 * win32_header.ml
 * Copyright (c) 2002-2004 by Harry Chomsky
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the Free
 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *)

open Win32_core

(********************************************************************)
(* User Interface: Windows User Experience: Windows Shell: SDK: Windows Controls: Individual Control Information: Header Controls *)

let wc_header = "SysHeader32"

type hditem_justification =
    HDF_CENTER
  | HDF_LEFT
  | HDF_RIGHT
type hditem_format_option =
    HDF_BITMAP_ON_RIGHT
  | HDF_IMAGE
  | HDF_OWNERDRAW
  | HDF_RTLREADING
  | HDF_STRING
type hditem_format = {
    hdif_justification : hditem_justification;
    hdif_options : hditem_format_option list }
type hditem = {
    hdi_size : int option;
    hdi_text : common_control_text option;
    hdi_bitmap : hbitmap option;
    hdi_format : hditem_format option;
    hdi_lparam : int32 option;
    hdi_image : common_control_image_index option;
    hdi_order : int option }
let default_hditem = {
    hdi_size = None;
    hdi_text = None;
    hdi_bitmap = None;
    hdi_format = None;
    hdi_lparam = None;
    hdi_image = None;
    hdi_order = None }

type hditem_component =
    Hdi_size
  | Hdi_text of int
  | Hdi_bitmap
  | Hdi_format
  | Hdi_lparam
  | Hdi_image
  | Hdi_order
let all_hditem_components = [
    Hdi_size;
    Hdi_text 256;
    Hdi_bitmap;
    Hdi_format;
    Hdi_lparam;
    Hdi_image;
    Hdi_order ]

(* Styles *)

type header_style_option =
    HDS_BUTTONS
  | HDS_DRAGDROP
  | HDS_FULLDRAG
  | HDS_HIDDEN
  | HDS_HORZ
  | HDS_HOTTRACK

external header_style_of_option : header_style_option -> style = "header_style_of_option"

let header_style_of_options = special_common_control_style_of_options ~special_func:header_style_of_option

(* Messages *)

let hdm_first = 0x1200

let hdm_createdragimage = hdm_first + 16
external pack_hdm_createdragimage : item:int -> message_contents = "pack_hdm_createdragimage"
external unpack_hdm_createdragimage : message_result -> himagelist = "unpack_hdm_createdragimage"
let issue_hdm_createdragimage ~sender ~item = unpack_hdm_createdragimage (sender ~msg:(pack_hdm_createdragimage ~item))

let hdm_deleteitem = hdm_first + 2
external pack_hdm_deleteitem : item:int -> message_contents = "pack_hdm_deleteitem"
external unpack_hdm_deleteitem : message_result -> unit = "unpack_hdm_deleteitem"
let issue_hdm_deleteitem ~sender ~item = unpack_hdm_deleteitem (sender ~msg:(pack_hdm_deleteitem ~item))

let hdm_getimagelist = hdm_first + 9
let pack_hdm_getimagelist = pack_simple_message ~id:hdm_getimagelist
external unpack_hdm_getimagelist : message_result -> himagelist = "unpack_hdm_getimagelist"
let issue_hdm_getimagelist ~sender = unpack_hdm_getimagelist (sender ~msg:pack_hdm_getimagelist)

let hdm_getitem = hdm_first + 3
external issue_hdm_getitem : sender:message_sender -> item:int -> mask:hditem_component list -> hditem = "issue_hdm_getitem"

let hdm_getitemcount = hdm_first + 0
let pack_hdm_getitemcount = pack_simple_message ~id:hdm_getitemcount
external unpack_hdm_getitemcount : message_result -> int = "unpack_hdm_getitemcount"
let issue_hdm_getitemcount ~sender = unpack_hdm_getitemcount (sender ~msg:pack_hdm_getitemcount)

let hdm_getitemrect = hdm_first + 7
external issue_hdm_getitemrect : sender:message_sender -> item:int -> rect = "issue_hdm_getitemrect"

let hdm_getorderarray = hdm_first + 17
external issue_hdm_getorderarray : sender:message_sender -> count:int -> int array = "issue_hdm_getorderarray"

(* hdm_getunicodeformat: use ccm_getunicodeformat *)

let hdm_hittest = hdm_first + 6
type header_hit_test_direction =
    HHT_ABOVE
  | HHT_BELOW
  | HHT_TOLEFT
  | HHT_TORIGHT
type header_hit_test_part =
    HHT_ONDIVIDER
  | HHT_ONDIVOPEN
  | HHT_ONHEADER
type header_hit_test_result =
    Hhtr_outside of header_hit_test_direction list
  | Hhtr_nowhere
  | Hhtr_onitem of int * header_hit_test_part
external issue_hdm_hittest : sender:message_sender -> pt:point -> header_hit_test_result = "issue_hdm_hittest"

let hdm_insertitem = hdm_first + 1
external issue_hdm_insertitem : sender:message_sender -> item:int -> hditem:hditem -> int = "issue_hdm_insertitem"

let hdm_layout = hdm_first + 5
external issue_hdm_layout : sender:message_sender -> rect:rect -> windowpos = "issue_hdm_layout"

let hdm_ordertoindex = hdm_first + 15
external pack_hdm_ordertoindex : order:int -> message_contents = "pack_hdm_ordertoindex"
external unpack_hdm_ordertoindex : message_result -> int = "unpack_hdm_ordertoindex"
let issue_hdm_ordertoindex ~sender ~order = unpack_hdm_ordertoindex (sender ~msg:(pack_hdm_ordertoindex ~order))

let hdm_sethotdivider = hdm_first + 19
type header_hot_spot =
    Hhs_point of point
  | Hhs_index of int
external pack_hdm_sethotdivider : hot_spot:header_hot_spot -> message_contents = "pack_hdm_sethotdivider"
external unpack_hdm_sethotdivider : message_result -> int = "unpack_hdm_sethotdivider"
let issue_hdm_sethotdivider ~sender ~hot_spot = unpack_hdm_sethotdivider (sender ~msg:(pack_hdm_sethotdivider ~hot_spot))

let hdm_setimagelist = hdm_first + 8
external pack_hdm_setimagelist : iml:himagelist -> message_contents = "pack_hdm_setimagelist"
external unpack_hdm_setimagelist : message_result -> himagelist = "unpack_hdm_setimagelist"
let issue_hdm_setimagelist ~sender ~iml = unpack_hdm_setimagelist (sender ~msg:(pack_hdm_setimagelist ~iml))

let hdm_setitem = hdm_first + 4
external issue_hdm_setitem : sender:message_sender -> item:int -> hditem:hditem -> unit = "issue_hdm_setitem"

let hdm_setorderarray = hdm_first + 18
external issue_hdm_setorderarray : sender:message_sender -> order:int array -> unit = "issue_hdm_setorderarray"

(* hdm_setunicodeformat: use ccm_setunicodeformat *)

(* Notifications *)

external unpack_nmcustomdraw_header_item_spec : msg:message_contents -> int = "unpack_nmcustomdraw_header_item_spec"

type nmheader_button =
    Nmhb_left
  | Nmhb_right
  | Nmhb_middle
type nmheader = {
    nmhead_item : int;
    nmhead_button : nmheader_button;
    nmhead_hditem : hditem option }
external unpack_nmheader : msg:message_contents -> nmheader = "unpack_nmheader"

let hdn_first = -300
let hdn_last = -399

let hdn_begindrag = hdn_first - 10
let on_hdn_begindrag = on_notify_message ~code:hdn_begindrag ~unpack:unpack_nmheader ~return:return_common_notify

let hdn_begintrack = hdn_first - 6
let on_hdn_begintrack = on_notify_message ~code:hdn_begintrack ~unpack:unpack_nmheader ~return:return_common_notify

let hdn_dividerdblclick = hdn_first - 5
let on_hdn_dividerdblclick = on_notify_message ~code:hdn_dividerdblclick ~unpack:unpack_nmheader ~return:return_simple_message

let hdn_enddrag = hdn_first - 11
let on_hdn_enddrag = on_notify_message ~code:hdn_enddrag ~unpack:unpack_nmheader ~return:return_common_notify

let hdn_endtrack = hdn_first - 7
let on_hdn_endtrack = on_notify_message ~code:hdn_endtrack ~unpack:unpack_nmheader ~return:return_simple_message

let hdn_getdispinfo = hdn_first - 9
type header_dispinfo = {
    hddi_text : string option;
    hddi_image : int option;
    hddi_lparam : int32 option }
let default_header_dispinfo = {
    hddi_text = None;
    hddi_image = None;
    hddi_lparam = None }
type hdn_getdispinfo_handler =
    wnd:hwnd ->
    msg:message_contents ->
    id:int ->
    hdr:nmhdr ->
    item:int ->
    mask:hditem_component list ->
    (header_dispinfo * bool) message_handler_result
external on_hdn_getdispinfo :
    hdn_getdispinfo_handler ->
    wnd:hwnd ->
    msg:message_contents ->
    message_result option = "on_hdn_getdispinfo"

let hdn_itemchanged = hdn_first - 1
let on_hdn_itemchanged = on_notify_message ~code:hdn_itemchanged ~unpack:unpack_nmheader ~return:return_simple_message

let hdn_itemchanging = hdn_first - 0
let on_hdn_itemchanging = on_notify_message ~code:hdn_itemchanging ~unpack:unpack_nmheader ~return:return_common_notify

let hdn_itemclick = hdn_first - 2
let on_hdn_itemclick = on_notify_message ~code:hdn_itemclick ~unpack:unpack_nmheader ~return:return_simple_message

let hdn_itemdblclick = hdn_first - 3
let on_hdn_itemdblclick = on_notify_message ~code:hdn_itemdblclick ~unpack:unpack_nmheader ~return:return_simple_message

let hdn_track = hdn_first - 8
let on_hdn_track = on_notify_message ~code:hdn_track ~unpack:unpack_simple_notify ~return:return_common_notify
