/*		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 "dc.h"
#include "win.h"
#include "wine/exception.h"
#include "ddraw.h"
#include "d3d.h"
#include "debugtools.h"
#include "message.h"
#include "monitor.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 ) {
		WND *tmpWnd =WIN_FindWndPtr(ddraw->d->mainWindow);
		/* We didn't handle the message - give it to the application */
		if (ddraw && ddraw->d->mainWindow && tmpWnd)
		    ret = CallWindowProcA(tmpWnd->winproc,
		ddraw->d->mainWindow, msg, wParam, lParam );
		WIN_ReleaseWndPtr(tmpWnd);
	    }
	    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;
}
