/*
* TWAIN32 Options UI
*
* Copyright 2006 CodeWeavers, Aric Stewart
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/

#include "config.h"

#include <stdlib.h>
#include <stdarg.h>
#include <stdio.h>

#define NONAMELESSUNION
#define NONAMELESSSTRUCT
#include "windef.h"
#include "winbase.h"
#include "winuser.h"
#include "winnls.h"
#include "wingdi.h"
#include "prsht.h"
#include "twain.h"
#include "sane_i.h"
#include "wine/debug.h"
#include "resource.h"

#ifdef SONAME_LIBSANE

WINE_DEFAULT_DEBUG_CHANNEL(twain);

#define ID_BASE 0x100
#define ID_EDIT_BASE 0x1000
#define ID_STATIC_BASE 0x2000

static INT_PTR CALLBACK DialogProc (HWND , UINT , WPARAM , LPARAM );
static INT CALLBACK PropSheetProc(HWND, UINT,LPARAM);

static int create_leading_static(HDC hdc, LPCSTR text,
        LPDLGITEMTEMPLATEW* template_out, int y, int id)
{
    LPDLGITEMTEMPLATEW tpl =  NULL;
    INT len;
    SIZE size;
    LPBYTE ptr;
    LONG base;

    *template_out = NULL;

    if (!text)
        return 0;

    base = GetDialogBaseUnits();

    len = MultiByteToWideChar(CP_ACP,0,text,-1,NULL,0);
    len *= sizeof(WCHAR);
    len += sizeof(DLGITEMTEMPLATE);
    len += 3*sizeof(WORD);

    tpl = HeapAlloc(GetProcessHeap(),0,len);
    tpl->style=WS_VISIBLE;
    tpl->dwExtendedStyle = 0;
    tpl->x = 4;
    tpl->y = y;
    tpl->id = ID_BASE;

    GetTextExtentPoint32A(hdc,text,lstrlenA(text),&size);

    tpl->cx =  MulDiv(size.cx,4,LOWORD(base));
    tpl->cy =  MulDiv(size.cy,8,HIWORD(base)) * 2;
    ptr = (LPBYTE)tpl + sizeof(DLGITEMTEMPLATE);
    *(LPWORD)ptr = 0xffff;
    ptr += sizeof(WORD);
    *(LPWORD)ptr = 0x0082;
    ptr += sizeof(WORD);
    ptr += MultiByteToWideChar(CP_ACP,0,text,-1,(LPWSTR)ptr,len) * sizeof(WCHAR);
    *(LPWORD)ptr = 0x0000;

    *template_out = tpl;
    return len;
}

static int create_trailing_edit(HDC hdc, LPDLGITEMTEMPLATEW* template_out, int id,
        int y, LPCSTR text,BOOL is_int)
{
    LPDLGITEMTEMPLATEW tpl =  NULL;
    INT len;
    LPBYTE ptr;
    SIZE size;
    LONG base;
    static const char int_base[] = "0000 xxx";
    static const char float_base[] = "0000.0000 xxx";

    base = GetDialogBaseUnits();

    len = MultiByteToWideChar(CP_ACP,0,text,-1,NULL,0);
    len *= sizeof(WCHAR);
    len += sizeof(DLGITEMTEMPLATE);
    len += 3*sizeof(WORD);

    tpl = HeapAlloc(GetProcessHeap(),0,len);
    tpl->style=WS_VISIBLE|ES_READONLY|WS_BORDER;
    tpl->dwExtendedStyle = 0;
    tpl->x = 1;
    tpl->y = y;
    tpl->id = id;

    if (is_int)
        GetTextExtentPoint32A(hdc,int_base,lstrlenA(int_base),&size);
    else
        GetTextExtentPoint32A(hdc,float_base,lstrlenA(float_base),&size);

    tpl->cx =  MulDiv(size.cx*2,4,LOWORD(base));
    tpl->cy =  MulDiv(size.cy,8,HIWORD(base)) * 2;

    ptr = (LPBYTE)tpl + sizeof(DLGITEMTEMPLATE);
    *(LPWORD)ptr = 0xffff;
    ptr += sizeof(WORD);
    *(LPWORD)ptr = 0x0081;
    ptr += sizeof(WORD);
    ptr += MultiByteToWideChar(CP_ACP,0,text,-1,(LPWSTR)ptr,len) * sizeof(WCHAR);
    *(LPWORD)ptr = 0x0000;

    *template_out = tpl;
    return len;
}


static int create_item(HDC hdc, const SANE_Option_Descriptor *opt,
        INT id, LPDLGITEMTEMPLATEW *template_out, int y, int *cx, int* count)
{
    LPDLGITEMTEMPLATEW tpl = NULL,rc = NULL;
    WORD class = 0xffff;
    DWORD styles = WS_VISIBLE;
    LPBYTE ptr = NULL;
    LPDLGITEMTEMPLATEW lead_static = NULL;
    LPDLGITEMTEMPLATEW trail_edit = NULL;
    DWORD leading_len = 0;
    DWORD trail_len = 0;
    DWORD local_len = 0;
    LPCSTR title = NULL;
    CHAR buffer[255];
    int padding = 0;
    int padding2 = 0;
    int base_x = 0;
    LONG base;
    int ctl_cx = 0;
    SIZE size;

    GetTextExtentPoint32A(hdc,"X",1,&size);
    base = GetDialogBaseUnits();
    base_x = MulDiv(size.cx,4,LOWORD(base));

    if (opt->type == SANE_TYPE_BOOL)
    {
        class = 0x0080; /* Button */
        styles |= BS_AUTOCHECKBOX;
        local_len += MultiByteToWideChar(CP_ACP,0,opt->title,-1,NULL,0);
        local_len *= sizeof(WCHAR);
        title = opt->title;
    }
    else if (opt->type == SANE_TYPE_INT)
    {
        SANE_Int i;

        psane_control_option(activeDS.deviceHandle, id-ID_BASE,
                SANE_ACTION_GET_VALUE, &i,NULL);

        sprintf(buffer,"%i",i);

        if (opt->constraint_type == SANE_CONSTRAINT_NONE)
        {
            class = 0x0081; /* Edit*/
            styles |= ES_NUMBER;
            title = buffer;
            local_len += MultiByteToWideChar(CP_ACP,0,title,-1,NULL,0);
            local_len *= sizeof(WCHAR);
        }
        else if (opt->constraint_type == SANE_CONSTRAINT_RANGE)
        {
            class = 0x0084; /* scroll */
            ctl_cx = 10 * base_x;
            trail_len += create_trailing_edit(hdc, &trail_edit, id +
                    ID_EDIT_BASE, y,buffer,TRUE);
        }
        else
        {
            class= 0x0085; /* Combo */
            ctl_cx = 10 * base_x;
            styles |= CBS_DROPDOWNLIST;
        }
        leading_len += create_leading_static(hdc, opt->title, &lead_static, y, 
                id+ID_STATIC_BASE);
    }
    else if (opt->type == SANE_TYPE_FIXED)
    {
        SANE_Fixed *i;
        double dd;

        i = HeapAlloc(GetProcessHeap(),0,opt->size*sizeof(SANE_Word));

        psane_control_option(activeDS.deviceHandle, id-ID_BASE,
                SANE_ACTION_GET_VALUE, i, NULL);

        dd = SANE_UNFIX(*i);
        sprintf(buffer,"%f",dd);
        HeapFree(GetProcessHeap(),0,i);

        if (opt->constraint_type == SANE_CONSTRAINT_NONE)
        {
            class = 0x0081; /* Edit */
            title = buffer;
            local_len += MultiByteToWideChar(CP_ACP,0,title,-1,NULL,0);
            local_len *= sizeof(WCHAR);
        }
        else if (opt->constraint_type == SANE_CONSTRAINT_RANGE)
        {
            class= 0x0084; /* scroll */
            ctl_cx = 10 * base_x;
            trail_len += create_trailing_edit(hdc, &trail_edit, id +
                    ID_EDIT_BASE, y,buffer,FALSE);
        }
        else
        {
            class= 0x0085; /* Combo */
            ctl_cx = 10 * base_x;
            styles |= CBS_DROPDOWNLIST;
        }
        leading_len += create_leading_static(hdc, opt->title, &lead_static, y,
                id+ID_STATIC_BASE);
    }
    else if (opt->type == SANE_TYPE_STRING)
    {
        if (opt->constraint_type == SANE_CONSTRAINT_NONE)
        {
            class = 0x0081; /* Edit*/
        }
        else
        {
            class= 0x0085; /* Combo */
            ctl_cx = opt->size * base_x;
            styles |= CBS_DROPDOWNLIST;
        }
        leading_len += create_leading_static(hdc, opt->title, &lead_static, y,
                id+ID_STATIC_BASE);
        psane_control_option(activeDS.deviceHandle, id-ID_BASE,
                SANE_ACTION_GET_VALUE, buffer,NULL);

        title = buffer;
        local_len += MultiByteToWideChar(CP_ACP,0,title,-1,NULL,0);
        local_len *= sizeof(WCHAR);
    }
    else if (opt->type == SANE_TYPE_BUTTON)
    {
        class = 0x0080; /* Button */
        local_len += MultiByteToWideChar(CP_ACP,0,opt->title,-1,NULL,0);
        local_len *= sizeof(WCHAR);
        title = opt->title;
    }
    else if (opt->type == SANE_TYPE_GROUP)
    {
        class = 0x0080; /* Button */
        styles |= BS_GROUPBOX;
        local_len += MultiByteToWideChar(CP_ACP,0,opt->title,-1,NULL,0);
        local_len *= sizeof(WCHAR);
        title = opt->title;
    }

    local_len += sizeof(DLGITEMTEMPLATE);
    if (title)
        local_len += 3*sizeof(WORD);
    else
        local_len += 4*sizeof(WORD);

    if (lead_static)
    {
        padding = leading_len % sizeof(DWORD);
        rc = HeapReAlloc(GetProcessHeap(),0,lead_static,leading_len+local_len + padding);
        tpl = (LPDLGITEMTEMPLATEW)((LPBYTE)rc + leading_len + padding);
    }   
    else
        rc = tpl = HeapAlloc(GetProcessHeap(),0,local_len);

    tpl->style=styles;
    tpl->dwExtendedStyle = 0;
    if (lead_static)
        tpl->x = lead_static->x + lead_static->cx + 1;
    else if (opt->type == SANE_TYPE_GROUP)
        tpl->x = 2;
    else
        tpl->x = 4;
    tpl->y = y;
    tpl->id = id;

    if (title)
    {
        GetTextExtentPoint32A(hdc,title,lstrlenA(title),&size);
        tpl->cx = size.cx;
        tpl->cy = size.cy;
    }
    else
    {
        if (lead_static)
            tpl->cy = lead_static->cy;
        else
            tpl->cy = 15;

        if (!ctl_cx)
            ctl_cx = 15;

        tpl->cx = ctl_cx;
    }
    ptr = (LPBYTE)tpl + sizeof(DLGITEMTEMPLATE);
    *(LPWORD)ptr = 0xffff;
    ptr += sizeof(WORD);
    *(LPWORD)ptr = class;
    ptr += sizeof(WORD);
    if (title)
    {
        ptr += MultiByteToWideChar(CP_ACP,0,title,-1,(LPWSTR)ptr,local_len) * sizeof(WCHAR);
    }
    else
    {
        *(LPWORD)ptr = 0x0000;
        ptr += sizeof(WORD);
    }

    *((LPWORD)ptr) = 0x0000;
    ptr += sizeof(WORD);

    if (trail_edit)
    {
        trail_edit->x = tpl->cx + tpl->x + 2;
        *cx = trail_edit->x + trail_edit->cx;

        padding2 = (leading_len + local_len + padding)% sizeof(DWORD);

        rc = HeapReAlloc(GetProcessHeap(),0,rc,leading_len+local_len + padding
                +padding2+trail_len);

        memcpy(((LPBYTE)rc) + leading_len + local_len + padding + padding2,
                trail_edit,trail_len);
    }   
    else
        *cx = tpl->cx + tpl->x;
    
    *template_out = rc;
    if (leading_len)
        *count = 2;
    else
        *count = 1;

    if (trail_edit)
        *count+=1;

    return leading_len + local_len + padding + padding2 + trail_len;
}


