/*
 * TWAIN32 Source Manager
 *
 * Copyright 2000 Corel Corporation
 * 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 <stdlib.h>
#include <stdarg.h>
#include <stdio.h>

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

WINE_DEFAULT_DEBUG_CHANNEL(twain);

static TW_UINT16 DSM_initialized;	/* whether Source Manager is initialized */
static TW_UINT32 DSM_sourceId;		/* source id generator */
static TW_UINT16 DSM_currentDevice;	/* keep track of device during enumeration */

struct all_devices {
	char 		*modname;
	TW_IDENTITY	identity;
};

static int nrdevices = 0;
static struct all_devices *devices = NULL;

static void
twain_add_onedriver(const char *dsname) {
	HMODULE 	hmod;
	DSENTRYPROC	dsEntry;
	TW_IDENTITY	fakeOrigin;
	TW_IDENTITY	sourceId;
	TW_UINT16	ret;

	hmod = LoadLibraryA(dsname);
	if (!hmod) {
		ERR("Failed to load TWAIN Source %s\n", dsname);
		return;
	}
	dsEntry = (DSENTRYPROC)GetProcAddress(hmod, "DS_Entry"); 
	if (!dsEntry) {
		ERR("Failed to find DS_Entry() in TWAIN DS %s\n", dsname);
		return;
	}
	/* Loop to do multiple detects, mostly for sane.ds and gphoto2.ds */
	do {
		int i;

		sourceId.Id 		= DSM_sourceId;
		sourceId.ProtocolMajor	= TWON_PROTOCOLMAJOR;
		sourceId.ProtocolMinor	= TWON_PROTOCOLMINOR;
		ret = dsEntry (&fakeOrigin, DG_CONTROL, DAT_IDENTITY, MSG_GET, &sourceId);
		if (ret != TWRC_SUCCESS) {
			ERR("Source->(DG_CONTROL,DAT_IDENTITY,MSG_GET) failed!\n");
                        break;
		}
		TRACE("Manufacturer: %s\n",	debugstr_a(sourceId.Manufacturer));
		TRACE("ProductFamily: %s\n",	debugstr_a(sourceId.ProductFamily));
		TRACE("ProductName: %s\n",	debugstr_a(sourceId.ProductName));

		for (i=0;i<nrdevices;i++) {
			if (!strcmp(sourceId.ProductName,devices[i].identity.ProductName))
				break;
		}
		if (i < nrdevices)
			break;
		if (nrdevices)
			devices = HeapReAlloc(GetProcessHeap(), 0, devices, sizeof(devices[0])*(nrdevices+1));
		else
			devices = HeapAlloc(GetProcessHeap(), 0, sizeof(devices[0]));
		if ((devices[nrdevices].modname = HeapAlloc(GetProcessHeap(), 0, strlen(dsname) + 1)))
			lstrcpyA(devices[nrdevices].modname, dsname);
		devices[nrdevices].identity = sourceId;
		nrdevices++;
		DSM_sourceId++;
	} while (1);
	FreeLibrary (hmod);
}

static BOOL detectionrun = FALSE;

static void
twain_autodetect(void) {
	if (detectionrun) return;
        detectionrun = TRUE;

	twain_add_onedriver("sane.ds");
	twain_add_onedriver("gphoto2.ds");
#if 0
	twain_add_onedriver("c:\\windows\\Twain_32\\Largan\\sp503a.ds");
	twain_add_onedriver("c:\\windows\\Twain_32\\vivicam10\\vivicam10.ds");
	twain_add_onedriver("c:\\windows\\Twain_32\\ws30slim\\sp500a.ds");
#endif
}

