/*
 * Copyright 2000 Corel Corporation
 *
 * 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
 */

#define NONAMELESSUNION
#define NONAMELESSSTRUCT

#include "config.h"

#include <stdarg.h>

#include "windef.h"
#include "winbase.h"
#include "twain.h"
#include "sane_i.h"
#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(twain);

TW_UINT16 SANE_SaneCapability (pTW_CAPABILITY pCapability, TW_UINT16 action)
{
    TW_UINT16 twCC = TWCC_SUCCESS;

    TRACE("capability=%d action=%d\n", pCapability->Cap, action);

    switch (pCapability->Cap)
    {
        case CAP_DEVICEEVENT:
        case CAP_ALARMS:
        case CAP_ALARMVOLUME:
        case ACAP_AUDIOFILEFORMAT:
        case ACAP_XFERMECH:
        case ICAP_AUTOMATICBORDERDETECTION:
        case ICAP_AUTOMATICDESKEW:
        case ICAP_AUTODISCARDBLANKPAGES:
        case ICAP_AUTOMATICROTATE:
        case ICAP_FLIPROTATION:
        case CAP_AUTOMATICCAPTURE:
        case CAP_TIMEBEFOREFIRSTCAPTURE:
        case CAP_TIMEBETWEENCAPTURES:
        case CAP_AUTOSCAN:
        case CAP_CLEARBUFFERS:
        case CAP_MAXBATCHBUFFERS:
        case ICAP_BARCODEDETECTIONENABLED:
        case ICAP_SUPPORTEDBARCODETYPES:
        case ICAP_BARCODEMAXSEARCHPRIORITIES:
        case ICAP_BARCODESEARCHPRIORITIES:
        case ICAP_BARCODESEARCHMODE:
        case ICAP_BARCODEMAXRETRIES:
        case ICAP_BARCODETIMEOUT:
        case CAP_EXTENDEDCAPS:
        case CAP_SUPPORTEDCAPS:
        case ICAP_FILTER:
        case ICAP_GAMMA:
        case ICAP_PLANARCHUNKY:
        case ICAP_BITORDERCODES:
        case ICAP_CCITTKFACTOR:
        case ICAP_COMPRESSION:
        case ICAP_JPEGPIXELTYPE:
        /*case ICAP_JPEGQUALITY:*/
        case ICAP_PIXELFLAVORCODES:
        case ICAP_TIMEFILL:
        case CAP_DEVICEONLINE:
        case CAP_DEVICETIMEDATE:
        case CAP_SERIALNUMBER:
        case ICAP_EXPOSURETIME:
        case ICAP_FLASHUSED2:
        case ICAP_IMAGEFILTER:
        case ICAP_LAMPSTATE:
        case ICAP_LIGHTPATH:
        case ICAP_NOISEFILTER:
        case ICAP_OVERSCAN:
        case ICAP_PHYSICALHEIGHT:
        case ICAP_PHYSICALWIDTH:
        case ICAP_UNITS:
        case ICAP_ZOOMFACTOR:
        case CAP_PRINTER:
        case CAP_PRINTERENABLED:
        case CAP_PRINTERINDEX:
        case CAP_PRINTERMODE:
        case CAP_PRINTERSTRING:
        case CAP_PRINTERSUFFIX:
        case CAP_AUTHOR:
        case CAP_CAPTION:
        case CAP_TIMEDATE:
        case ICAP_AUTOBRIGHT:
        case ICAP_BRIGHTNESS:
        case ICAP_CONTRAST:
        case ICAP_HIGHLIGHT:
        case ICAP_ORIENTATION:
        case ICAP_ROTATION:
        case ICAP_SHADOW:
        case ICAP_XSCALING:
        case ICAP_YSCALING:
        case ICAP_BITDEPTH:
        case ICAP_BITDEPTHREDUCTION:
        case ICAP_BITORDER:
        case ICAP_CUSTHALFTONE:
        case ICAP_HALFTONES:
        case ICAP_PIXELFLAVOR:
        case ICAP_PIXELTYPE:
        case ICAP_THRESHOLD:
        case CAP_LANGUAGE:
        case ICAP_FRAMES:
        case ICAP_MAXFRAMES:
        case ICAP_SUPPORTEDSIZES:
        case CAP_AUTOFEED:
        case CAP_CLEARPAGE:
        case CAP_FEEDERALIGNMENT:
        case CAP_FEEDERENABLED:
        case CAP_FEEDERLOADED:
        case CAP_FEEDERORDER:
        case CAP_FEEDPAGE:
        case CAP_PAPERBINDING:
        case CAP_PAPERDETECTABLE:
        case CAP_REACQUIREALLOWED:
        case CAP_REWINDPAGE:
        case ICAP_PATCHCODEDETECTIONENABLED:
        case ICAP_SUPPORTEDPATCHCODETYPES:
        case ICAP_PATCHCODEMAXSEARCHPRIORITIES:
        case ICAP_PATCHCODESEARCHPRIORITIES:
        case ICAP_PATCHCODESEARCHMODE:
        case ICAP_PATCHCODEMAXRETRIES:
        case ICAP_PATCHCODETIMEOUT:
        case CAP_BATTERYMINUTES:
        case CAP_BATTERYPERCENTAGE:
        case CAP_POWERDOWNTIME:
        case CAP_POWERSUPPLY:
        case ICAP_XNATIVERESOLUTION:
        case ICAP_XRESOLUTION:
        case ICAP_YNATIVERESOLUTION:
        case ICAP_YRESOLUTION:
            twCC = TWCC_CAPUNSUPPORTED;
            break;
        case CAP_XFERCOUNT:
            /* This is a required capability that every source need to
               support but we havev't implemented yet. */
            twCC = TWCC_SUCCESS;
            break;
        /*case ICAP_COMPRESSION:*/
        case ICAP_IMAGEFILEFORMAT:
        case ICAP_TILES:
            twCC = TWCC_CAPUNSUPPORTED;
            break;
        case ICAP_XFERMECH:
            twCC = SANE_ICAPXferMech (pCapability, action);
            break;
        case ICAP_UNDEFINEDIMAGESIZE:
        case CAP_CAMERAPREVIEWUI:
        case CAP_ENABLEDSUIONLY:
        case CAP_INDICATORS:
        case CAP_UICONTROLLABLE:
            twCC = TWCC_CAPUNSUPPORTED;
            break;
        default:
            twCC = TWRC_FAILURE;

    }

    return twCC;
}

