/*		DirectDraw Base Functions
 *
 * Copyright 1997-1999 Marcus Meissner
 * Copyright 1998 Lionel Ulmer (most of Direct3D stuff)
 */

#include "config.h"

#include <unistd.h>
#include <assert.h>
#include <fcntl.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>

#include "winerror.h"
#include "heap.h"
#include "wine/exception.h"
#include "debugtools.h"

#include "initguid.h"
#include "ddraw.h"
#include "d3d.h"

/* This for all the enumeration and creation of D3D-related objects */
#include "ddraw_private.h"

#define MAX_DDRAW_DRIVERS	3
static ddraw_driver * ddraw_drivers[MAX_DDRAW_DRIVERS];
static int nrof_ddraw_drivers			= 0;

DEFAULT_DEBUG_CHANNEL(ddraw);

/* register a direct draw driver. We better not use malloc for we are in 
 * the ELF startup initialisation at this point.
 */
void ddraw_register_driver(ddraw_driver *driver) {
    ddraw_drivers[nrof_ddraw_drivers++] = driver;

    /* increase MAX_DDRAW_DRIVERS if the line below triggers */
    assert(nrof_ddraw_drivers <= MAX_DDRAW_DRIVERS);
}

/**********************************************************************/

typedef struct {
    LPVOID lpCallback;
    LPVOID lpContext; 
} DirectDrawEnumerateProcData;

/***********************************************************************
 *		DirectDrawEnumerateExA (DDRAW.*)
 */
HRESULT WINAPI DirectDrawEnumerateExA(
    LPDDENUMCALLBACKEXA lpCallback, LPVOID lpContext, DWORD dwFlags)
{
    int i;
    TRACE("(%p,%p, %08lx)\n", lpCallback, lpContext, dwFlags);

    if (TRACE_ON(ddraw)) {
	DPRINTF("  Flags : ");
	if (dwFlags & DDENUM_ATTACHEDSECONDARYDEVICES)
	    DPRINTF("DDENUM_ATTACHEDSECONDARYDEVICES ");
	if (dwFlags & DDENUM_DETACHEDSECONDARYDEVICES)
	    DPRINTF("DDENUM_DETACHEDSECONDARYDEVICES ");
	if (dwFlags & DDENUM_NONDISPLAYDEVICES)
	    DPRINTF("DDENUM_NONDISPLAYDEVICES ");
	DPRINTF("\n");
    }

    /* Invoke callback for what flags we do support */
    for (i=0;i<MAX_DDRAW_DRIVERS;i++) {
	if (!ddraw_drivers[i])
	    continue;
	if (ddraw_drivers[i]->createDDRAW(NULL)) /* !0 is failing */
	    continue;
        TRACE("Enumerating %s/%s interface\n",ddraw_drivers[i]->name,ddraw_drivers[i]->type);
	if (!lpCallback(
	    ddraw_drivers[i]->guid,
	    (LPSTR)ddraw_drivers[i]->name,
	    (LPSTR)ddraw_drivers[i]->type,
	    lpContext,
	    0		/* FIXME: flags not supported here */
	))
	    return DD_OK;
    }
    if (nrof_ddraw_drivers) {
	TRACE("Enumerating the default interface\n");
	if (!lpCallback(NULL,"WINE (default)", "display", lpContext, 0))
	    return DD_OK;
    }

    /* Unsupported flags */
    if (dwFlags & DDENUM_NONDISPLAYDEVICES) {
	FIXME("no non-display devices supported.\n");
    }
/* Hmm. Leave this out.
    if (dwFlags & DDENUM_ATTACHEDSECONDARYDEVICES) {
	FIXME("no attached secondary devices supported.\n");
    }
 */
    if (dwFlags & DDENUM_DETACHEDSECONDARYDEVICES) {
	FIXME("no detached secondary devices supported.\n");
    }

    return DD_OK;
}

/***********************************************************************
 *		DirectDrawEnumerateExW (DDRAW.*)
 */