/* DG_CONTROL/DAT_IDENTITY/MSG_CLOSEDS */
TW_UINT16 TWAIN_CloseDS (pTW_IDENTITY pOrigin, TW_MEMREF pData)
{
	TW_UINT16 twRC = TWRC_SUCCESS;
	pTW_IDENTITY pIdentity = (pTW_IDENTITY) pData;
	activeDS *currentDS = NULL, *prevDS = NULL;

	TRACE ("DG_CONTROL/DAT_IDENTITY/MSG_CLOSEDS\n");

	for (currentDS = activeSources; currentDS; currentDS = currentDS->next) {
		if (currentDS->identity.Id == pIdentity->Id)
			break;
		prevDS = currentDS;
	}
	if (!currentDS) {
		DSM_twCC = TWCC_NODS;
		return TWRC_FAILURE;
	}
	twRC = currentDS->dsEntry (pOrigin, DG_CONTROL, DAT_IDENTITY, MSG_CLOSEDS, pData);
	/* This causes crashes due to still open Windows, so leave out for now.
	 * FreeLibrary (currentDS->hmod);
	 */
	if (prevDS)
		prevDS->next = currentDS->next;
	else
		activeSources = currentDS->next;
	HeapFree (GetProcessHeap(), 0, currentDS);
	if (twRC == TWRC_SUCCESS)
		DSM_twCC = TWCC_SUCCESS;
	else /* FIXME: unclear how to get TWCC */
		DSM_twCC = TWCC_SEQERROR;
	return twRC;
}

/* DG_CONTROL/DAT_IDENTITY/MSG_GETDEFAULT */
TW_UINT16 TWAIN_IdentityGetDefault (pTW_IDENTITY pOrigin, TW_MEMREF pData)
{
	pTW_IDENTITY pSourceIdentity = (pTW_IDENTITY) pData;

	TRACE("DG_CONTROL/DAT_IDENTITY/MSG_GETDEFAULT\n");
	DSM_twCC = TWCC_NODS;
	twain_autodetect();
	if (!nrdevices)
		return TWRC_FAILURE;
	*pSourceIdentity = devices[0].identity;
	DSM_twCC = TWCC_SUCCESS;
	return TWRC_SUCCESS;
}

/* DG_CONTROL/DAT_IDENTITY/MSG_GETFIRST */
TW_UINT16 TWAIN_IdentityGetFirst (pTW_IDENTITY pOrigin, TW_MEMREF pData)
{
	pTW_IDENTITY pSourceIdentity = (pTW_IDENTITY) pData;

	TRACE ("DG_CONTROL/DAT_IDENTITY/MSG_GETFIRST\n");
	twain_autodetect();
	if (!nrdevices) {
		TRACE ("no entries found.\n");
		DSM_twCC = TWCC_NODS;
		return TWRC_FAILURE;
	}
	DSM_currentDevice = 0;
	*pSourceIdentity = devices[DSM_currentDevice++].identity;
	return TWRC_SUCCESS;
}

/* DG_CONTROL/DAT_IDENTITY/MSG_GETNEXT */
TW_UINT16 TWAIN_IdentityGetNext (pTW_IDENTITY pOrigin, TW_MEMREF pData)
{
	pTW_IDENTITY pSourceIdentity = (pTW_IDENTITY) pData;

	TRACE("DG_CONTROL/DAT_IDENTITY/MSG_GETNEXT\n");
	if (!nrdevices || (DSM_currentDevice == nrdevices)) {
		DSM_twCC = TWCC_SUCCESS;
		return TWRC_ENDOFLIST;
	}
	*pSourceIdentity = devices[DSM_currentDevice++].identity;
	return TWRC_SUCCESS;
}

