/*		DirectInput Device
 *
 * Copyright 1998 Marcus Meissner
 * Copyright 1998,1999 Lionel Ulmer
 *
 */

/* This file contains all the Device specific functions that can be used as stubs
   by real device implementations.

   It also contains all the helper functions.
*/
#include "config.h"

#include "debugtools.h"
#include "winbase.h"
#include "winerror.h"
#include "windef.h"
#include "dinput.h"
#include "device_private.h"

DEFAULT_DEBUG_CHANNEL(dinput);

/******************************************************************************
 *	Various debugging tools
 */
void _dump_cooperativelevel_DI(DWORD dwFlags) {
  int   i;
  const struct {
    DWORD       mask;
    char        *name;
  } flags[] = {
#define FE(x) { x, #x},
    FE(DISCL_BACKGROUND)
    FE(DISCL_EXCLUSIVE)
    FE(DISCL_FOREGROUND)
    FE(DISCL_NONEXCLUSIVE)
#undef FE
  };
  for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
    if (flags[i].mask & dwFlags)
      DPRINTF("%s ",flags[i].name);
  DPRINTF("\n");
}

void _dump_EnumObjects_flags(DWORD dwFlags) {
  int   i;
  const struct {
    DWORD       mask;
    char        *name;
  } flags[] = {
#define FE(x) { x, #x},
    FE(DIDFT_ABSAXIS)
    FE(DIDFT_ALL)
    FE(DIDFT_AXIS)
    FE(DIDFT_BUTTON)
    FE(DIDFT_COLLECTION)
    FE(DIDFT_FFACTUATOR)
    FE(DIDFT_FFEFFECTTRIGGER)
    FE(DIDFT_NOCOLLECTION)
    FE(DIDFT_NODATA)
    FE(DIDFT_OUTPUT)
    FE(DIDFT_POV)
    FE(DIDFT_PSHBUTTON)
    FE(DIDFT_RELAXIS)
    FE(DIDFT_TGLBUTTON)
#undef FE
  };
  if (dwFlags == DIDFT_ALL) {
    DPRINTF("DIDFT_ALL");
    return;
  }
  for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
    if (flags[i].mask & dwFlags)
      DPRINTF("%s ",flags[i].name);
  if (dwFlags & DIDFT_INSTANCEMASK)
    DPRINTF("Instance(%04lx) ", dwFlags >> 8);
}

void _dump_DIPROPHEADER(DIPROPHEADER *diph) {
  DPRINTF("  - dwObj = 0x%08lx\n", diph->dwObj);
  DPRINTF("  - dwHow = %s\n",
	  ((diph->dwHow == DIPH_DEVICE) ? "DIPH_DEVICE" :
	   ((diph->dwHow == DIPH_BYOFFSET) ? "DIPH_BYOFFSET" :
	    ((diph->dwHow == DIPH_BYID)) ? "DIPH_BYID" : "unknown")));
}

void _dump_OBJECTINSTANCEA(DIDEVICEOBJECTINSTANCEA *ddoi) {
  if (TRACE_ON(dinput)) {
    DPRINTF("    - enumerating : 0x%08lx - %2ld - 0x%08lx - %s\n",
	    ddoi->guidType.Data1, ddoi->dwOfs, ddoi->dwType, ddoi->tszName);
  }
}

