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

#define NONAMELESSUNION
#define NONAMELESSSTRUCT
#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;
}