static BOOL CALLBACK DirectDrawEnumerateExProcW(
    GUID *lpGUID, LPSTR lpDriverDescription, LPSTR lpDriverName, 
    LPVOID lpContext, HMONITOR hm)
{
    DirectDrawEnumerateProcData *pEPD = (DirectDrawEnumerateProcData*)lpContext;
    LPWSTR lpDriverDescriptionW =
	HEAP_strdupAtoW(GetProcessHeap(), 0, lpDriverDescription);
    LPWSTR lpDriverNameW =
	HEAP_strdupAtoW(GetProcessHeap(), 0, lpDriverName);

    BOOL bResult = (*(LPDDENUMCALLBACKEXW *) pEPD->lpCallback)(
	lpGUID, lpDriverDescriptionW, lpDriverNameW, pEPD->lpContext, hm);

    HeapFree(GetProcessHeap(), 0, lpDriverDescriptionW);
    HeapFree(GetProcessHeap(), 0, lpDriverNameW);
    return bResult;
}

/**********************************************************************/

HRESULT WINAPI DirectDrawEnumerateExW(
  LPDDENUMCALLBACKEXW lpCallback, LPVOID lpContext, DWORD dwFlags)
{
    DirectDrawEnumerateProcData epd;
    epd.lpCallback = (LPVOID) lpCallback;
    epd.lpContext = lpContext;

    return DirectDrawEnumerateExA(DirectDrawEnumerateExProcW, (LPVOID) &epd, 0);
}

/***********************************************************************
 *		DirectDrawEnumerateA (DDRAW.*)
 */

static BOOL CALLBACK DirectDrawEnumerateProcA(
	GUID *lpGUID, LPSTR lpDriverDescription, LPSTR lpDriverName, 
	LPVOID lpContext, HMONITOR hm)
{
    DirectDrawEnumerateProcData *pEPD = (DirectDrawEnumerateProcData*)lpContext;

    return ((LPDDENUMCALLBACKA) pEPD->lpCallback)(
	lpGUID, lpDriverDescription, lpDriverName, pEPD->lpContext);
}

/**********************************************************************/

HRESULT WINAPI DirectDrawEnumerateA(
  LPDDENUMCALLBACKA lpCallback, LPVOID lpContext) 
{
    DirectDrawEnumerateProcData epd;  
    epd.lpCallback = (LPVOID) lpCallback;
    epd.lpContext = lpContext;

    return DirectDrawEnumerateExA(DirectDrawEnumerateProcA, (LPVOID) &epd, 0);
}

/***********************************************************************
 *		DirectDrawEnumerateW (DDRAW.*)
 */

static BOOL WINAPI DirectDrawEnumerateProcW(
  GUID *lpGUID, LPWSTR lpDriverDescription, LPWSTR lpDriverName, 
  LPVOID lpContext, HMONITOR hm)
{
    DirectDrawEnumerateProcData *pEPD = (DirectDrawEnumerateProcData*)lpContext;
  
    return ((LPDDENUMCALLBACKW) pEPD->lpCallback)(
	lpGUID, lpDriverDescription, lpDriverName, pEPD->lpContext);
}

/**********************************************************************/

HRESULT WINAPI DirectDrawEnumerateW(
  LPDDENUMCALLBACKW lpCallback, LPVOID lpContext) 
{
    DirectDrawEnumerateProcData epd;
    epd.lpCallback = (LPVOID) lpCallback;
    epd.lpContext = lpContext;

    return DirectDrawEnumerateExW(DirectDrawEnumerateProcW, (LPVOID) &epd, 0);
}

/******************************************************************************
 * 				DirectDraw Window Procedure
 */
static LRESULT WINAPI DDWndProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam)
{
    LRESULT ret;
    IDirectDrawImpl* ddraw = NULL;
    DWORD lastError;

    /* FIXME(ddraw,"(0x%04x,%s,0x%08lx,0x%08lx),stub!\n",(int)hwnd,SPY_GetMsgName(msg),(long)wParam,(long)lParam); */

    SetLastError( ERROR_SUCCESS );
    ddraw  = (IDirectDrawImpl*)GetPropA( hwnd, ddProp );
    if( (!ddraw)  && ( ( lastError = GetLastError() ) != ERROR_SUCCESS )) 
	ERR("Unable to retrieve this ptr from window. Error %08lx\n",lastError);

    if( ddraw ) {
    /* Perform any special direct draw functions */
	if (msg==WM_PAINT)
	    ddraw->d->paintable = 1;

	/* Now let the application deal with the rest of this */
	if( ddraw->d->mainWindow ) {

	    /* Don't think that we actually need to call this but... 
	     * might as well be on the safe side of things...
	     */

	    /* I changed hwnd to ddraw->d->mainWindow as I did not see why
	     * it should be the procedures of our fake window that gets called
	     * instead of those of the window provided by the application.
	     * And with this patch, mouse clicks work with Monkey Island III
	     * - Lionel
	     */
	    ret = DefWindowProcA( ddraw->d->mainWindow, msg, wParam, lParam );

	    if( !ret ) {
		/* We didn't handle the message - give it to the application */
		if (ddraw && ddraw->d->mainWindow)
                {
                    WNDPROC winproc = (WNDPROC)GetWindowLongA( ddraw->d->mainWindow, GWL_WNDPROC );
		    ret = CallWindowProcA(winproc, ddraw->d->mainWindow, msg, wParam, lParam );
                }
	    }
	    return ret;
	} /* else FALLTHROUGH */
    } /* else FALLTHROUGH */
    return DefWindowProcA(hwnd,msg,wParam,lParam);
}