/* Conversion between internal data buffer and external data buffer */
void fill_DataFormat(void *out, void *in, DataFormat *df) {
  int i;
  char *in_c = (char *) in;
  char *out_c = (char *) out;

  if (df->dt == NULL) {
    /* This means that the app uses Wine's internal data format */
    memcpy(out, in, df->internal_format_size);
  } else {
    for (i = 0; i < df->size; i++) {
      if (df->dt[i].offset_in >= 0) {
	switch (df->dt[i].size) {
	case 1:
	  TRACE("Copying (c) to %d from %d (value %d)\n",
		df->dt[i].offset_out, df->dt[i].offset_in, *((char *) (in_c + df->dt[i].offset_in)));
	  *((char *) (out_c + df->dt[i].offset_out)) = *((char *) (in_c + df->dt[i].offset_in));
	  break;
	
	case 2:
	  TRACE("Copying (s) to %d from %d (value %d)\n",
		df->dt[i].offset_out, df->dt[i].offset_in, *((short *) (in_c + df->dt[i].offset_in)));
	  *((short *) (out_c + df->dt[i].offset_out)) = *((short *) (in_c + df->dt[i].offset_in));
	  break;
	
	case 4:
	  TRACE("Copying (i) to %d from %d (value %d)\n",
		df->dt[i].offset_out, df->dt[i].offset_in, *((int *) (in_c + df->dt[i].offset_in)));
	  *((int *) (out_c + df->dt[i].offset_out)) = *((int *) (in_c + df->dt[i].offset_in));
	  break;
	
	default:
	  memcpy((out_c + df->dt[i].offset_out), (in_c + df->dt[i].offset_in), df->dt[i].size);
	}
      } else {
	switch (df->dt[i].size) {
	case 1:
	  TRACE("Copying (c) to %d default value %d\n",
		df->dt[i].offset_out, df->dt[i].value);
	  *((char *) (out_c + df->dt[i].offset_out)) = (char) df->dt[i].value;
	  break;
	
	case 2:
	  TRACE("Copying (s) to %d default value %d\n",
		df->dt[i].offset_out, df->dt[i].value);
	  *((short *) (out_c + df->dt[i].offset_out)) = (short) df->dt[i].value;
	  break;
	
	case 4:
	  TRACE("Copying (i) to %d default value %d\n",
		df->dt[i].offset_out, df->dt[i].value);
	  *((int *) (out_c + df->dt[i].offset_out)) = (int) df->dt[i].value;
	  break;
	
	default:
	  memset((out_c + df->dt[i].offset_out), df->dt[i].size, 0);
	}
      }
    }
  }
}

DataFormat *create_DataFormat(DIDATAFORMAT *wine_format, LPCDIDATAFORMAT asked_format, int *offset) {
  DataFormat *ret;
  DataTransform *dt;
  int i, j;
  int same = 1;
  int *done;
  int index = 0;
  
  ret = (DataFormat *) HeapAlloc(GetProcessHeap(), 0, sizeof(DataFormat));
  
  done = (int *) HeapAlloc(GetProcessHeap(), 0, sizeof(int) * asked_format->dwNumObjs);
  memset(done, 0, sizeof(int) * asked_format->dwNumObjs);

  dt = (DataTransform *) HeapAlloc(GetProcessHeap(), 0, asked_format->dwNumObjs * sizeof(DataTransform));

  TRACE("Creating DataTransorm : \n");
  
  for (i = 0; i < wine_format->dwNumObjs; i++) {
    offset[i] = -1;
    
    for (j = 0; j < asked_format->dwNumObjs; j++) {
      if (done[j] == 1)
	continue;
      
      if (((asked_format->rgodf[j].pguid == NULL) || (IsEqualGUID(wine_format->rgodf[i].pguid, asked_format->rgodf[j].pguid)))
	  &&
	  (wine_format->rgodf[i].dwType & asked_format->rgodf[j].dwType)) {

	done[j] = 1;

	TRACE("Matching : \n"); 
	TRACE("   - Asked (%d) : %s - Ofs = %3ld - (Type = 0x%02x | Instance = %04x)\n",
	      j, debugstr_guid(asked_format->rgodf[j].pguid), 
	      asked_format->rgodf[j].dwOfs,
	      DIDFT_GETTYPE(asked_format->rgodf[j].dwType), DIDFT_GETINSTANCE(asked_format->rgodf[j].dwType));
	
	TRACE("   - Wine  (%d) : %s - Ofs = %3ld - (Type = 0x%02x | Instance = %04x)\n",
	      j, debugstr_guid(wine_format->rgodf[i].pguid), 
	      wine_format->rgodf[i].dwOfs,
	      DIDFT_GETTYPE(wine_format->rgodf[i].dwType), DIDFT_GETINSTANCE(wine_format->rgodf[i].dwType));
	
	if (wine_format->rgodf[i].dwType & DIDFT_BUTTON)
	  dt[index].size = sizeof(BYTE);
	else
	  dt[index].size = sizeof(DWORD);
	dt[index].offset_in  = wine_format ->rgodf[i].dwOfs;
	dt[index].offset_out = asked_format->rgodf[j].dwOfs;
	dt[index].value = 0;
	index++;
	
	if (wine_format->rgodf[i].dwOfs != asked_format->rgodf[j].dwOfs)
	  same = 0;

	offset[i] = asked_format->rgodf[j].dwOfs;
	break;
      }
    }

    if (j == asked_format->dwNumObjs)
      same = 0;
  }

  TRACE("Setting to default value :\n");
  for (j = 0; j < asked_format->dwNumObjs; j++) {
    if (done[j] == 0) {
      TRACE(" - Asked (%d) : %s - Ofs = %3ld - (Type = 0x%02x | Instance = %04x)\n",
	    j, debugstr_guid(asked_format->rgodf[j].pguid), 
	    asked_format->rgodf[j].dwOfs,
	    DIDFT_GETTYPE(asked_format->rgodf[j].dwType), DIDFT_GETINSTANCE(asked_format->rgodf[j].dwType));

      
      if (asked_format->rgodf[j].dwType & DIDFT_BUTTON)
	dt[index].size = sizeof(BYTE);
      else
	dt[index].size = sizeof(DWORD);
      dt[index].offset_in  = -1;
      dt[index].offset_out = asked_format->rgodf[j].dwOfs;
      dt[index].value = 0;
      index++;

      same = 0;
    }
  }

  ret->internal_format_size = wine_format->dwDataSize;
  ret->size = index;
  if (same) {
    ret->dt = NULL;
    HeapFree(GetProcessHeap(), 0, dt);
  } else {
    ret->dt = dt;
  }
  
  HeapFree(GetProcessHeap(), 0, done);

  return ret;
}

