#ifndef __SLABOP_H__ 
#define __SLABOP_H__ 

#pragma warning(disable: 4786) 

// "geep" is the sound you make when you pronounce "GPGPU".
namespace geep
{

struct NoopRenderTargetPolicy
{
  void ActivateRenderTarget()  {}
  void DeactivateRenderTarget() {}
};

struct NoopGLStatePolicy
{
  void SetGLState()   {}
  void ResetGLState() {}
};

struct NoopVertexPipePolicy
{
  void SetVertexPipeState()   {}
  void ResetVertexPipeState() {}
};

struct NoopFragmentPipePolicy
{
  void SetFragmentPipeState() {}
  void ResetFragmentPipeState() {}
};

struct NoopComputePolicy
{
  void Compute() {}
};

struct NoopUpdatePolicy
{
  void UpdateOutputSlab() {}
};

template 
<
  class RenderTargetPolicy,
  class GLStatePolicy,
  class VertexPipePolicy,
  class FragmentPipePolicy,
  class ComputePolicy,
  class UpdatePolicy
>
class SlabOp : public RenderTargetPolicy,
               public GLStatePolicy,
               public VertexPipePolicy,
               public FragmentPipePolicy,
               public ComputePolicy,
               public UpdatePolicy
{
public:
  SlabOp()  {}
  ~SlabOp() {}

  void Compute()
  {
    ActivateRenderTarget();
    SetGLState();
    SetVertexPipeState();
    SetFragmentPipeState();
    ComputePolicy::Compute();
    UpdateOutputSlab();
    ResetFragmentPipeState();
    ResetVertexPipeState();
    ResetGLState();
    DeactivateRenderTarget();
  }
  
protected:
private:
};

typedef SlabOp< NoopRenderTargetPolicy, 
                NoopGLStatePolicy,
                NoopVertexPipePolicy,
                NoopFragmentPipePolicy,
                NoopComputePolicy,
                NoopUpdatePolicy >
        SlabNop;

};

#endif //__SLABOP_H__