/* OCaml-Win32
 * win32_ipaddress.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: IP Address Controls */

CAMLprim value pack_ip_address(value val)
{
    return copy_int32(MAKEIPADDRESS(
        Int_val(Field(val, 0)),
        Int_val(Field(val, 1)),
        Int_val(Field(val, 2)),
        Int_val(Field(val, 3))));
}

CAMLprim value unpack_ip_address(value addr)
{
    CAMLparam1(addr);
    DWORD dw;
    CAMLlocal1(val);

    dw = Int32_val(addr);
    val = alloc_tuple(4);
    Store_field(val, 0, Val_int(FIRST_IPADDRESS(dw)));
    Store_field(val, 1, Val_int(SECOND_IPADDRESS(dw)));
    Store_field(val, 2, Val_int(THIRD_IPADDRESS(dw)));
    Store_field(val, 3, Val_int(FOURTH_IPADDRESS(dw)));
    CAMLreturn(val);
}

/* Messages */

CAMLprim value issue_ipm_getaddress(value sender)
{
    CAMLparam1(sender);
    DWORD dw;
    CAMLlocal4(contents, result, val, v);

    contents = pack_message(IPM_GETADDRESS, 0, (LPARAM)&dw);
    result = callback(sender, contents);
    val = alloc_tuple(2);
    v = copy_int32(dw);
    Store_field(val, 0, v);
    Store_field(val, 1, Val_int(Int32_val(result)));
    CAMLreturn(val);
}

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

CAMLprim value pack_ipm_setaddress(value address)
{
    return pack_message(IPM_SETADDRESS, 0, Int32_val(address));
}

CAMLprim value pack_ipm_setfocus(value field)
{
    return pack_message(IPM_SETFOCUS, Int_val(field), 0);
}

CAMLprim value pack_ipm_setrange(value field, value range)
{
    return pack_message(IPM_SETRANGE, Int_val(field), MAKEIPRANGE(Int_val(Field(range, 0)), Int_val(Field(range, 1))));
}

CAMLprim value unpack_ipm_setrange(value result)
{
    if (Int32_val(result) == 0)
        raise_win32_error(0);
    return Val_unit;
}

/* Notifications */

CAMLprim value on_ipn_fieldchanged(value handler, value wnd, value msg)
{
    CAMLparam3(handler, wnd, msg);
    NMHDR* nmh;
    NMIPADDRESS* nmipa;
    CAMLlocalN(args, 6);
    CAMLlocal2(result, ret);

    ret = Val_none;
    if (Int_val(Field(msg, 0)) == WM_NOTIFY) {
        nmh = (NMHDR*)Lparam(msg);
        if (nmh->code == IPN_FIELDCHANGED) {
            nmipa = (NMIPADDRESS*)nmh;
            args[0] = wnd;
            args[1] = msg;
            args[2] = Val_int(Wparam(msg));
            args[3] = alloc_nmhdr(nmh);
            args[4] = Val_int(nmipa->iField);
            args[5] = Val_int(nmipa->iValue);
            result = callbackN(handler, 6, args);
            if (Is_block(result)) {
                if (Tag_val(result) == 0)
                    ret = alloc_some(Field(result, 0));
                else {
                    nmipa->iValue = Int_val(Field(result, 0));
                    ret = alloc_some(copy_int32(0));
                }
            }
        }
    }
    CAMLreturn(ret);
}