/******************************************************************************
 *	IDirectInputDeviceA
 */

HRESULT WINAPI IDirectInputDevice2AImpl_SetDataFormat(
	LPDIRECTINPUTDEVICE2A iface,LPCDIDATAFORMAT df
) {
  int i;
  ICOM_THIS(IDirectInputDevice2AImpl,iface);

  TRACE("(this=%p,%p)\n",This,df);
  
  TRACE("df.dwSize=%ld\n",df->dwSize);
  TRACE("(df.dwObjsize=%ld)\n",df->dwObjSize);
  TRACE("(df.dwFlags=0x%08lx)\n",df->dwFlags);
  TRACE("(df.dwDataSize=%ld)\n",df->dwDataSize);
  TRACE("(df.dwNumObjs=%ld)\n",df->dwNumObjs);
  
  for (i=0;i<df->dwNumObjs;i++) {
    TRACE("df.rgodf[%d].guid %s\n",i,debugstr_guid(df->rgodf[i].pguid));
    TRACE("df.rgodf[%d].dwOfs %ld\n",i,df->rgodf[i].dwOfs);
    TRACE("dwType 0x%02x,dwInstance %d\n",DIDFT_GETTYPE(df->rgodf[i].dwType),DIDFT_GETINSTANCE(df->rgodf[i].dwType));
    TRACE("df.rgodf[%d].dwFlags 0x%08lx\n",i,df->rgodf[i].dwFlags);
  }
  return 0;
}

HRESULT WINAPI IDirectInputDevice2AImpl_SetCooperativeLevel(
	LPDIRECTINPUTDEVICE2A iface,HWND hwnd,DWORD dwflags
) {
	ICOM_THIS(IDirectInputDevice2AImpl,iface);
	TRACE("(this=%p,0x%08lx,0x%08lx)\n",This,(DWORD)hwnd,dwflags);
	if (TRACE_ON(dinput))
	  _dump_cooperativelevel_DI(dwflags);
	return 0;
}

HRESULT WINAPI IDirectInputDevice2AImpl_SetEventNotification(
	LPDIRECTINPUTDEVICE2A iface,HANDLE hnd
) {
	ICOM_THIS(IDirectInputDevice2AImpl,iface);
	FIXME("(this=%p,0x%08lx): stub\n",This,(DWORD)hnd);
	return 0;
}

ULONG WINAPI IDirectInputDevice2AImpl_Release(LPDIRECTINPUTDEVICE2A iface)
{
	ICOM_THIS(IDirectInputDevice2AImpl,iface);
	This->ref--;
	if (This->ref)
		return This->ref;
	HeapFree(GetProcessHeap(),0,This);
	return 0;
}

