dumpStateGLFW :: IORef GLFWState -> IO ()
dumpStateGLFW ref = do
  maybeWin <- ref ^@ glfwWindow
  case maybeWin of
    Nothing      -> return ()
    Just glfwWin -> do
      version       <- GLFW.getVersion
      versionString <- GLFW.getVersionString
      monitorInfos  <- runMaybeT getMonitorInfos
      joystickNames <- getJoystickNames
      clientAPI     <- GLFW.getWindowClientAPI              glfwWin
      cv0           <- GLFW.getWindowContextVersionMajor    glfwWin
      cv1           <- GLFW.getWindowContextVersionMinor    glfwWin
      cv2           <- GLFW.getWindowContextVersionRevision glfwWin
      robustness    <- GLFW.getWindowContextRobustness      glfwWin
      forwardCompat <- GLFW.getWindowOpenGLForwardCompat    glfwWin
      debug         <- GLFW.getWindowOpenGLDebugContext     glfwWin
      profile       <- GLFW.getWindowOpenGLProfile          glfwWin

      putStrLn $ render $
        nest 4 (
          text "------------------------------------------------------------" $+$
          text "GLFW C library:" $+$
          nest 4 (
            text "Version:"        <+> renderVersion version $+$
            text "Version string:" <+> renderVersionString versionString
          ) $+$
          text "Monitors:" $+$
          nest 4 (
            renderMonitorInfos monitorInfos
          ) $+$
          text "Joysticks:" $+$
          nest 4 (
            renderJoystickNames joystickNames
          ) $+$
          text "OpenGL context:" $+$
          nest 4 (
            text "Client API:"            <+> renderClientAPI clientAPI $+$
            text "Version:"               <+> renderContextVersion cv0 cv1 cv2 $+$
            text "Robustness:"            <+> renderContextRobustness robustness $+$
            text "Forward compatibility:" <+> renderForwardCompat forwardCompat $+$
            text "Debug:"                 <+> renderDebug debug $+$
            text "Profile:"               <+> renderProfile profile
          ) $+$
          text "------------------------------------------------------------"
        )
  where
    renderVersion (GLFW.Version v0 v1 v2) =
        text $ intercalate "." $ map show [v0, v1, v2]

    renderVersionString =
        text . show

    renderMonitorInfos =
        maybe (text "(error)") (vcat . map renderMonitorInfo)

    renderMonitorInfo (name, (x,y), (w,h), vms) =
        text (show name) $+$
        nest 4 (
          location <+> size $+$
          fsep (map renderVideoMode vms)
        )
      where
        location = int x <> text "," <> int y
        size     = int w <> text "x" <> int h <> text "mm"

    renderVideoMode (GLFW.VideoMode w h r g b rr) =
        brackets $ res <+> rgb <+> hz
      where
        res = int w <> text "x" <> int h
        rgb = int r <> text "x" <> int g <> text "x" <> int b
        hz  = int rr <> text "Hz"

    renderJoystickNames pairs =
        vcat $ map (\(js, name) -> text (show js) <+> text (show name)) pairs

    renderContextVersion v0 v1 v2 =
        hcat [int v0, text ".", int v1, text ".", int v2]

    renderClientAPI         = text . show
    renderContextRobustness = text . show
    renderForwardCompat     = text . show
    renderDebug             = text . show
    renderProfile           = text . show
