#ifndef __SM_D3D

#define __SM_D3D

#include <d3d8.h>

namespace SM_D3d
{
  // General initialization control
  int Init();
  int Shutdown();

  // Display control
  int InitDisplay(HWND hwnd, 
                  unsigned uWidth, 
                  unsigned uHeight, 
                  unsigned uBPP, 
                  bool bStencil, 
                  bool bFullscreen, 
                  int (*Requirements)(int iMode), 
                  char* pcRequirement, 
                  bool bAntialias=false, 
                  bool bWaitRetrace=true, 
                  bool bUpdateWindow = false,
                  bool bLockable = false);


  int ShutdownDisplay();
  int ToggleFullScreen();


  // Device
  IDirect3D8*         D3D();
  IDirect3DDevice8*   Device();
  D3DCAPS8* const     DeviceCaps();         


  // Modes
  struct   D3DModeDescriptor
  {    
    unsigned    uDevice;
    unsigned    uMode;
    unsigned    uWidth;
    unsigned    uHeight;
    unsigned    uBPP;
    D3DFORMAT   d3dFormat;
    unsigned    uRefresh;
    int         bFullscreen             :1;
    int         bWindowed               :1;
    int         bMultisamplingWindowed  :1;
    int         bMultisamplingFullscreen:1;
    int         bStencil:1;
    int         iDepthStencilFlags;
    D3DCAPS8    dcDeviceCaps;
  };

  int                       EnumerateModes();
  unsigned                  AvailableModes();
  D3DModeDescriptor* const  GetModes();  
  D3DModeDescriptor* const  GetCurrentMode();

  // Helpers con cache
  HRESULT SetRenderState      (D3DRENDERSTATETYPE State, DWORD Value);  
  HRESULT SetTextureStageState(DWORD Stage, D3DTEXTURESTAGESTATETYPE State, DWORD Value);
  
  // Frame  
  int StartFrame();
  int EndFrame();

  // Callbacks
  class IRestorable
  {
  public:
    virtual int RestoreInit()=0;
    virtual int RestoreShut()=0;    
  };

  int AddRestorable(IRestorable* pRestorable);
  int RemoveRestorable(IRestorable* pRestorable);  
}

#endif