HRESULT WINAPI IDirectInputDevice2AImpl_QueryInterface(
	LPDIRECTINPUTDEVICE2A iface,REFIID riid,LPVOID *ppobj
)
{
	ICOM_THIS(IDirectInputDevice2AImpl,iface);

	TRACE("(this=%p,%s,%p)\n",This,debugstr_guid(riid),ppobj);
	if (IsEqualGUID(&IID_IUnknown,riid)) {
		IDirectInputDevice2_AddRef(iface);
		*ppobj = This;
		return 0;
	}
	if (IsEqualGUID(&IID_IDirectInputDeviceA,riid)) {
		IDirectInputDevice2_AddRef(iface);
		*ppobj = This;
		return 0;
	}
	if (IsEqualGUID(&IID_IDirectInputDevice2A,riid)) {
		IDirectInputDevice2_AddRef(iface);
		*ppobj = This;
		return 0;
	}
	TRACE("Unsupported interface !\n");
	return E_FAIL;
}

ULONG WINAPI IDirectInputDevice2AImpl_AddRef(
	LPDIRECTINPUTDEVICE2A iface)
{
	ICOM_THIS(IDirectInputDevice2AImpl,iface);
	return ++This->ref;
}

HRESULT WINAPI IDirectInputDevice2AImpl_EnumObjects(
	LPDIRECTINPUTDEVICE2A iface,
	LPDIENUMDEVICEOBJECTSCALLBACKA lpCallback,
	LPVOID lpvRef,
	DWORD dwFlags)
{
	FIXME("(this=%p,%p,%p,%08lx): stub!\n", iface, lpCallback, lpvRef, dwFlags);
	if (TRACE_ON(dinput)) {
	  DPRINTF("  - flags = ");
	  _dump_EnumObjects_flags(dwFlags);
	  DPRINTF("\n");
	}
	
	return DI_OK;
}
	
HRESULT WINAPI IDirectInputDevice2AImpl_GetProperty(
	LPDIRECTINPUTDEVICE2A iface,
	REFGUID rguid,
	LPDIPROPHEADER pdiph)
{
	FIXME("(this=%p,%s,%p): stub!\n",
	      iface, debugstr_guid(rguid), pdiph);
	
	if (TRACE_ON(dinput))
	  _dump_DIPROPHEADER(pdiph);
	
	return DI_OK;
}

HRESULT WINAPI IDirectInputDevice2AImpl_GetObjectInfo(
	LPDIRECTINPUTDEVICE2A iface,
	LPDIDEVICEOBJECTINSTANCEA pdidoi,
	DWORD dwObj,
	DWORD dwHow)
{
	FIXME("(this=%p,%p,%ld,0x%08lx): stub!\n",
	      iface, pdidoi, dwObj, dwHow);
	
	return DI_OK;
}
	
HRESULT WINAPI IDirectInputDevice2AImpl_GetDeviceInfo(
	LPDIRECTINPUTDEVICE2A iface,
	LPDIDEVICEINSTANCEA pdidi)
{
	FIXME("(this=%p,%p): stub!\n",
	      iface, pdidi);
	
	return DI_OK;
}
	
HRESULT WINAPI IDirectInputDevice2AImpl_RunControlPanel(
	LPDIRECTINPUTDEVICE2A iface,
	HWND hwndOwner,
	DWORD dwFlags)
{
  FIXME("(this=%p,0x%08x,0x%08lx): stub!\n",
	iface, hwndOwner, dwFlags);
	
	return DI_OK;
}
	
HRESULT WINAPI IDirectInputDevice2AImpl_Initialize(
	LPDIRECTINPUTDEVICE2A iface,
	HINSTANCE hinst,
	DWORD dwVersion,
	REFGUID rguid)
{
	FIXME("(this=%p,%d,%ld,%s): stub!\n",
	      iface, hinst, dwVersion, debugstr_guid(rguid));
	return DI_OK;
}
	
/******************************************************************************
 *	IDirectInputDevice2A
 */

HRESULT WINAPI IDirectInputDevice2AImpl_CreateEffect(
	LPDIRECTINPUTDEVICE2A iface,
	REFGUID rguid,
	LPCDIEFFECT lpeff,
	LPDIRECTINPUTEFFECT *ppdef,
	LPUNKNOWN pUnkOuter)
{
	FIXME("(this=%p,%s,%p,%p,%p): stub!\n",
	      iface, debugstr_guid(rguid), lpeff, ppdef, pUnkOuter);
	return DI_OK;
}