dumpStateGLFW :: IORef GLFWState -> IO ()
dumpStateGLFW ref = do
  maybeWin <- ref ^@ glfwWindow
  case maybeWin of
    Nothing      -> return ()
    Just glfwWin -> do
      version       <- GLFW.getVersion
      versionString <- GLFW.getVersionString
      monitorInfos  <- runMaybeT getMonitorInfos
      joystickNames <- getJoystickNames
      clientAPI     <- GLFW.getWindowClientAPI              glfwWin
      cv0           <- GLFW.getWindowContextVersionMajor    glfwWin
      cv1           <- GLFW.getWindowContextVersionMinor    glfwWin
      cv2           <- GLFW.getWindowContextVersionRevision glfwWin
      robustness    <- GLFW.getWindowContextRobustness      glfwWin
      forwardCompat <- GLFW.getWindowOpenGLForwardCompat    glfwWin
      debug         <- GLFW.getWindowOpenGLDebugContext     glfwWin
      profile       <- GLFW.getWindowOpenGLProfile          glfwWin

      putStrLn $ render $
        nest 4 (
          text "------------------------------------------------------------" $+$
          text "GLFW C library:" $+$
          nest 4 (
            text "Version:"        <+> renderVersion version $+$
            text "Version string:" <+> renderVersionString versionString
          ) $+$
          text "Monitors:" $+$
          nest 4 (
            renderMonitorInfos monitorInfos
          ) $+$
          text "Joysticks:" $+$
          nest 4 (
            renderJoystickNames joystickNames
          ) $+$
          text "OpenGL context:" $+$
          nest 4 (
            text "Client API:"            <+> renderClientAPI clientAPI $+$
            text "Version:"               <+> renderContextVersion cv0 cv1 cv2 $+$
            text "Robustness:"            <+> renderContextRobustness robustness $+$
            text "Forward compatibility:" <+> renderForwardCompat forwardCompat $+$
            text "Debug:"                 <+> renderDebug debug $+$
            text "Profile:"               <+> renderProfile profile
          ) $+$
          text "------------------------------------------------------------"
        )
  where
    renderVersion (GLFW.Version v0 v1 v2) =
        text $ intercalate "." $ map show [v0, v1, v2]

    renderVersionString =
        text . show

    renderMonitorInfos =
        maybe (text "(error)") (vcat . map renderMonitorInfo)

    renderMonitorInfo (name, (x,y), (w,h), vms) =
        text (show name) $+$
        nest 4 (
          location <+> size $+$
          fsep (map renderVideoMode vms)
        )
      where
        location = int x <> text "," <> int y
        size     = int w <> text "x" <> int h <> text "mm"

    renderVideoMode (GLFW.VideoMode w h r g b rr) =
        brackets $ res <+> rgb <+> hz
      where
        res = int w <> text "x" <> int h
        rgb = int r <> text "x" <> int g <> text "x" <> int b
        hz  = int rr <> text "Hz"

    renderJoystickNames pairs =
        vcat $ map (\(js, name) -> text (show js) <+> text (show name)) pairs

    renderContextVersion v0 v1 v2 =
        hcat [int v0, text ".", int v1, text ".", int v2]

    renderClientAPI         = text . show
    renderContextRobustness = text . show
    renderForwardCompat     = text . show
    renderDebug             = text . show
    renderProfile           = text . show
dumpStateGLFW ref = do
  maybeWin <- ref ^@ glfwWindow
  case maybeWin of
    Nothing      -> return ()
    Just glfwWin -> do
      version       <- GLFW.getVersion
      versionString <- GLFW.getVersionString
      monitorInfos  <- runMaybeT getMonitorInfos
      joystickNames <- getJoystickNames
      clientAPI     <- GLFW.getWindowClientAPI              glfwWin
      cv0           <- GLFW.getWindowContextVersionMajor    glfwWin
      cv1           <- GLFW.getWindowContextVersionMinor    glfwWin
      cv2           <- GLFW.getWindowContextVersionRevision glfwWin
      robustness    <- GLFW.getWindowContextRobustness      glfwWin
      forwardCompat <- GLFW.getWindowOpenGLForwardCompat    glfwWin
      debug         <- GLFW.getWindowOpenGLDebugContext     glfwWin
      profile       <- GLFW.getWindowOpenGLProfile          glfwWin

      putStrLn $ render $
        nest 4 (
          text "------------------------------------------------------------" $+$
          text "GLFW C library:" $+$
          nest 4 (
            text "Version:"        <+> renderVersion version $+$
            text "Version string:" <+> renderVersionString versionString
          ) $+$
          text "Monitors:" $+$
          nest 4 (
            renderMonitorInfos monitorInfos
          ) $+$
          text "Joysticks:" $+$
          nest 4 (
            renderJoystickNames joystickNames
          ) $+$
          text "OpenGL context:" $+$
          nest 4 (
            text "Client API:"            <+> renderClientAPI clientAPI $+$
            text "Version:"               <+> renderContextVersion cv0 cv1 cv2 $+$
            text "Robustness:"            <+> renderContextRobustness robustness $+$
            text "Forward compatibility:" <+> renderForwardCompat forwardCompat $+$
            text "Debug:"                 <+> renderDebug debug $+$
            text "Profile:"               <+> renderProfile profile
          ) $+$
          text "------------------------------------------------------------"
        )
  where
    renderVersion (GLFW.Version v0 v1 v2) =
        text $ intercalate "." $ map show [v0, v1, v2]

    renderVersionString =
        text . show

    renderMonitorInfos =
        maybe (text "(error)") (vcat . map renderMonitorInfo)

    renderMonitorInfo (name, (x,y), (w,h), vms) =
        text (show name) $+$
        nest 4 (
          location <+> size $+$
          fsep (map renderVideoMode vms)
        )
      where
        location = int x <> text "," <> int y
        size     = int w <> text "x" <> int h <> text "mm"

    renderVideoMode (GLFW.VideoMode w h r g b rr) =
        brackets $ res <+> rgb <+> hz
      where
        res = int w <> text "x" <> int h
        rgb = int r <> text "x" <> int g <> text "x" <> int b
        hz  = int rr <> text "Hz"

    renderJoystickNames pairs =
        vcat $ map (\(js, name) -> text (show js) <+> text (show name)) pairs

    renderContextVersion v0 v1 v2 =
        hcat [int v0, text ".", int v1, text ".", int v2]

    renderClientAPI         = text . show
    renderContextRobustness = text . show
    renderForwardCompat     = text . show
    renderDebug             = text . show
    renderProfile           = text . show