/*
 * IDirect3DBaseTexture9 implementation
 *
 * Copyright 2002-2004 Jason Edmeades
 *                     Raphael Junqueira
 *
 * 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 "d3d9_private.h"

WINE_DEFAULT_DEBUG_CHANNEL(d3d);

/* IDirect3DBaseTexture9 IUnknown parts follow: */
HRESULT WINAPI IDirect3DBaseTexture9Impl_QueryInterface(LPDIRECT3DBASETEXTURE9 iface, REFIID riid, LPVOID* ppobj) {
    IDirect3DBaseTexture9Impl *This = (IDirect3DBaseTexture9Impl *)iface;

    if (IsEqualGUID(riid, &IID_IUnknown)
        || IsEqualGUID(riid, &IID_IDirect3DResource9)
        || IsEqualGUID(riid, &IID_IDirect3DBaseTexture9)) {
        IDirect3DBaseTexture9Impl_AddRef(iface);
        *ppobj = This;
        return D3D_OK;
    }

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

ULONG WINAPI IDirect3DBaseTexture9Impl_AddRef(LPDIRECT3DBASETEXTURE9 iface) {
    IDirect3DBaseTexture9Impl *This = (IDirect3DBaseTexture9Impl *)iface;
    ULONG ref = InterlockedIncrement(&This->ref);

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

    return ref;
}

ULONG WINAPI IDirect3DBaseTexture9Impl_Release(LPDIRECT3DBASETEXTURE9 iface) {
    IDirect3DBaseTexture9Impl *This = (IDirect3DBaseTexture9Impl *)iface;
    ULONG ref = InterlockedDecrement(&This->ref);

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

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

/* IDirect3DBaseTexture9 IDirect3DResource9 Interface follow: */
HRESULT WINAPI IDirect3DBaseTexture9Impl_GetDevice(LPDIRECT3DBASETEXTURE9 iface, IDirect3DDevice9** ppDevice) {
    IDirect3DBaseTexture9Impl *This = (IDirect3DBaseTexture9Impl *)iface;
    return IDirect3DResource9Impl_GetDevice((LPDIRECT3DRESOURCE9) This, ppDevice);
}

HRESULT WINAPI IDirect3DBaseTexture9Impl_SetPrivateData(LPDIRECT3DBASETEXTURE9 iface, REFGUID refguid, CONST void* pData, DWORD SizeOfData, DWORD Flags) {
    IDirect3DBaseTexture9Impl *This = (IDirect3DBaseTexture9Impl *)iface;
    return IWineD3DBaseTexture_SetPrivateData(This->wineD3DBaseTexture, refguid, pData, SizeOfData, Flags);
}

HRESULT WINAPI IDirect3DBaseTexture9Impl_GetPrivateData(LPDIRECT3DBASETEXTURE9 iface, REFGUID refguid, void* pData, DWORD* pSizeOfData) {
    IDirect3DBaseTexture9Impl *This = (IDirect3DBaseTexture9Impl *)iface;
    return IWineD3DBaseTexture_GetPrivateData(This->wineD3DBaseTexture, refguid, pData, pSizeOfData);
}

HRESULT WINAPI IDirect3DBaseTexture9Impl_FreePrivateData(LPDIRECT3DBASETEXTURE9 iface, REFGUID refguid) {
    IDirect3DBaseTexture9Impl *This = (IDirect3DBaseTexture9Impl *)iface;
    return IWineD3DBaseTexture_FreePrivateData(This->wineD3DBaseTexture, refguid);
}

DWORD WINAPI IDirect3DBaseTexture9Impl_SetPriority(LPDIRECT3DBASETEXTURE9 iface, DWORD PriorityNew) {
    IDirect3DBaseTexture9Impl *This = (IDirect3DBaseTexture9Impl *)iface;
    return IWineD3DBaseTexture_SetPriority(This->wineD3DBaseTexture, PriorityNew);
}

DWORD WINAPI IDirect3DBaseTexture9Impl_GetPriority(LPDIRECT3DBASETEXTURE9 iface) {
    IDirect3DBaseTexture9Impl *This = (IDirect3DBaseTexture9Impl *)iface;
    return IWineD3DBaseTexture_GetPriority(This->wineD3DBaseTexture);
}

void WINAPI IDirect3DBaseTexture9Impl_PreLoad(LPDIRECT3DBASETEXTURE9 iface) {
    IDirect3DBaseTexture9Impl *This = (IDirect3DBaseTexture9Impl *)iface;
    IWineD3DBaseTexture_PreLoad(This->wineD3DBaseTexture);
    return ;
}

D3DRESOURCETYPE WINAPI IDirect3DBaseTexture9Impl_GetType(LPDIRECT3DBASETEXTURE9 iface) {
    IDirect3DBaseTexture9Impl *This = (IDirect3DBaseTexture9Impl *)iface;
    return IWineD3DBaseTexture_GetType(This->wineD3DBaseTexture);
}

/* IDirect3DBaseTexture9 Interface follow: */
DWORD  WINAPI IDirect3DBaseTexture9Impl_SetLOD(LPDIRECT3DBASETEXTURE9 iface, DWORD LODNew) {
    IDirect3DBaseTexture9Impl *This = (IDirect3DBaseTexture9Impl *)iface;
    return IWineD3DBaseTexture_SetLOD(This->wineD3DBaseTexture, LODNew);
}

DWORD WINAPI IDirect3DBaseTexture9Impl_GetLOD(LPDIRECT3DBASETEXTURE9 iface) {
    IDirect3DBaseTexture9Impl *This = (IDirect3DBaseTexture9Impl *)iface;
    return IWineD3DBaseTexture_GetLOD(This->wineD3DBaseTexture);
}

DWORD WINAPI IDirect3DBaseTexture9Impl_GetLevelCount(LPDIRECT3DBASETEXTURE9 iface) {
    IDirect3DBaseTexture9Impl *This = (IDirect3DBaseTexture9Impl *)iface;
    return IWineD3DBaseTexture_GetLevelCount(This->wineD3DBaseTexture);
}

HRESULT WINAPI IDirect3DBaseTexture9Impl_SetAutoGenFilterType(LPDIRECT3DBASETEXTURE9 iface, D3DTEXTUREFILTERTYPE FilterType) {
    IDirect3DBaseTexture9Impl *This = (IDirect3DBaseTexture9Impl *)iface;
    return IWineD3DBaseTexture_SetAutoGenFilterType(This->wineD3DBaseTexture, FilterType);
}

D3DTEXTUREFILTERTYPE WINAPI IDirect3DBaseTexture9Impl_GetAutoGenFilterType(LPDIRECT3DBASETEXTURE9 iface) {
    IDirect3DBaseTexture9Impl *This = (IDirect3DBaseTexture9Impl *)iface;
    return IWineD3DBaseTexture_GetAutoGenFilterType(This->wineD3DBaseTexture);
}

void WINAPI IDirect3DBaseTexture9Impl_GenerateMipSubLevels(LPDIRECT3DBASETEXTURE9 iface) {
    IDirect3DBaseTexture9Impl *This = (IDirect3DBaseTexture9Impl *)iface;
    return IWineD3DBaseTexture_GenerateMipSubLevels(This->wineD3DBaseTexture);
}

IDirect3DBaseTexture9Vtbl Direct3DBaseTexture9_Vtbl =
{
    IDirect3DBaseTexture9Impl_QueryInterface,
    IDirect3DBaseTexture9Impl_AddRef,
    IDirect3DBaseTexture9Impl_Release,
    IDirect3DBaseTexture9Impl_GetDevice,
    IDirect3DBaseTexture9Impl_SetPrivateData,
    IDirect3DBaseTexture9Impl_GetPrivateData,
    IDirect3DBaseTexture9Impl_FreePrivateData,
    IDirect3DBaseTexture9Impl_SetPriority,
    IDirect3DBaseTexture9Impl_GetPriority,
    IDirect3DBaseTexture9Impl_PreLoad,
    IDirect3DBaseTexture9Impl_GetType,
    IDirect3DBaseTexture9Impl_SetLOD,
    IDirect3DBaseTexture9Impl_GetLOD,
    IDirect3DBaseTexture9Impl_GetLevelCount,
    IDirect3DBaseTexture9Impl_SetAutoGenFilterType,
    IDirect3DBaseTexture9Impl_GetAutoGenFilterType,
    IDirect3DBaseTexture9Impl_GenerateMipSubLevels   
};