static LPDLGTEMPLATEW create_options_page(HDC hdc, int *from_index,
                                          BOOL split_tabs)
{
    SANE_Status rc;
    SANE_Int optcount;
    int i;
    INT y = 2;
    LPDLGTEMPLATEW tpl = NULL;
    LPBYTE all_controls = NULL;
    DWORD control_len = 0;
    int max_cx = 0;
    int group_max_cx = 0;
    LPBYTE ptr;
    int group_offset = -1;
    INT control_count = 0;

    rc = psane_control_option(activeDS.deviceHandle, 0, SANE_ACTION_GET_VALUE,
            &optcount, NULL);

    if (rc != SANE_STATUS_GOOD)
    {
        ERR("Unable to read number of options\n");
        return NULL;
    }

    for (i = *from_index; i < optcount; i++)
    {
        LPDLGITEMTEMPLATEW item_tpl = NULL;
        const SANE_Option_Descriptor *opt;
        int len;
        int padding = 0;
        int x;
        int count;
        int hold_for_group = 0;

        opt = psane_get_option_descriptor(activeDS.deviceHandle, i);
        if (opt->type == SANE_TYPE_GROUP && split_tabs)
        {
            if (control_len > 0)
            {
                *from_index = i - 1;
                goto exit;
            }
            else
            {
                *from_index = i;
                return NULL;
            }
        }

        len = create_item(hdc, opt, ID_BASE + i, &item_tpl, y, &x, &count);

        control_count += count;

        if (!len)
        {
            continue;
        }

        hold_for_group = y;
        y+= item_tpl->cy + 1;
        max_cx = max(max_cx, x + 2);
        group_max_cx = max(group_max_cx, x );

        padding = len % sizeof(DWORD);

        if (all_controls)
        {
            LPBYTE newone;
            newone = HeapReAlloc(GetProcessHeap(),0,all_controls,
                    control_len + len + padding);
            all_controls = newone;
            memcpy(all_controls+control_len,item_tpl,len);
            memset(all_controls+control_len+len,0xca,padding);
            HeapFree(GetProcessHeap(),0,item_tpl);
        }
        else
        {
            if (!padding)
            {
                all_controls = (LPBYTE)item_tpl;
            }
            else
            {
                all_controls = HeapAlloc(GetProcessHeap(),0,len + padding);
                memcpy(all_controls,item_tpl,len);
                memset(all_controls+len,0xcb,padding);
                HeapFree(GetProcessHeap(),0,item_tpl);
            }
        }

        if (opt->type == SANE_TYPE_GROUP)
        {
            if (group_offset == -1)
            {
                group_offset  = control_len;
                group_max_cx = 0;
            }
            else
            {
                LPDLGITEMTEMPLATEW group =
                    (LPDLGITEMTEMPLATEW)(all_controls+group_offset);

                group->cy = hold_for_group - group->y;
                group->cx = group_max_cx;

                group = (LPDLGITEMTEMPLATEW)(all_controls+control_len);
                group->y += 2;
                y+=2;
                group_max_cx = 0;
                group_offset  = control_len;
            }
        }

        control_len += len + padding;
    }

    if ( group_offset && !split_tabs )
    {
        LPDLGITEMTEMPLATEW group =
            (LPDLGITEMTEMPLATEW)(all_controls+group_offset);
        group->cy = y - group->y;
        group->cx = group_max_cx;
        y+=2;
    }

    *from_index = i-1;
exit:

    tpl = HeapAlloc(GetProcessHeap(),0,sizeof(DLGTEMPLATE) + 3*sizeof(WORD) + 
            control_len);

    tpl->style = WS_VISIBLE | WS_OVERLAPPEDWINDOW;
    tpl->dwExtendedStyle = 0;
    tpl->cdit = control_count;
    tpl->x = 0;
    tpl->y = 0;
    tpl->cx = max_cx + 10;
    tpl->cy = y + 10;
    ptr = (LPBYTE)tpl + sizeof(DLGTEMPLATE);
    *(LPWORD)ptr = 0x0000;
    ptr+=sizeof(WORD);
    *(LPWORD)ptr = 0x0000;
    ptr+=sizeof(WORD);
    *(LPWORD)ptr = 0x0000;
    ptr+=sizeof(WORD);
    memcpy(ptr,all_controls,control_len);

    HeapFree(GetProcessHeap(),0,all_controls);

    return tpl;
}

