/* OCaml-Win32
 * win32_trackbar.c
 * 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.
 */

#include "win32.h"

/********************************************************************/
/* User Interface: Windows User Experience: Windows Shell: SDK: Windows Controls: Individual Control Information: Trackbar Controls */

/* Styles */

static DWORD trackbar_style_options[] = {
    TBS_AUTOTICKS,
    TBS_BOTH,
    TBS_BOTTOM,
    TBS_ENABLESELRANGE,
    TBS_FIXEDLENGTH,
    TBS_HORZ,
    TBS_LEFT,
    TBS_NOTHUMB,
    TBS_NOTICKS,
    TBS_RIGHT,
    TBS_TOOLTIPS,
    TBS_TOP,
    TBS_VERT
};
Define_static_constants(trackbar_style_options);

CAMLprim value trackbar_style_of_option(value option)
{
    return copy_int64((int64)Constant_val(option, trackbar_style_options));
}

/* Messages */

CAMLprim value pack_tbm_clearsel(value redraw)
{
    return pack_message(TBM_CLEARSEL, Bool_val(redraw), 0);
}

CAMLprim value pack_tbm_cleartics(value redraw)
{
    return pack_message(TBM_CLEARTICS, Bool_val(redraw), 0);
}

CAMLprim value pack_tbm_getbuddy(value location)
{
    return pack_message(TBM_GETBUDDY, Bool_val(location), 0);
}

CAMLprim value unpack_tbm_getbuddy(value result)
{
    return alloc_handle((HWND)Int32_val(result));
}

CAMLprim value issue_tbm_getchannelrect(value sender)
{
    CAMLparam1(sender);
    RECT r;
    CAMLlocal2(contents, val);

    contents = pack_message(TBM_GETCHANNELRECT, 0, (LPARAM)&r);
    callback(sender, contents);
    val = alloc_rect(&r);
    CAMLreturn(val);
}

CAMLprim value unpack_tbm_getlinesize(value result)
{
    return Val_int(Int32_val(result));
}

CAMLprim value unpack_tbm_getnumtics(value result)
{
    return Val_int(Int32_val(result));
}

CAMLprim value unpack_tbm_getpagesize(value result)
{
    return Val_int(Int32_val(result));
}

CAMLprim value unpack_tbm_getpos(value result)
{
    return Val_int(Int32_val(result));
}

CAMLprim value issue_tbm_getptics(value sender, value tics)
{
    CAMLparam2(sender, tics);
    CAMLlocal2(contents, result);
    DWORD* p;
    int n, i;

    contents = pack_message(TBM_GETPTICS, 0, 0);
    result = callback(sender, contents);
    p = (DWORD*)Int32_val(result);
    n = Wosize_val(tics);
    for (i = 0; i < n; ++i)
        Store_field(tics, i, Val_int(p[i]));
    CAMLreturn(Val_unit);
}

CAMLprim value unpack_tbm_getrangemax(value result)
{
    return Val_int(Int32_val(result));
}

CAMLprim value unpack_tbm_getrangemin(value result)
{
    return Val_int(Int32_val(result));
}

CAMLprim value unpack_tbm_getselend(value result)
{
    return Val_int(Int32_val(result));
}

CAMLprim value unpack_tbm_getselstart(value result)
{
    return Val_int(Int32_val(result));
}

CAMLprim value unpack_tbm_getthumblength(value result)
{
    return Val_int(Int32_val(result));
}

CAMLprim value issue_tbm_getthumbrect(value sender)
{
    CAMLparam1(sender);
    RECT r;
    CAMLlocal2(contents, val);

    contents = pack_message(TBM_GETTHUMBRECT, 0, (LPARAM)&r);
    callback(sender, contents);
    val = alloc_rect(&r);
    CAMLreturn(val);
}

CAMLprim value pack_tbm_gettic(value tic)
{
    return pack_message(TBM_GETTIC, Int_val(tic), 0);
}

CAMLprim value unpack_tbm_gettic(value result)
{
    int pos;

    pos = Int32_val(result);
    if (pos == -1)
        raise_win32_error(0);
    return Val_int(pos);
}

CAMLprim value pack_tbm_getticpos(value tic)
{
    return pack_message(TBM_GETTICPOS, Int_val(tic), 0);
}

