{-# OPTIONS_GHC -fglasgow-exts #-} -- For deriving Data/Typeable
----------------------------------------------------------------------------
-- |
-- Module      :  XMonad.Layout.Minimize
-- Copyright   :  (c) Jan Vornberger 2009
-- License     :  BSD3-style (see LICENSE)
--
-- Maintainer  :  jan.vornberger@informatik.uni-oldenburg.de
-- Stability   :  unstable
-- Portability :  not portable
--
-----------------------------------------------------------------------------

module XMonad.Layout.Minimize (
        minimize,
        MinimizeMsg(..)
    ) where

import XMonad
import qualified XMonad.StackSet as W
import XMonad.Layout.LayoutModifier
import XMonad.Layout.BoringWindows as BW
import Data.List

data Minimize a = Minimize [Window] deriving ( Read, Show )
minimize :: LayoutClass l Window => l Window -> ModifiedLayout Minimize l Window
minimize = ModifiedLayout $ Minimize []

data MinimizeMsg = MinimizeWin Window
                    | RestoreMinimizedWin Window
                    | RestoreNextMinimizedWin
                    deriving (Typeable, Eq)
instance Message MinimizeMsg

instance LayoutModifier Minimize Window where
    modifierDescription (Minimize _) = "Minimize"

    modifyLayout (Minimize minimized) wksp rect = do
        let stack = W.stack wksp
            filtStack = stack >>=W.filter (\w -> not (w `elem` minimized))
        runLayout (wksp {W.stack = filtStack}) rect

    handleMess (Minimize minimized) m = case fromMessage m of
        Just (MinimizeWin w)
          | not (w `elem` minimized) -> do
                BW.focusDown
                return $ Just $ Minimize (w:minimized)
          | otherwise               -> return Nothing
        Just (RestoreMinimizedWin w) ->
            return $ Just $ Minimize (minimized \\ [w])
        Just (RestoreNextMinimizedWin)
          | not (null minimized)    -> do
                focus (head minimized)
                return $ Just $ Minimize (tail minimized)
          | otherwise               -> return Nothing
        _ -> return Nothing