/***********************************************************************
 *		DirectDrawCreate
 */
HRESULT WINAPI DirectDrawCreate(
	LPGUID lpGUID, LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter
) {
    IDirectDrawImpl** ilplpDD=(IDirectDrawImpl**)lplpDD;
    WNDCLASSA	wc;
    HRESULT	ret = 0;
    int		i,drvindex=0;
    GUID	zeroGUID;

    struct ddraw_driver	*ddd = NULL;

    if (!HIWORD(lpGUID)) lpGUID = NULL;

    TRACE("(%s,%p,%p)\n",debugstr_guid(lpGUID),ilplpDD,pUnkOuter);

    memset(&zeroGUID,0,sizeof(zeroGUID));
    while (1) {
	ddd = NULL;
	if ( ( !lpGUID ) ||
	     ( IsEqualGUID( &zeroGUID,  lpGUID ) ) ||
	     ( IsEqualGUID( &IID_IDirectDraw,  lpGUID ) ) ||
	     ( IsEqualGUID( &IID_IDirectDraw2, lpGUID ) ) ||
	     ( IsEqualGUID( &IID_IDirectDraw4, lpGUID ) ) ||
	     ( IsEqualGUID( &IID_IDirectDraw7, lpGUID ) )
	) {
	    /* choose an interface out of the list */
	    for (i=0;i<nrof_ddraw_drivers;i++) {
		ddraw_driver *xddd = ddraw_drivers[i];
		if (!xddd)
		    continue;
		if (!ddd || (ddd->preference<xddd->preference)) {
		    drvindex = i;
		    ddd = xddd;
		}
	    }
	} else {
	    for (i=0;i<nrof_ddraw_drivers;i++) {
		if (!ddraw_drivers[i])
		    continue;
		if (IsEqualGUID(ddraw_drivers[i]->guid,lpGUID)) {
		    drvindex = i;
		    ddd = ddraw_drivers[i];
		    break;
		}
	    }
	}
	if (!ddd) {
	    if (!nrof_ddraw_drivers) {
		ERR("DirectDrawCreate(%s,%p,%p): no DirectDraw drivers compiled in.\n",debugstr_guid(lpGUID),lplpDD,pUnkOuter);
		return DDERR_NODIRECTDRAWHW;
	    }
	    ERR("DirectDrawCreate(%s,%p,%p): did not recognize requested GUID.\n",debugstr_guid(lpGUID),lplpDD,pUnkOuter);
	    return DDERR_INVALIDDIRECTDRAWGUID;
	}
	TRACE("using \"%s\" driver, calling %p\n",ddd->name,ddd->createDDRAW);

	ret = ddd->createDDRAW(lplpDD);
	if (!ret)
	    break;
	ddraw_drivers[drvindex] = NULL; /* mark this one as unusable */
    }
    wc.style		= CS_GLOBALCLASS;
    wc.lpfnWndProc	= DDWndProc;
    wc.cbClsExtra	= 0;
    wc.cbWndExtra	= 0;

    /* We can be a child of the desktop since we're really important */
    wc.hInstance= 0; 
    wc.hIcon	= 0;
    wc.hCursor	= (HCURSOR)IDC_ARROWA;
    wc.hbrBackground	= NULL_BRUSH;
    wc.lpszMenuName 	= 0;
    wc.lpszClassName	= "WINE_DirectDraw";
    (*ilplpDD)->d->winclass = RegisterClassA(&wc);
    return ret;
}

/***********************************************************************
 *		DirectDrawCreateEx
 */
HRESULT WINAPI DirectDrawCreateEx(
	LPGUID lpGUID, LPVOID* lplpDD, REFIID iid, LPUNKNOWN pUnkOuter
) {
  FIXME(":semi stub\n");
  /* I don't know about what functionality is unique to Ex */
  return DirectDrawCreate(lpGUID,(LPDIRECTDRAW*)lplpDD,pUnkOuter);
}

