// MaterialHook.h : Declaration of the CMaterialHook

#ifndef __MATERIALHOOK_H_
#define __MATERIALHOOK_H_

#include "resource.h"       // main symbols

#include "Direct3DHook.h"
#include "DirectDrawHook.h"

/////////////////////////////////////////////////////////////////////////////
// CMaterialHook
class ATL_NO_VTABLE CMaterialHook : 
	public CComObjectRootEx<CComMultiThreadModel>,
   public IDirect3DMaterial,
   public IDirect3DMaterial2,
   public IDirect3DMaterial3
{
public:
	CMaterialHook()
	{
	}

DECLARE_PROTECT_FINAL_CONSTRUCT()

BEGIN_COM_MAP(CMaterialHook)
   COM_INTERFACE_ENTRY_IID(IID_IDirect3DMaterial, IDirect3DMaterial)
   COM_INTERFACE_ENTRY_IID(IID_IDirect3DMaterial2, IDirect3DMaterial2)
   COM_INTERFACE_ENTRY_IID(IID_IDirect3DMaterial3, IDirect3DMaterial3)
END_COM_MAP()

   CComPtr< IDirect3DMaterial > m_pMaterial;
   CComPtr< IDirect3DMaterial2 > m_pMaterial2;
   CComPtr< IDirect3DMaterial3 > m_pMaterial3;

   D3DMATERIALHANDLE m_hMaterial;

   void setObject( IUnknown *pUnk, IDirect3DDevice2 *pDevice2, IDirect3DDevice3 *pDevice3 )
   {
      pUnk->QueryInterface( IID_IDirect3DMaterial, reinterpret_cast< void ** >( &m_pMaterial ) );
      pUnk->QueryInterface( IID_IDirect3DMaterial2, reinterpret_cast< void ** >( &m_pMaterial2 ) );
      pUnk->QueryInterface( IID_IDirect3DMaterial3, reinterpret_cast< void ** >( &m_pMaterial3 ) );

      if( pDevice2 != NULL )
         m_pMaterial2->GetHandle( pDevice2, &m_hMaterial );
      else if( pDevice3 != NULL )
         m_pMaterial3->GetHandle( pDevice3, &m_hMaterial );
   }

// IMaterialHook
public:

   // Methods from IDirect3DMaterial
    STDMETHOD(Initialize)(LPDIRECT3D p1)
    {
       CDirectDrawHook *pHook = static_cast< CDirectDrawHook * >( p1 );
       return m_pMaterial->Initialize( pHook->m_pD3D );
    }

    STDMETHOD(SetMaterial)(LPD3DMATERIAL p1)
    {
       return m_pMaterial->SetMaterial( p1 );
    }

    STDMETHOD(GetMaterial)(LPD3DMATERIAL p1)
    {
       return m_pMaterial->GetMaterial( p1 );
    }

    STDMETHOD(GetHandle)(LPDIRECT3DDEVICE p1,LPD3DMATERIALHANDLE p2)
    {
       *p2 = m_hMaterial;
       return S_OK;
       /*
       CDirect3DHook *pHook = dynamic_cast< CDirect3DHook * >( p1 );
       if( pHook != NULL )
         return m_pMaterial->GetHandle( pHook->m_pDevice, p2 );
       return m_pMaterial->GetHandle( p1, p2 );
       */
    }

    STDMETHOD(Reserve)()
    {
       return m_pMaterial->Reserve();
    }

    STDMETHOD(Unreserve)()
    {
       return m_pMaterial->Unreserve();
    }

    // Methods from IDirect3DMaterial2
    STDMETHOD(GetHandle)(LPDIRECT3DDEVICE2 p1,LPD3DMATERIALHANDLE p2)
    {
       *p2 = m_hMaterial;
       return S_OK;
       /*
       CDirect3DHook *pHook = dynamic_cast< CDirect3DHook * >( p1 );
       return m_pMaterial2->GetHandle( pHook->m_pDevice2, p2 );
       */
    }

    // Methods from IDirect3DMaterial3
    STDMETHOD(GetHandle)(LPDIRECT3DDEVICE3 p1,LPD3DMATERIALHANDLE p2)
    {
       *p2 = m_hMaterial;
       return S_OK;
       /*
       CDirect3DHook *pHook = dynamic_cast< CDirect3DHook * >( p1 );
       return m_pMaterial3->GetHandle( pHook->m_pDevice3, p2 );
       */
    }
};

#endif //__MATERIALHOOK_H_