HRESULT WINAPI IDirectInputDevice2AImpl_EnumEffects(
	LPDIRECTINPUTDEVICE2A iface,
	LPDIENUMEFFECTSCALLBACKA lpCallback,
	LPVOID lpvRef,
	DWORD dwFlags)
{
	FIXME("(this=%p,%p,%p,0x%08lx): stub!\n",
	      iface, lpCallback, lpvRef, dwFlags);
	
	if (lpCallback)
		lpCallback(NULL, lpvRef);
	return DI_OK;
}

HRESULT WINAPI IDirectInputDevice2AImpl_GetEffectInfo(
	LPDIRECTINPUTDEVICE2A iface,
	LPDIEFFECTINFOA lpdei,
	REFGUID rguid)
{
	FIXME("(this=%p,%p,%s): stub!\n",
	      iface, lpdei, debugstr_guid(rguid));
	return DI_OK;
}

HRESULT WINAPI IDirectInputDevice2AImpl_GetForceFeedbackState(
	LPDIRECTINPUTDEVICE2A iface,
	LPDWORD pdwOut)
{
	FIXME("(this=%p,%p): stub!\n",
	      iface, pdwOut);
	return DI_OK;
}

HRESULT WINAPI IDirectInputDevice2AImpl_SendForceFeedbackCommand(
	LPDIRECTINPUTDEVICE2A iface,
	DWORD dwFlags)
{
	FIXME("(this=%p,0x%08lx): stub!\n",
	      iface, dwFlags);
	return DI_OK;
}

HRESULT WINAPI IDirectInputDevice2AImpl_EnumCreatedEffectObjects(
	LPDIRECTINPUTDEVICE2A iface,
	LPDIENUMCREATEDEFFECTOBJECTSCALLBACK lpCallback,
	LPVOID lpvRef,
	DWORD dwFlags)
{
	FIXME("(this=%p,%p,%p,0x%08lx): stub!\n",
	      iface, lpCallback, lpvRef, dwFlags);
	if (lpCallback)
		lpCallback(NULL, lpvRef);
	return DI_OK;
}

HRESULT WINAPI IDirectInputDevice2AImpl_Escape(
	LPDIRECTINPUTDEVICE2A iface,
	LPDIEFFESCAPE lpDIEEsc)
{
	FIXME("(this=%p,%p): stub!\n",
	      iface, lpDIEEsc);
	return DI_OK;
}

HRESULT WINAPI IDirectInputDevice2AImpl_Poll(
	LPDIRECTINPUTDEVICE2A iface)
{
	FIXME("(this=%p): stub!\n",
	      iface);
	return DI_OK;
}

HRESULT WINAPI IDirectInputDevice2AImpl_SendDeviceData(
	LPDIRECTINPUTDEVICE2A iface,
	DWORD cbObjectData,
	LPDIDEVICEOBJECTDATA rgdod,
	LPDWORD pdwInOut,
	DWORD dwFlags)
{
	FIXME("(this=%p,0x%08lx,%p,%p,0x%08lx): stub!\n",
	      iface, cbObjectData, rgdod, pdwInOut, dwFlags);
	
	return DI_OK;
}

HRESULT WINAPI IDirectInputDevice7AImpl_EnumEffectsInFile(LPDIRECTINPUTDEVICE7A iface,
							  LPCSTR lpszFileName,
							  LPDIENUMEFFECTSINFILECALLBACK pec,
							  LPVOID pvRef,
							  DWORD dwFlags)
{
  FIXME("(%p)->(%s,%p,%p,%08lx): stub !\n", iface, lpszFileName, pec, pvRef, dwFlags);

  return DI_OK;
}

HRESULT WINAPI IDirectInputDevice7AImpl_WriteEffectToFile(LPDIRECTINPUTDEVICE7A iface,
							  LPCSTR lpszFileName,
							  DWORD dwEntries,
							  LPDIFILEEFFECT rgDiFileEft,
							  DWORD dwFlags)
{
  FIXME("(%p)->(%s,%08lx,%p,%08lx): stub !\n", iface, lpszFileName, dwEntries, rgDiFileEft, dwFlags);
  
  return DI_OK;
}