/* DG_CONTROL/DAT_IDENTITY/MSG_OPENDS */
TW_UINT16 TWAIN_OpenDS (pTW_IDENTITY pOrigin, TW_MEMREF pData)
{
	TW_UINT16 i = 0;
	pTW_IDENTITY pIdentity = (pTW_IDENTITY) pData;
	activeDS *newSource;
	const char *modname = NULL;
	HMODULE hmod;

	TRACE("DG_CONTROL/DAT_IDENTITY/MSG_OPENDS\n");
        TRACE("pIdentity is %s\n", pIdentity->ProductName);
	if (!DSM_initialized) {
		FIXME("seq error\n");
		DSM_twCC = TWCC_SEQERROR;
		return TWRC_FAILURE;
	}
	twain_autodetect();
	if (!nrdevices) {
		FIXME("no devs.\n");
		DSM_twCC = TWCC_NODS;
		return TWRC_FAILURE;
	}

	if (pIdentity->ProductName[0] != '\0') {
		/* Make sure the source to be opened exists in the device list */
		for (i = 0; i<nrdevices; i++)
			if (!strcmp (devices[i].identity.ProductName, pIdentity->ProductName))
				break;
		if (i == nrdevices)
			i = 0;
	} /* else use the first device */

	/* the source is found in the device list */
	newSource = HeapAlloc (GetProcessHeap(), 0, sizeof (activeDS));
	if (!newSource) {
		DSM_twCC = TWCC_LOWMEMORY;
		FIXME("Out of memory.\n");
		return TWRC_FAILURE;
	}
	hmod = LoadLibraryA(devices[i].modname);
	if (!hmod) {
		ERR("Failed to load TWAIN Source %s\n", modname);
		DSM_twCC = TWCC_OPERATIONERROR;
                HeapFree(GetProcessHeap(), 0, newSource);
		return TWRC_FAILURE;
	}
	newSource->hmod = hmod; 
	newSource->dsEntry = (DSENTRYPROC)GetProcAddress(hmod, "DS_Entry"); 
	if (TWRC_SUCCESS != newSource->dsEntry (pOrigin, DG_CONTROL, DAT_IDENTITY, MSG_OPENDS, pIdentity)) {
		DSM_twCC = TWCC_OPERATIONERROR;
                HeapFree(GetProcessHeap(), 0, newSource);
		return TWRC_FAILURE;
	}
	/* Assign name and id for the opened data source */
	pIdentity->Id = DSM_sourceId ++;
	/* add the data source to an internal active source list */
	newSource->next = activeSources;
	newSource->identity.Id = pIdentity->Id;
	strcpy (newSource->identity.ProductName, pIdentity->ProductName);
	activeSources = newSource;
	DSM_twCC = TWCC_SUCCESS;
	return TWRC_SUCCESS;
}

/* DG_CONTROL/DAT_IDENTITY/MSG_USERSELECT */
TW_UINT16 TWAIN_UserSelect (pTW_IDENTITY pOrigin, TW_MEMREF pData)
{
	pTW_IDENTITY	selected = (pTW_IDENTITY)pData;

	if (!nrdevices) {
		DSM_twCC = TWCC_OPERATIONERROR;
		return TWRC_FAILURE;
	}
	*selected = devices[0].identity;
	DSM_twCC = TWCC_SUCCESS;
	return TWRC_SUCCESS;
}

/* DG_CONTROL/DAT_PARENT/MSG_CLOSEDSM */
TW_UINT16 TWAIN_CloseDSM (pTW_IDENTITY pOrigin, TW_MEMREF pData)
{
    activeDS *currentDS = activeSources, *nextDS;

    TRACE("DG_CONTROL/DAT_PARENT/MSG_CLOSEDSM\n");

    if (DSM_initialized)
    {
        DSM_initialized = FALSE;

        /* If there are data sources still open, close them now. */
        while (currentDS != NULL)
        {
            nextDS = currentDS->next;
	    currentDS->dsEntry (pOrigin, DG_CONTROL, DAT_IDENTITY, MSG_CLOSEDS, pData);
            HeapFree (GetProcessHeap(), 0, currentDS);
            currentDS = nextDS;
        }
        activeSources = NULL;
        DSM_twCC = TWCC_SUCCESS;
        return TWRC_SUCCESS;
    } else {
        DSM_twCC = TWCC_SEQERROR;
        return TWRC_FAILURE;
    }
}

/* DG_CONTROL/DAT_PARENT/MSG_OPENDSM */
TW_UINT16 TWAIN_OpenDSM (pTW_IDENTITY pOrigin, TW_MEMREF pData)
{
	TW_UINT16 twRC = TWRC_SUCCESS;

	TRACE("DG_CONTROL/DAT_PARENT/MSG_OPENDSM\n");
        if (!DSM_initialized) {
		DSM_currentDevice = 0;
		DSM_initialized = TRUE;
		DSM_twCC = TWCC_SUCCESS;
		twRC = TWRC_SUCCESS;
	} else {
		/* operation invoked in invalid state */
		DSM_twCC = TWCC_SEQERROR;
		twRC = TWRC_FAILURE;
	}
	return twRC;
}

/* DG_CONTROL/DAT_STATUS/MSG_GET */
TW_UINT16 TWAIN_GetDSMStatus (pTW_IDENTITY pOrigin, TW_MEMREF pData)
{
	pTW_STATUS pSourceStatus = (pTW_STATUS) pData;

	TRACE ("DG_CONTROL/DAT_STATUS/MSG_GET\n");

	pSourceStatus->ConditionCode = DSM_twCC;
	DSM_twCC = TWCC_SUCCESS;  /* clear the condition code */
	return TWRC_SUCCESS;
}