CAMLprim value unpack_tbm_getticpos(value result)
{
    int pos;

    pos = Int32_val(result);
    if (pos == -1)
        raise_win32_error(0);
    return Val_int(pos);
}

CAMLprim value unpack_tbm_gettooltips(value result)
{
    return alloc_handle((HWND)Int32_val(result));
}

CAMLprim value pack_tbm_setbuddy(value location, value buddy)
{
    return pack_message(TBM_SETBUDDY, Bool_val(location), (LPARAM)Handle_val(buddy));
}

CAMLprim value unpack_tbm_setbuddy(value result)
{
    return alloc_handle((HWND)Int32_val(result));
}

CAMLprim value pack_tbm_setlinesize(value size)
{
    return pack_message(TBM_SETLINESIZE, 0, Int_val(size));
}

CAMLprim value unpack_tbm_setlinesize(value result)
{
    return Val_int(Int32_val(result));
}

CAMLprim value pack_tbm_setpagesize(value size)
{
    return pack_message(TBM_SETPAGESIZE, 0, Int_val(size));
}

CAMLprim value unpack_tbm_setpagesize(value result)
{
    return Val_int(Int32_val(result));
}

CAMLprim value pack_tbm_setpos(value pos, value redraw)
{
    return pack_message(TBM_SETPOS, Bool_val(redraw), Int_val(pos));
}

CAMLprim value pack_tbm_setrange(value range, value redraw)
{
    return pack_message(TBM_SETRANGE,
        Bool_val(redraw), MAKELONG(Int_val(Field(range, 0)), Int_val(Field(range, 1))));
}

CAMLprim value pack_tbm_setrangemax(value max, value redraw)
{
    return pack_message(TBM_SETRANGEMAX, Bool_val(redraw), Int_val(max));
}

CAMLprim value pack_tbm_setrangemin(value min, value redraw)
{
    return pack_message(TBM_SETRANGEMIN, Bool_val(redraw), Int_val(min));
}

CAMLprim value pack_tbm_setsel(value sel, value redraw)
{
    return pack_message(TBM_SETSEL,
        Bool_val(redraw), MAKELONG(Int_val(Field(sel, 0)), Int_val(Field(sel, 1))));
}

CAMLprim value pack_tbm_setselend(value pos, value redraw)
{
    return pack_message(TBM_SETSELEND, Bool_val(redraw), Int_val(pos));
}

CAMLprim value pack_tbm_setselstart(value pos, value redraw)
{
    return pack_message(TBM_SETSELSTART, Bool_val(redraw), Int_val(pos));
}

CAMLprim value pack_tbm_setthumblength(value length)
{
    return pack_message(TBM_SETTHUMBLENGTH, Int_val(length), 0);
}

CAMLprim value pack_tbm_settic(value pos)
{
    return pack_message(TBM_SETTIC, 0, Int_val(pos));
}

CAMLprim value unpack_tbm_settic(value result)
{
    return Val_bool(Int32_val(result) != 0);
}

CAMLprim value pack_tbm_setticfreq(value freq)
{
    return pack_message(TBM_SETTICFREQ, Int_val(freq), 0);
}

static DWORD trackbar_tip_sides[] = {
    TBTS_TOP,
    TBTS_LEFT,
    TBTS_BOTTOM,
    TBTS_RIGHT
};
Define_static_constants(trackbar_tip_sides);

CAMLprim value pack_tbm_settipside(value side)
{
    return pack_message(TBM_SETTIPSIDE, Constant_val(side, trackbar_tip_sides), 0);
}

CAMLprim value unpack_tbm_settipside(value result)
{
    return Val_constant(Int32_val(result), trackbar_tip_sides);
}

CAMLprim value pack_tbm_settooltips(value tooltips)
{
    return pack_message(TBM_SETTOOLTIPS, (WPARAM)Handle_val(tooltips), 0);
}

/* Notifications */

static DWORD trackbar_customdraw_parts[] = {
    TBCD_CHANNEL,
    TBCD_THUMB,
    TBCD_TICS
};
Define_static_constants(trackbar_customdraw_parts);

CAMLprim value unpack_nmcustomdraw_trackbar_item_spec(value msg)
{
    NMCUSTOMDRAW* nmcd;

    nmcd = (NMCUSTOMDRAW*)Lparam(msg);
    return Val_constant(nmcd->dwItemSpec, trackbar_customdraw_parts);
}