BOOL DoScannerUI(void)
{
    HDC hdc;
    PROPSHEETPAGEW psp[10];
    int page_count= 0;
    PROPSHEETHEADERW psh;
    int index = 1;
    SANE_Status rc;
    SANE_Int optcount;
    UINT psrc;
    LPWSTR szCaption;
    DWORD len;

    hdc = GetDC(0);

    memset(&psp,0,sizeof(psp));
    rc = psane_control_option(activeDS.deviceHandle, 0, SANE_ACTION_GET_VALUE,
            &optcount, NULL);

    while (index < optcount)
    {
        const SANE_Option_Descriptor *opt;
        psp[page_count].u.pResource = create_options_page(hdc, &index,
                TRUE);
        opt = psane_get_option_descriptor(activeDS.deviceHandle, index);

        if (opt->type == SANE_TYPE_GROUP)
        {
            LPWSTR title = NULL;
            INT len;

            len = MultiByteToWideChar(CP_ACP,0,opt->title,-1,NULL,0);
            title = HeapAlloc(GetProcessHeap(),0,len * sizeof(WCHAR));
            MultiByteToWideChar(CP_ACP,0,opt->title,-1,title,len);

            psp[page_count].pszTitle = title;
        }

        if (psp[page_count].u.pResource)
        {
            psp[page_count].dwSize = sizeof(PROPSHEETPAGEW);
            psp[page_count].dwFlags =  PSP_DLGINDIRECT | PSP_USETITLE;
            psp[page_count].hInstance = SANE_instance;
            psp[page_count].pfnDlgProc = DialogProc;
            psp[page_count].lParam = (LPARAM)&activeDS;
            page_count ++;
        }
       
        index ++;
    }
 
    len = lstrlenA(activeDS.identity.Manufacturer)
         + lstrlenA(activeDS.identity.ProductName) + 2;
    szCaption = HeapAlloc(GetProcessHeap(),0,len *sizeof(WCHAR));
    MultiByteToWideChar(CP_ACP,0,activeDS.identity.Manufacturer,-1,
            szCaption,len);
    szCaption[lstrlenA(activeDS.identity.Manufacturer)] = ' ';
    MultiByteToWideChar(CP_ACP,0,activeDS.identity.ProductName,-1,
            &szCaption[lstrlenA(activeDS.identity.Manufacturer)+1],len);
    psh.dwSize = sizeof(PROPSHEETHEADERW);
    psh.dwFlags = PSH_PROPSHEETPAGE|PSH_PROPTITLE|PSH_USECALLBACK;
    psh.hwndParent = activeDS.hwndOwner;
    psh.hInstance = SANE_instance;
    psh.u.pszIcon = 0;
    psh.pszCaption = szCaption;
    psh.nPages = page_count;
    psh.u2.nStartPage = 0;
    psh.u3.ppsp = (LPCPROPSHEETPAGEW) &psp;
    psh.pfnCallback = PropSheetProc;

    psrc = PropertySheetW(&psh);

    for(index = 0; index < page_count; index ++)
    {
        HeapFree(GetProcessHeap(),0,(LPBYTE)psp[index].u.pResource);
        HeapFree(GetProcessHeap(),0,(LPBYTE)psp[index].pszTitle);
    }
    
    if (psrc == IDOK)
        return TRUE;
    else
        return FALSE;
}