static TW_BOOL TWAIN_OneValueSet (pTW_CAPABILITY pCapability, TW_UINT32 value)
{
    pCapability->hContainer = GlobalAlloc (0, sizeof(TW_ONEVALUE));

    if (pCapability->hContainer)
    {
        pTW_ONEVALUE pVal = GlobalLock (pCapability->hContainer);
        pVal->ItemType = TWTY_UINT32;
        pVal->Item = value;
        GlobalUnlock (pCapability->hContainer);
        return TRUE;
    }
    else
        return FALSE;
}

static TW_BOOL TWAIN_OneValueGet (pTW_CAPABILITY pCapability, TW_UINT32 *pValue)
{
    pTW_ONEVALUE pVal = GlobalLock (pCapability->hContainer);

    if (pVal)
    {
        *pValue = pVal->Item;
        GlobalUnlock (pCapability->hContainer);
        return TRUE;
    }
    else
        return FALSE;
}

/* ICAP_XFERMECH */
TW_UINT16 SANE_ICAPXferMech (pTW_CAPABILITY pCapability, TW_UINT16 action)
{
    TRACE("ICAP_XFERMECH\n");

    switch (action)
    {
        case MSG_GET:
            if (pCapability->ConType == TWON_ONEVALUE)
            {
                if (!TWAIN_OneValueSet (pCapability, activeDS.capXferMech))
                    return TWCC_LOWMEMORY;
            }
            break;
        case MSG_SET:
            if (pCapability->ConType == TWON_ONEVALUE)
            {
		TW_UINT32 xfermechtemp = 0;
                if (!TWAIN_OneValueGet (pCapability, &xfermechtemp))
                    return TWCC_LOWMEMORY;
		activeDS.capXferMech = xfermechtemp;
            }
            else if (pCapability->ConType == TWON_ENUMERATION)
            {

            }
            break;
        case MSG_GETCURRENT:
            if (!TWAIN_OneValueSet (pCapability, activeDS.capXferMech))
                return TWCC_LOWMEMORY;
            break;
        case MSG_GETDEFAULT:
            if (!TWAIN_OneValueSet (pCapability, TWSX_NATIVE))
                return TWCC_LOWMEMORY;
            break;
        case MSG_RESET:
            activeDS.capXferMech = TWSX_NATIVE;
            break;
    }
    return TWCC_SUCCESS;
}
