-- | Dump the state of the current 'StackSet' as a multiline 'String'.
--   @
--   stack [    mm
--         ,(*) ww
--         ,    ww
--         ]
--   float {    ww
--         ,    ww
--         }
--   @
--
-- One thing I'm not sure of is where the zipper is when focus is on a
-- floating window.
debugStackString :: X String
debugStackString =  withWindowSet $ \ws -> do
                      s <- emit "stack" ("[","]") (W.peek ws)                    $ W.index    ws
                      f <- emit "float" ("{","}") (W.peek ws) $ map fst $ toList $ W.floating ws
                      return $ s ++ f
  where
    emit :: String -> (String,String) -> Maybe Window -> [Window] -> X String
    emit title (lb,rb) _       [] = return $ title ++ " " ++ lb ++ rb ++ "]\n"
    emit title (lb,rb) focused ws = do
      (_,_,_,_,ss) <- foldM emit' (title,lb,rb,focused,"") ws
      return $ ss                               ++
               replicate (length title + 1) ' ' ++
               rb                               ++
               "\n"

    emit' :: (String,String,String,Maybe Window,String)
          -> Window
          -> X (String,String,String,Maybe Window,String)
    emit' (t,l,r,f,a) w = do
      w' <- emit'' f w
      return (replicate (length t) ' '
             ,',' : replicate (length l - 1) ' '
             ,r
             ,f
             ,a ++ t ++ " " ++ l ++ w' ++ "\n"
             )
    emit'' :: Maybe Window -> Window -> X String
    emit'' focus win =
      let fi f = if win == f then "(*) " else "    "
       in (maybe "    " fi focus ++) `fmap` debugWindow win
debugStackString :: X String
debugStackString =  withWindowSet $ \ws -> do
                      s <- emit "stack" ("[","]") (W.peek ws)                    $ W.index    ws
                      f <- emit "float" ("{","}") (W.peek ws) $ map fst $ toList $ W.floating ws
                      return $ s ++ f
  where
    emit :: String -> (String,String) -> Maybe Window -> [Window] -> X String
    emit title (lb,rb) _       [] = return $ title ++ " " ++ lb ++ rb ++ "]\n"
    emit title (lb,rb) focused ws = do
      (_,_,_,_,ss) <- foldM emit' (title,lb,rb,focused,"") ws
      return $ ss                               ++
               replicate (length title + 1) ' ' ++
               rb                               ++
               "\n"

    emit' :: (String,String,String,Maybe Window,String)
          -> Window
          -> X (String,String,String,Maybe Window,String)
    emit' (t,l,r,f,a) w = do
      w' <- emit'' f w
      return (replicate (length t) ' '
             ,',' : replicate (length l - 1) ' '
             ,r
             ,f
             ,a ++ t ++ " " ++ l ++ w' ++ "\n"
             )
    emit'' :: Maybe Window -> Window -> X String
    emit'' focus win =
      let fi f = if win == f then "(*) " else "    "
       in (maybe "    " fi focus ++) `fmap` debugWindow win
debugStackString =  withWindowSet $ \ws -> do
                      s <- emit "stack" ("[","]") (W.peek ws)                    $ W.index    ws
                      f <- emit "float" ("{","}") (W.peek ws) $ map fst $ toList $ W.floating ws
                      return $ s ++ f
  where
    emit :: String -> (String,String) -> Maybe Window -> [Window] -> X String
    emit title (lb,rb) _       [] = return $ title ++ " " ++ lb ++ rb ++ "]\n"
    emit title (lb,rb) focused ws = do
      (_,_,_,_,ss) <- foldM emit' (title,lb,rb,focused,"") ws
      return $ ss                               ++
               replicate (length title + 1) ' ' ++
               rb                               ++
               "\n"

    emit' :: (String,String,String,Maybe Window,String)
          -> Window
          -> X (String,String,String,Maybe Window,String)
    emit' (t,l,r,f,a) w = do
      w' <- emit'' f w
      return (replicate (length t) ' '
             ,',' : replicate (length l - 1) ' '
             ,r
             ,f
             ,a ++ t ++ " " ++ l ++ w' ++ "\n"
             )
    emit'' :: Maybe Window -> Window -> X String
    emit'' focus win =
      let fi f = if win == f then "(*) " else "    "
       in (maybe "    " fi focus ++) `fmap` debugWindow win