static void UpdateRelevantEdit(HWND hwnd, const SANE_Option_Descriptor *opt, 
        int index, int position)
{
    CHAR buffer[244];
    HWND edit_w;
    CHAR unit[20];

    LoadStringA(SANE_instance, opt->unit, unit,20);

    if (opt->type == SANE_TYPE_INT)
    {
        INT si;

        if (opt->constraint.range->quant)
            si = position * opt->constraint.range->quant;
        else
            si = position;

        sprintf(buffer,"%i %s",si,unit);

    }
    else if  (opt->type == SANE_TYPE_FIXED)
    {
        double s_quant, dd;

        s_quant = SANE_UNFIX(opt->constraint.range->quant);

        if (s_quant)
            dd = position * s_quant;
        else
            dd = position * 0.01;

        sprintf(buffer,"%f %s",dd,unit);
    }
    else
        buffer[0] = 0;

    edit_w = GetDlgItem(hwnd,index+ID_BASE+ID_EDIT_BASE);
    if (edit_w && buffer[0])
        SetWindowTextA(edit_w,buffer);

}

static BOOL UpdateSaneScrollOption(
        const SANE_Option_Descriptor *opt, int index, DWORD position)
{
    SANE_Status rc = SANE_STATUS_GOOD;  
    SANE_Int result = 0;

    if (opt->type == SANE_TYPE_INT)
    {
        SANE_Int si;

        if (opt->constraint.range->quant)
            si = position * opt->constraint.range->quant;
        else
            si = position;

        rc = psane_control_option (activeDS.deviceHandle,index,
            SANE_ACTION_SET_VALUE, &si, &result);

    }
    else if  (opt->type == SANE_TYPE_FIXED)
    {
        double s_quant, dd;
        SANE_Fixed *sf;

        s_quant = SANE_UNFIX(opt->constraint.range->quant);

        if (s_quant)
            dd = position * s_quant;
        else
            dd = position * 0.01;

        sf = HeapAlloc(GetProcessHeap(),0,opt->size*sizeof(SANE_Word));

        *sf = SANE_FIX(dd);

        rc = psane_control_option (activeDS.deviceHandle,index,
            SANE_ACTION_SET_VALUE, sf, &result);

        HeapFree(GetProcessHeap(),0,sf);
    }

    if(rc == SANE_STATUS_GOOD)
    {
        if (result & SANE_INFO_RELOAD_OPTIONS || 
                result & SANE_INFO_RELOAD_PARAMS || result & SANE_INFO_INEXACT) 
            return TRUE;
    }
    return FALSE;
}

