/*
 * Direct3D9 swap chains
 * Copyright (c) 2004 TransGaming Technologies Inc.
 */


#include "winbase.h"
#include "d3d9.h"

#include "d3d9_private.h"
#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(ddraw);

HRESULT WINAPI Direct3DSwapChain9_QueryInterface(
          LPDIRECT3DSWAPCHAIN9 iface, REFIID riid, LPVOID* obj )
{
  ICOM_THIS(IDirect3DSwapChain9Impl, iface);

  TRACE( "(%p)->(%s,%p)\n", iface, debugstr_guid(riid), obj );

  if( IsEqualGUID( &IID_IDirect3DSwapChain9, riid ) )
  {
    This->ref++;
    *obj = This;
    return S_OK;
  }

  ERR( "(%p)->(%s): no interface\n", iface, debugstr_guid(riid) );
 
  return E_NOINTERFACE;
}
                                                                                                                                                                        
ULONG WINAPI Direct3DSwapChain9_AddRef( LPDIRECT3DSWAPCHAIN9 iface )
{
  ICOM_THIS(IDirect3DSwapChain9Impl, iface);

  TRACE( "(%p)->()\n", iface );

  return ++This->ref;
}

ULONG WINAPI Direct3DSwapChain9_Release( LPDIRECT3DSWAPCHAIN9 iface )
{
  ICOM_THIS(IDirect3DSwapChain9Impl, iface);
  ULONG uRef;

  TRACE( "(%p)->()\n", iface );

  uRef = --This->ref;

  if( uRef == 0 )
  {
    HeapFree( GetProcessHeap(), 0, This );
  }
  
  return uRef;
}

HRESULT WINAPI Direct3DSwapChain9_Present(
          LPDIRECT3DSWAPCHAIN9 iface, CONST RECT* pSourceRect,
          CONST RECT* pDestRect, HWND hDestWindowOverride,
          CONST RGNDATA* pDirtyRegion, DWORD dwFlags )
{
  FIXME( "(%p)->(%p,%p,%d,%p,%lx):stub\n", iface, pSourceRect, pDestRect, hDestWindowOverride,
                                             pDirtyRegion, dwFlags );
  return D3D_OK;
}

HRESULT WINAPI Direct3DSwapChain9_GetFrontBufferData(
          LPDIRECT3DSWAPCHAIN9 iface, IDirect3DSurface9* pDestSurface )
{
  FIXME( "(%p)->(%p):stub\n", iface, pDestSurface );
  return D3D_OK;
}

HRESULT WINAPI Direct3DSwapChain9_GetBackBuffer(
          LPDIRECT3DSWAPCHAIN9 iface, UINT BackBuffer,
          D3DBACKBUFFER_TYPE Type, IDirect3DSurface9** ppBackBuffer )
{
  FIXME( "(%p)->(%u,%u,%p):stub\n", iface, BackBuffer, Type, ppBackBuffer );
  return D3D_OK;
}

HRESULT WINAPI Direct3DSwapChain9_GetRasterStatus(
          LPDIRECT3DSWAPCHAIN9 iface, D3DRASTER_STATUS* pRasterStatus )
{
  FIXME( "(%p)->(%p):stub\n", iface, pRasterStatus );
  return D3D_OK;
}

HRESULT WINAPI Direct3DSwapChain9_GetDisplayMode(
          LPDIRECT3DSWAPCHAIN9 iface, D3DDISPLAYMODE* pMode )
{
  FIXME( "(%p)->(%p):stub\n", iface, pMode );
  return D3D_OK;
}

HRESULT WINAPI Direct3DSwapChain9_GetDevice(
          LPDIRECT3DSWAPCHAIN9 iface, IDirect3DDevice9** ppDevice )
{
  FIXME( "(%p)->(%p):stub\n", iface, ppDevice );
  return D3D_OK;
}

HRESULT WINAPI Direct3DSwapChain9_GetPresentParameters(
          LPDIRECT3DSWAPCHAIN9 iface, D3DPRESENT_PARAMETERS* pPresentationParameters )
{
  FIXME( "(%p)->(%p):stub\n", iface, pPresentationParameters );
  return D3D_OK;
}


static ICOM_VTABLE( IDirect3DSwapChain9 ) D3D9SC_Vtbl =
{
  ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
  Direct3DSwapChain9_QueryInterface,
  Direct3DSwapChain9_AddRef,
  Direct3DSwapChain9_Release,
  Direct3DSwapChain9_Present,
  Direct3DSwapChain9_GetFrontBufferData,
  Direct3DSwapChain9_GetBackBuffer,
  Direct3DSwapChain9_GetRasterStatus,
  Direct3DSwapChain9_GetDisplayMode,
  Direct3DSwapChain9_GetDevice,
  Direct3DSwapChain9_GetPresentParameters
};


UINT WINAPI Direct3DDevice9_GetNumberOfSwapChains( LPDIRECT3DDEVICE9 iface )
{
  FIXME( "(%p)->(): stub\n", iface );
  return 0;
}

HRESULT WINAPI Direct3DDevice9_CreateAdditionalSwapChain(
    LPDIRECT3DDEVICE9 iface,
    D3DPRESENT_PARAMETERS* pPresentationParameters,
    IDirect3DSwapChain9** ppSwapChain )
{
  ICOM_THIS(IDirect3DDevice9Impl, iface);
  IDirect3DSwapChain9Impl* obj;

  FIXME( "(%p)->(%p,%p): stub\n", iface, pPresentationParameters, ppSwapChain );

  obj = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof( IDirect3DSwapChain9Impl ) );
  *ppSwapChain = (IDirect3DSwapChain9*)obj;

  if( obj == NULL ) return DDERR_OUTOFMEMORY;

  obj->lpVtbl = &D3D9SC_Vtbl;
  obj->ref    = 1;
  obj->parent = This;

  return D3D_OK;
}

HRESULT WINAPI Direct3DDevice9_GetSwapChain( LPDIRECT3DDEVICE9 iface, 
         UINT iSwapChain, IDirect3DSwapChain9 **ppSwapChain )
{
  ICOM_THIS(IDirect3DDevice9Impl, iface);
  IDirect3DSwapChain9Impl* obj;

  FIXME( "(%p)->(%u,%p): stub\n", iface,iSwapChain, ppSwapChain );

  obj = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof( IDirect3DSwapChain9Impl ) );
  *ppSwapChain = (IDirect3DSwapChain9*)obj;

  if( obj == NULL ) return DDERR_OUTOFMEMORY;

  obj->lpVtbl = &D3D9SC_Vtbl;
  obj->ref    = 1;
  obj->parent = This;

  return D3D_OK;
}
