/*
 * TWAIN32 functions
 *
 * Copyright 2000 Shi Quan He <shiquan@cyberdude.com>
 * Copyright 2006 Marcus Meissner
 *
 * 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 <stdarg.h>

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

WINE_DEFAULT_DEBUG_CHANNEL(twain);

/* A helper function that looks up a destination identity in the active
   source list */
static activeDS *TWAIN_LookupSource (const TW_IDENTITY *pDest)
{
    activeDS *pSource;

    for (pSource = activeSources; pSource; pSource = pSource->next)
        if (pSource->identity.Id == pDest->Id)
            break;
    return pSource;
}

BOOL WINAPI DllMain (HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
    TRACE("%p,%x,%p\n", hinstDLL, fdwReason, lpvReserved);

    switch (fdwReason)
    {
        case DLL_PROCESS_ATTACH:
            DisableThreadLibraryCalls(hinstDLL);
            DSM_currentState = 2;
            break;

        case DLL_PROCESS_DETACH:
            DSM_currentState = 1;
            break;
    }

    return TRUE;
}

static TW_UINT16 TWAIN_SourceManagerHandler (
           pTW_IDENTITY pOrigin,
           TW_UINT16   DAT,
           TW_UINT16   MSG,
           TW_MEMREF   pData)
{
    TW_UINT16 twRC = TWRC_SUCCESS;

    switch (DAT)
    {
        case DAT_IDENTITY:
            switch (MSG)
            {
                case MSG_CLOSEDS:
                    twRC = TWAIN_CloseDS (pOrigin, pData);
                    break;

                case MSG_GETDEFAULT:
                    twRC = TWAIN_IdentityGetDefault (pOrigin, pData);
                    break;

                case MSG_GETFIRST:
                    twRC = TWAIN_IdentityGetFirst (pOrigin, pData);
                    break;

                case MSG_GETNEXT:
                    twRC = TWAIN_IdentityGetNext (pOrigin, pData);
                    break;

                case MSG_OPENDS:
                    twRC = TWAIN_OpenDS (pOrigin, pData);
                    break;

                case MSG_USERSELECT:
                    twRC = TWAIN_UserSelect (pOrigin, pData);
                    break;

                default:
                    /* Unrecognized operation triplet */
                    twRC = TWRC_FAILURE;
                    DSM_twCC = TWCC_BADPROTOCOL;
                    WARN("unrecognized operation triplet\n");
                    break;
            }
            break;

        case DAT_PARENT:
            switch (MSG)
            {
                case MSG_CLOSEDSM:
                    twRC = TWAIN_CloseDSM (pOrigin, pData);
                    break;

                case MSG_OPENDSM:
                    twRC = TWAIN_OpenDSM (pOrigin, pData);
                    break;

                default:
                    /* Unrecognized operation triplet */
                    twRC = TWRC_FAILURE;
                    DSM_twCC = TWCC_BADPROTOCOL;
                    WARN("unrecognized operation triplet\n");
            }
            break;

        case DAT_STATUS:
            if (MSG == MSG_GET) {
                twRC = TWAIN_GetDSMStatus (pOrigin, pData);
            } else {
                twRC = TWRC_FAILURE;
                DSM_twCC = TWCC_BADPROTOCOL;
                WARN("unrecognized operation triplet\n");
            }
            break;

        default:
            twRC = TWRC_FAILURE;
            DSM_twCC = TWCC_BADPROTOCOL;
            WARN("unrecognized operation triplet\n");
            break;
    }

    return twRC;
}


/* Main entry point for the TWAIN library */
TW_UINT16 WINAPI
DSM_Entry (pTW_IDENTITY pOrigin,
           pTW_IDENTITY pDest,
           TW_UINT32    DG,
           TW_UINT16    DAT,
           TW_UINT16    MSG,
           TW_MEMREF    pData)
{
    TW_UINT16 twRC = TWRC_SUCCESS;  /* Return Code */

    TRACE("(DG=%d DAT=%d MSG=%d)\n", DG, DAT, MSG);

    if (pDest)
    {
        activeDS *pSource = TWAIN_LookupSource (pDest);
	/* This operation's destination is a source */

        if (!pSource) {
	    ERR("No source associated with pDest %p\n", pDest);
	    DSM_twCC = TWCC_BADDEST;
	    return TWRC_FAILURE;
	}
	DSM_twCC = TWCC_SUCCESS;
        TRACE("Forwarding %d/%d/%d/%p to DS.\n", DG, DAT, MSG, pData);
	twRC = pSource->dsEntry(pOrigin, DG, DAT, MSG, pData);
	TRACE("return value is %d\n", twRC);
	return twRC;
    }
    switch (DG)
    {
        case DG_CONTROL:
            twRC = TWAIN_SourceManagerHandler (pOrigin, DAT, MSG, pData);
            break;
        default:
            FIXME("The DSM does not handle DG %d\n", DG);
            DSM_twCC = TWCC_BADPROTOCOL;
            twRC = TWRC_FAILURE;
    }
    return twRC;
}