static BOOL UpdateSaneBoolOption(int index, BOOL position)
{
    SANE_Status rc = SANE_STATUS_GOOD;  
    SANE_Int result = 0;
    SANE_Bool si;

    si = position;

    rc = psane_control_option (activeDS.deviceHandle,index,
            SANE_ACTION_SET_VALUE, &si, &result);

    if(rc == SANE_STATUS_GOOD)
    {
        if (result & SANE_INFO_RELOAD_OPTIONS || 
                result & SANE_INFO_RELOAD_PARAMS || result & SANE_INFO_INEXACT) 
            return TRUE;
    }
    return FALSE;
}

static BOOL UpdateSaneStringOption(int index, SANE_String value)
{
    SANE_Status rc = SANE_STATUS_GOOD;  
    SANE_Int result = 0;

    rc = psane_control_option (activeDS.deviceHandle,index,
            SANE_ACTION_SET_VALUE, value, &result);

    if(rc == SANE_STATUS_GOOD)
    {
        if (result & SANE_INFO_RELOAD_OPTIONS || 
                result & SANE_INFO_RELOAD_PARAMS || result & SANE_INFO_INEXACT) 
            return TRUE;
    }
    return FALSE;
}

static INT_PTR InitializeDialog(HWND hwnd)
{
    SANE_Status rc;
    SANE_Int optcount;
    HWND control;
    int i;

    rc = psane_control_option(activeDS.deviceHandle, 0, SANE_ACTION_GET_VALUE,
            &optcount, NULL);

    for ( i = 1; i < optcount; i++)
    {
        const SANE_Option_Descriptor *opt;

        control = GetDlgItem(hwnd,i+ID_BASE);

        if (!control)
            continue;

        opt = psane_get_option_descriptor(activeDS.deviceHandle, i);

        TRACE("%i %s %i %i\n",i,opt->title,opt->type,opt->constraint_type);
        
        if (!SANE_OPTION_IS_ACTIVE(opt->cap))
            EnableWindow(control,FALSE);
        else
            EnableWindow(control,TRUE);

        SendMessageA(control,CB_RESETCONTENT,0,0);
        /* initialize values */
        if (opt->type == SANE_TYPE_STRING && opt->constraint_type !=
                SANE_CONSTRAINT_NONE)
        {
            int j = 0;
            CHAR buffer[255];
            while (opt->constraint.string_list[j]!=NULL)
            {
                SendMessageA(control,CB_ADDSTRING,0,
                        (LPARAM)opt->constraint.string_list[j]);
                j++;
            }
            psane_control_option(activeDS.deviceHandle, i, SANE_ACTION_GET_VALUE, buffer,NULL);
            SendMessageA(control,CB_SELECTSTRING,0,(LPARAM)buffer);
        }
        else if (opt->type == SANE_TYPE_BOOL)
        {
            SANE_Bool b;
            psane_control_option(activeDS.deviceHandle, i,
                    SANE_ACTION_GET_VALUE, &b, NULL);
            if (b)
                SendMessageA(control,BM_SETCHECK,BST_CHECKED,0);

        }
        else if (opt->constraint_type == SANE_CONSTRAINT_RANGE)
        {
            if (opt->type == SANE_TYPE_INT)
            {
                SANE_Int si;
                int min,max;

                min = (SANE_Int)opt->constraint.range->min /
                    (((SANE_Int)opt->constraint.range->quant)?
                    (SANE_Int)opt->constraint.range->quant:1);

                max = (SANE_Int)opt->constraint.range->max /
                    (((SANE_Int)opt->constraint.range->quant)
                    ?(SANE_Int)opt->constraint.range->quant:1);

                SendMessageA(control,SBM_SETRANGE,min,max);

                psane_control_option(activeDS.deviceHandle, i,
                        SANE_ACTION_GET_VALUE, &si,NULL);
                if (opt->constraint.range->quant)
                    si = si / opt->constraint.range->quant;

                SendMessageW(control,SBM_SETPOS, si, TRUE);
                UpdateRelevantEdit(hwnd, opt, i, si);
            }
            else if (opt->type == SANE_TYPE_FIXED)
            {
                SANE_Fixed *sf;

                double dd;
                double s_min,s_max,s_quant;
                INT pos;
                int min,max;

                s_min = SANE_UNFIX(opt->constraint.range->min);
                s_max = SANE_UNFIX(opt->constraint.range->max);
                s_quant = SANE_UNFIX(opt->constraint.range->quant);

                if (s_quant)
                {
                    min = (s_min / s_quant);
                    max = (s_max / s_quant);
                }
                else
                {
                    min = s_min / 0.01;
                    max = s_max / 0.01;
                }

                SendMessageA(control,SBM_SETRANGE,min,max);


                sf = HeapAlloc(GetProcessHeap(),0,opt->size*sizeof(SANE_Word));
                psane_control_option(activeDS.deviceHandle, i,
                        SANE_ACTION_GET_VALUE, sf,NULL);

                dd = SANE_UNFIX(*sf);
                HeapFree(GetProcessHeap(),0,sf);

                if (s_quant)
                    pos = (dd / s_quant);
                else
                    pos = dd / 0.01;

                SendMessageW(control, SBM_SETPOS, pos, TRUE);
                
                UpdateRelevantEdit(hwnd, opt, i, pos);
            }
        }
    }

    return TRUE;
}

