/*
 * Copyright 2009 Jeremy White <jwhite@codeweavers.com> for CodeWeavers
 *
 * 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 "twain.h"
#include "sane_i.h"
#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(twain);

#ifdef SONAME_LIBSANE
static SANE_Status sane_find_option(SANE_Handle h, const char *option_name,
        const SANE_Option_Descriptor **opt_p, int *optno, SANE_Value_Type type)
{
    SANE_Status rc;
    SANE_Int optcount;
    const SANE_Option_Descriptor *opt;
    int i;

    /* Debian, in 32_net_backend_standard_fix.dpatch,
     *  forces a frontend (that's us) to reload options
     *  manually by invoking get_option_descriptor. */
    opt = psane_get_option_descriptor(h, 0);
    if (! opt)
        return SANE_STATUS_EOF;

    rc = psane_control_option(h, 0, SANE_ACTION_GET_VALUE, &optcount, NULL);
    if (rc != SANE_STATUS_GOOD)
        return rc;

    for (i = 1; i < optcount; i++)
    {
        opt = psane_get_option_descriptor(h, i);
        if (opt && (opt->name && strcmp(opt->name, option_name) == 0) &&
               opt->type == type)
        {
            *opt_p = opt;
            *optno = i;
            return SANE_STATUS_GOOD;
        }
    }
    return SANE_STATUS_EOF;
}

SANE_Status sane_option_get_int(SANE_Handle h, const char *option_name, SANE_Int *val)
{
    SANE_Status rc;
    int optno;
    const SANE_Option_Descriptor *opt;

    rc = sane_find_option(h, option_name, &opt, &optno, SANE_TYPE_INT);
    if (rc != SANE_STATUS_GOOD)
        return rc;

    return psane_control_option(h, optno, SANE_ACTION_GET_VALUE, val, NULL);
}

SANE_Status sane_option_set_int(SANE_Handle h, const char *option_name, SANE_Int val, SANE_Int *status)
{
    SANE_Status rc;
    int optno;
    const SANE_Option_Descriptor *opt;

    rc = sane_find_option(h, option_name, &opt, &optno, SANE_TYPE_INT);
    if (rc != SANE_STATUS_GOOD)
        return rc;

    return psane_control_option(h, optno, SANE_ACTION_SET_VALUE, (void *) &val, status);
}

/* Important:  SANE has the side effect of of overwriting val with the returned value */
SANE_Status sane_option_set_str(SANE_Handle h, const char *option_name, SANE_String val, SANE_Int *status)
{
    SANE_Status rc;
    int optno;
    const SANE_Option_Descriptor *opt;

    rc = sane_find_option(h, option_name, &opt, &optno, SANE_TYPE_STRING);
    if (rc != SANE_STATUS_GOOD)
        return rc;

    return psane_control_option(h, optno, SANE_ACTION_SET_VALUE, (void *) val, status);
}

SANE_Status sane_option_probe_resolution(SANE_Handle h, const char *option_name, SANE_Int *minval, SANE_Int *maxval, SANE_Int *quant)
{
    SANE_Status rc;
    int optno;
    const SANE_Option_Descriptor *opt;

    rc = sane_find_option(h, option_name, &opt, &optno, SANE_TYPE_INT);
    if (rc != SANE_STATUS_GOOD)
        return rc;

    if (opt->constraint_type != SANE_CONSTRAINT_RANGE)
        return SANE_STATUS_UNSUPPORTED;

    *minval = opt->constraint.range->min;
    *maxval = opt->constraint.range->max;
    *quant = opt->constraint.range->quant;

    return rc;
}

SANE_Status sane_option_probe_mode(SANE_Handle h, SANE_String_Const **choices, char *current, int current_size)
{
    SANE_Status rc;
    int optno;
    const SANE_Option_Descriptor *opt;
    rc = sane_find_option(h, "mode", &opt, &optno, SANE_TYPE_STRING);
    if (rc != SANE_STATUS_GOOD)
        return rc;

    if (choices && opt->constraint_type == SANE_CONSTRAINT_STRING_LIST)
        *choices = (SANE_String_Const *) opt->constraint.string_list;

    if (opt->size < current_size)
        return psane_control_option(h, optno, SANE_ACTION_GET_VALUE, current, NULL);
    else
        return SANE_STATUS_NO_MEM;

}

SANE_Status sane_option_probe_scan_area(SANE_Handle h, const char *option_name, SANE_Fixed *val,
                                        SANE_Unit *unit, SANE_Fixed *min, SANE_Fixed *max, SANE_Fixed *quant)
{
    SANE_Status rc;
    int optno;
    const SANE_Option_Descriptor *opt;

    rc = sane_find_option(h, option_name, &opt, &optno, SANE_TYPE_FIXED);
    if (rc != SANE_STATUS_GOOD)
        return rc;

    if (unit)
        *unit = opt->unit;
    if (min)
        *min = opt->constraint.range->min;
    if (max)
        *max = opt->constraint.range->max;
    if (quant)
        *quant = opt->constraint.range->quant;

    if (val)
        rc = psane_control_option(h, optno, SANE_ACTION_GET_VALUE, val, NULL);

    return rc;
}
#endif
