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

/* 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;
    GUID	zeroGUID;
    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");
    }
    if (dwFlags & DDENUM_ATTACHEDSECONDARYDEVICES) {
	FIXME("no attached secondary devices supported.\n");
	/*return E_FAIL;*/
    }

    memset(&zeroGUID,0,sizeof(zeroGUID));

    /* we have at least one DDRAW driver */
    if (ddraw_drivers[0]) {
	if (!lpCallback(
	    &zeroGUID, /* FIXME: or NULL? -MM */
	    "WINE DirectDraw",
	    "display",
	    lpContext,
	    0		/* FIXME: flags not supported here */
	))
	    return DD_OK;
    }
    /* 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");
    }
    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 */
    }

    if (lpGUID &&
	(IsEqualGUID( &IID_IDirectDraw2, lpGUID ) ||
	 IsEqualGUID( &IID_IDirectDraw4, lpGUID ) ||
	 IsEqualGUID( &IID_IDirectDraw7, lpGUID )
	)
    ) {
	LPVOID x;
	ret = IDirectDraw_QueryInterface(*lplpDD,lpGUID,&x);
	IDirectDraw_Release(*lplpDD); /* either drop 1 refcount, or release */
	if (!ret)
	    *lplpDD = x;
	else
	    return ret;
    }
    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
) {
  LPDIRECTDRAW	ddraw;
  HRESULT	hres;

  FIXME("(%p,%p,%s,%p), might be wrong.\n",lpGUID,lplpDD,debugstr_guid(iid),pUnkOuter);

  hres=DirectDrawCreate(lpGUID,(LPDIRECTDRAW*)&ddraw,pUnkOuter);
  if (!hres) {
      hres=IDirectDraw_QueryInterface(ddraw,iid,lplpDD);
      IDirectDraw_Release(ddraw);
  }
  return hres;
}

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