static INT_PTR ProcessScroll(HWND hwnd, WPARAM wParam, LPARAM lParam)
{
    int index;
    const SANE_Option_Descriptor *opt;
    WORD scroll;
    DWORD position;

    index = GetDlgCtrlID((HWND)lParam)- ID_BASE;
    if (index < 0)
        return FALSE;

    opt = psane_get_option_descriptor(activeDS.deviceHandle, index);

    if (!opt)
        return FALSE;

    scroll = LOWORD(wParam);

    switch (scroll)
    {
        case SB_THUMBTRACK:
        case SB_THUMBPOSITION:
        {
            SCROLLINFO si;
            si.cbSize = sizeof(SCROLLINFO);
            si.fMask = SIF_TRACKPOS;
            GetScrollInfo((HWND)lParam,SB_CTL, &si);
            position = si.nTrackPos;
        }
            break;
        case SB_LEFT:
        case SB_LINELEFT:
        case SB_PAGELEFT:
            position = SendMessageW((HWND)lParam,SBM_GETPOS,0,0);
            position--;
            break;
        case SB_RIGHT:
        case SB_LINERIGHT:
        case SB_PAGERIGHT:
            position = SendMessageW((HWND)lParam,SBM_GETPOS,0,0);
            position++;
            break;
        default:
            position = SendMessageW((HWND)lParam,SBM_GETPOS,0,0);
    }

    SendMessageW((HWND)lParam,SBM_SETPOS, position, TRUE);
    position = SendMessageW((HWND)lParam,SBM_GETPOS,0,0);

    UpdateRelevantEdit(hwnd, opt, index, position);
    if (UpdateSaneScrollOption(opt, index, position))
        InitializeDialog(hwnd);

    return TRUE;
}


