module Graphics.Rendering.OpenGL.GL.SavingState (
   ServerAttributeGroup(..), preservingAttrib,
   ClientAttributeGroup(..), preservingClientAttrib
) where
import Graphics.Rendering.OpenGL.GL.Exception ( bracket_ )
import Graphics.GL
data ServerAttributeGroup =
     CurrentAttributes
   | PointAttributes
   | LineAttributes
   | PolygonAttributes
   | PolygonStippleAttributes
   | PixelModeAttributes
   | LightingAttributes
   | FogAttributes
   | DepthBufferAttributes
   | AccumBufferAttributes
   | StencilBufferAttributes
   | ViewportAttributes
   | TransformAttributes
   | EnableAttributes
   | ColorBufferAttributes
   | HintAttributes
   | EvalAttributes
   | ListAttributes
   | TextureAttributes
   | ScissorAttributes
   | MultisampleAttributes
   | AllServerAttributes
   deriving ( Eq, Ord, Show )
marshalServerAttributeGroup :: ServerAttributeGroup -> GLbitfield
marshalServerAttributeGroup x = case x of
   CurrentAttributes -> GL_CURRENT_BIT
   PointAttributes -> GL_POINT_BIT
   LineAttributes -> GL_LINE_BIT
   PolygonAttributes -> GL_POLYGON_BIT
   PolygonStippleAttributes -> GL_POLYGON_STIPPLE_BIT
   PixelModeAttributes -> GL_PIXEL_MODE_BIT
   LightingAttributes -> GL_LIGHTING_BIT
   FogAttributes -> GL_FOG_BIT
   DepthBufferAttributes -> GL_DEPTH_BUFFER_BIT
   AccumBufferAttributes -> GL_ACCUM_BUFFER_BIT
   StencilBufferAttributes -> GL_STENCIL_BUFFER_BIT
   ViewportAttributes -> GL_VIEWPORT_BIT
   TransformAttributes -> GL_TRANSFORM_BIT
   EnableAttributes -> GL_ENABLE_BIT
   ColorBufferAttributes -> GL_COLOR_BUFFER_BIT
   HintAttributes -> GL_HINT_BIT
   EvalAttributes -> GL_EVAL_BIT
   ListAttributes -> GL_LIST_BIT
   TextureAttributes -> GL_TEXTURE_BIT
   ScissorAttributes -> GL_SCISSOR_BIT
   MultisampleAttributes -> GL_MULTISAMPLE_BIT
   AllServerAttributes -> GL_ALL_ATTRIB_BITS
preservingAttrib :: [ServerAttributeGroup] -> IO a -> IO a
preservingAttrib groups = bracket_ (pushAttrib groups) glPopAttrib
pushAttrib :: [ServerAttributeGroup] -> IO ()
pushAttrib = glPushAttrib . sum . map marshalServerAttributeGroup
data ClientAttributeGroup =
     PixelStoreAttributes
   | VertexArrayAttributes
   | AllClientAttributes
   deriving ( Eq, Ord, Show )
marshalClientAttributeGroup :: ClientAttributeGroup -> GLbitfield
marshalClientAttributeGroup x = case x of
   PixelStoreAttributes -> GL_CLIENT_PIXEL_STORE_BIT
   VertexArrayAttributes -> GL_CLIENT_VERTEX_ARRAY_BIT
   AllClientAttributes -> GL_CLIENT_ALL_ATTRIB_BITS
preservingClientAttrib :: [ClientAttributeGroup] -> IO a -> IO a
preservingClientAttrib groups =
   bracket_ (pushClientAttrib groups) glPopClientAttrib
pushClientAttrib :: [ClientAttributeGroup] -> IO ()
pushClientAttrib = glPushClientAttrib . sum . map marshalClientAttributeGroup