/*******************************************************************************
 * DirectDraw ClassFactory
 *
 *  Heavily inspired (well, can you say completely copied :-) ) from DirectSound
 *
 */
typedef struct {
    /* IUnknown fields */
    ICOM_VFIELD(IClassFactory);
    DWORD		ref;
} IClassFactoryImpl;

static HRESULT WINAPI 
DDCF_QueryInterface(LPCLASSFACTORY iface,REFIID riid,LPVOID *ppobj) {
    ICOM_THIS(IClassFactoryImpl,iface);

    FIXME("(%p)->(%s,%p),stub!\n",This,debugstr_guid(riid),ppobj);
    return E_NOINTERFACE;
}

static ULONG WINAPI
DDCF_AddRef(LPCLASSFACTORY iface) {
    ICOM_THIS(IClassFactoryImpl,iface);
    return ++(This->ref);
}

static ULONG WINAPI DDCF_Release(LPCLASSFACTORY iface) {
    ICOM_THIS(IClassFactoryImpl,iface);
    /* static class, won't be  freed */
    return --(This->ref);
}

static HRESULT WINAPI DDCF_CreateInstance(
	LPCLASSFACTORY iface,LPUNKNOWN pOuter,REFIID riid,LPVOID *ppobj
) {
    ICOM_THIS(IClassFactoryImpl,iface);

    TRACE("(%p)->(%p,%s,%p)\n",This,pOuter,debugstr_guid(riid),ppobj);
    if ( ( IsEqualGUID( &IID_IDirectDraw,  riid ) ) ||
	 ( IsEqualGUID( &IID_IDirectDraw2, riid ) ) ||
	 ( IsEqualGUID( &IID_IDirectDraw4, riid ) ) ) {
	    /* FIXME: reuse already created DirectDraw if present? */
	    return DirectDrawCreate((LPGUID) riid,(LPDIRECTDRAW*)ppobj,pOuter);
    }
    return CLASS_E_CLASSNOTAVAILABLE;
}

static HRESULT WINAPI DDCF_LockServer(LPCLASSFACTORY iface,BOOL dolock) {
    ICOM_THIS(IClassFactoryImpl,iface);
    FIXME("(%p)->(%d),stub!\n",This,dolock);
    return S_OK;
}

static ICOM_VTABLE(IClassFactory) DDCF_Vtbl = 
{
    ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
    DDCF_QueryInterface,
    DDCF_AddRef,
    DDCF_Release,
    DDCF_CreateInstance,
    DDCF_LockServer
};
static IClassFactoryImpl DDRAW_CF = {&DDCF_Vtbl, 1 };

/*******************************************************************************
 * DllGetClassObject [DDRAW.13]
 * Retrieves class object from a DLL object
 *
 * NOTES
 *    Docs say returns STDAPI
 *
 * PARAMS
 *    rclsid [I] CLSID for the class object
 *    riid   [I] Reference to identifier of interface for class object
 *    ppv    [O] Address of variable to receive interface pointer for riid
 *
 * RETURNS
 *    Success: S_OK
 *    Failure: CLASS_E_CLASSNOTAVAILABLE, E_OUTOFMEMORY, E_INVALIDARG,
 *             E_UNEXPECTED
 */
DWORD WINAPI DDRAW_DllGetClassObject(REFCLSID rclsid,REFIID riid,LPVOID *ppv)
{
    TRACE("(%p,%p,%p)\n", debugstr_guid(rclsid), debugstr_guid(riid), ppv);
    if ( IsEqualGUID( &IID_IClassFactory, riid ) ) {
    	*ppv = (LPVOID)&DDRAW_CF;
	IClassFactory_AddRef((IClassFactory*)*ppv);
	return S_OK;
    }
    FIXME("(%p,%p,%p): no interface found.\n", debugstr_guid(rclsid), debugstr_guid(riid), ppv);
    return CLASS_E_CLASSNOTAVAILABLE;
}


/*******************************************************************************
 * DllCanUnloadNow [DDRAW.12]  Determines whether the DLL is in use.
 *
 * RETURNS
 *    Success: S_OK
 *    Failure: S_FALSE
 */
DWORD WINAPI DDRAW_DllCanUnloadNow(void) {
    FIXME("(void): stub\n");
    return S_FALSE;
}