static void ButtonClicked(HWND hwnd, INT id, HWND control)
{
    int index;
    const SANE_Option_Descriptor *opt;

    index = id - ID_BASE;
    if (index < 0)
        return;

    opt = psane_get_option_descriptor(activeDS.deviceHandle, index);

    if (!opt)
        return;

    if (opt->type == SANE_TYPE_BOOL)
    {
        BOOL r = SendMessageW(control,BM_GETCHECK,0,0)==BST_CHECKED;
        if (UpdateSaneBoolOption(index, r))
                InitializeDialog(hwnd);
    }
}

static void ComboChanged(HWND hwnd, INT id, HWND control)
{
    int index;
    int selection;
    int len;
    const SANE_Option_Descriptor *opt;
    SANE_String value;

    index = id - ID_BASE;
    if (index < 0)
        return;

    opt = psane_get_option_descriptor(activeDS.deviceHandle, index);

    if (!opt)
        return;

    selection = SendMessageW(control,CB_GETCURSEL,0,0);
    len = SendMessageW(control,CB_GETLBTEXTLEN,selection,0);

    len++;
    value = HeapAlloc(GetProcessHeap(),0,len);
    SendMessageA(control,CB_GETLBTEXT,selection,(LPARAM)value);

    if (opt->type == SANE_TYPE_STRING)
    {
        if (UpdateSaneStringOption(index, value))
                InitializeDialog(hwnd);
    }
}


