/*
* 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,
                                          SANE_Int optcount, BOOL split_tabs)
{
    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;

    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)
            continue;
        if (opt->type == SANE_TYPE_GROUP && split_tabs)
        {
            if (control_len > 0)
            {
                *from_index = i - 1;
                goto exit;
            }
            else
            {
                *from_index = i;
                return NULL;
            }
        }
        if (!SANE_OPTION_IS_ACTIVE (opt->cap))
            continue;

        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);
    if (rc != SANE_STATUS_GOOD)
    {
        ERR("Unable to read number of options\n");
        return FALSE;
    }

    while (index < optcount)
    {
        const SANE_Option_Descriptor *opt;
        psp[page_count].u.pResource = create_options_page(hdc, &index,
                optcount, 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);
    }
    HeapFree(GetProcessHeap(),0,szCaption);
    
    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);
    if (rc != SANE_STATUS_GOOD)
    {
        ERR("Unable to read number of options\n");
        return FALSE;
    }

    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 */
