/*
 * IDirect3DStateBlock8 implementation
 *
 * Copyright 2002-2003 Raphael Junqueira
 * Copyright 2002-2003 Jason Edmeades
 * Copyright 2005 Oliver Stieber
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#include "config.h"
#include "d3d8_private.h"

WINE_DEFAULT_DEBUG_CHANNEL(d3d8);

/* NOTE: DirectX8 doesn't export a IDirect3DStateBlock8, the interface is used internally to keep d3d8 and d3d9 as simila as possible */
/* IDirect3DStateBlock8 IUnknown parts follow: */
HRESULT WINAPI IDirect3DStateBlock8Impl_QueryInterface(IDirect3DStateBlock8 *iface, REFIID riid, LPVOID *ppobj) {
    IDirect3DStateBlock8Impl *This = (IDirect3DStateBlock8Impl *)iface;

    if (IsEqualGUID(riid, &IID_IUnknown)
        || IsEqualGUID(riid, &IID_IDirect3DStateBlock8)) {
        IUnknown_AddRef(iface);
        *ppobj = This;
        return D3D_OK;
    }

    WARN("(%p)->(%s,%p),not found\n", This, debugstr_guid(riid), ppobj);
    return E_NOINTERFACE;
}

ULONG WINAPI IDirect3DStateBlock8Impl_AddRef(IDirect3DStateBlock8 *iface) {
    IDirect3DStateBlock8Impl *This = (IDirect3DStateBlock8Impl *)iface;
    ULONG ref = InterlockedIncrement(&This->ref);

    TRACE("(%p) : AddRef from %ld\n", This, ref - 1);

    return ref;
}

ULONG WINAPI IDirect3DStateBlock8Impl_Release(IDirect3DStateBlock8 *iface) {
    IDirect3DStateBlock8Impl *This = (IDirect3DStateBlock8Impl *)iface;
    ULONG ref = InterlockedDecrement(&This->ref);

    TRACE("(%p) : ReleaseRef to %ld\n", This, ref);

    if (ref == 0) {
        IWineD3DStateBlock_Release(This->wineD3DStateBlock);
        HeapFree(GetProcessHeap(), 0, This);
    }
    return ref;
}

/* IDirect3DStateBlock8 Interface follow: */
HRESULT WINAPI IDirect3DStateBlock8Impl_GetDevice(IDirect3DStateBlock8 *iface, IDirect3DDevice8 **ppDevice) {
    IDirect3DStateBlock8Impl *This = (IDirect3DStateBlock8Impl *)iface;
    TRACE("(%p) Relay\n", This); 
    return IDirect3DResource8Impl_GetDevice((LPDIRECT3DRESOURCE8) This, ppDevice);
}

HRESULT WINAPI IDirect3DStateBlock8Impl_Capture(IDirect3DStateBlock8 *iface) {
    IDirect3DStateBlock8Impl *This = (IDirect3DStateBlock8Impl *)iface;
    TRACE("(%p) Relay\n", This); 
    return IWineD3DStateBlock_Capture(This->wineD3DStateBlock);
}

HRESULT WINAPI IDirect3DStateBlock8Impl_Apply(IDirect3DStateBlock8 *iface) {
    IDirect3DStateBlock8Impl *This = (IDirect3DStateBlock8Impl *)iface;
    TRACE("(%p) Relay\n", This); 
    return IWineD3DStateBlock_Apply(This->wineD3DStateBlock);
}

const IDirect3DStateBlock8Vtbl Direct3DStateBlock8_Vtbl =
{
    /* IUnknown */
    IDirect3DStateBlock8Impl_QueryInterface,
    IDirect3DStateBlock8Impl_AddRef,
    IDirect3DStateBlock8Impl_Release,
    /* IDirect3DStateBlock8 */
    IDirect3DStateBlock8Impl_GetDevice,
    IDirect3DStateBlock8Impl_Capture,
    IDirect3DStateBlock8Impl_Apply
};