static INT_PTR CALLBACK DialogProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
{
    switch (msg)
    {
        case WM_INITDIALOG:
            return InitializeDialog(hwndDlg);
        case WM_HSCROLL:
            return ProcessScroll(hwndDlg, wParam, lParam);
        case WM_NOTIFY:
            {
                LPPSHNOTIFY psn = (LPPSHNOTIFY)lParam;
                switch (((NMHDR*)lParam)->code)
                {
                    case PSN_APPLY:
                        if (psn->lParam == TRUE)
                        {
                            activeDS.currentState = 6;
                            activeDS.pendingEvent.TWMessage = MSG_XFERREADY;
                        }
                        break;
                    case PSN_QUERYCANCEL:
                        activeDS.pendingEvent.TWMessage = MSG_CLOSEDSREQ;
                        break;
                    case PSN_SETACTIVE:
                        InitializeDialog(hwndDlg);
                        break;
                }
            }
        case WM_COMMAND:
            {
                switch (HIWORD(wParam))
                {
                    case BN_CLICKED:
                        ButtonClicked(hwndDlg,LOWORD(wParam),
                                (HWND)lParam);
                        break;
                    case CBN_SELCHANGE:
                        ComboChanged(hwndDlg,LOWORD(wParam),
                                (HWND)lParam);
                }
            }
    }

    return FALSE;
}

static int CALLBACK PropSheetProc(HWND hwnd, UINT msg, LPARAM lParam)
{
    if (msg == PSCB_INITIALIZED)
    {
        /* rename OK button to Scan */
        HWND scan = GetDlgItem(hwnd,IDOK);
        SetWindowTextA(scan,"Scan");
    }
    return TRUE;
}


static INT_PTR CALLBACK ScanningProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    return FALSE;
}

HWND ScanningDialogBox(HWND dialog, LONG progress)
{
    if (!dialog)
        dialog = CreateDialogW(SANE_instance,
                (LPWSTR)MAKEINTRESOURCE(IDD_DIALOG1), NULL, ScanningProc);

    if (progress == -1)
    {
        EndDialog(dialog,0);
        return NULL;
    }

    RedrawWindow(dialog,NULL,NULL,
            RDW_INTERNALPAINT|RDW_UPDATENOW|RDW_ALLCHILDREN);

    return dialog;
}

#else  /* SONAME_LIBSANE */

BOOL DoScannerUI(void)
{
    return FALSE;
}

#endif  /* SONAME_LIBSANE */
