content: {-# LANGUAGE FlexibleInstances, MultiParamTypeClasses #-}
  
  -----------------------------------------------------------------------------
  -- |
  -- Module      :  XMonad.Layout.PerScreen
  -- Copyright   :  (c) Edward Z. Yang
  -- License     :  BSD-style (see LICENSE)
  --
  -- Maintainer  :  <ezyang@cs.stanford.edu>
  -- Stability   :  unstable
  -- Portability :  unportable
  --
  -- Configure layouts based on the width of your screen; use your
  -- favorite multi-column layout for wide screens and a full-screen
  -- layout for small ones.
  -----------------------------------------------------------------------------
  
  module XMonad.Layout.PerScreen
      ( -- * Usage
        -- $usage
        PerScreen,
        ifWider
      ) where
  
  import XMonad
  import qualified XMonad.StackSet as W
  
  import Data.Maybe (fromMaybe)
  
  -- $usage
  -- You can use this module by importing it into your ~\/.xmonad\/xmonad.hs file:
  --
  -- > import XMonad.Layout.PerScreen
  --
  -- and modifying your layoutHook as follows (for example):
  --
  -- > layoutHook = ifWider 1280 (Tall 1 (3/100) (1/2) ||| Full) Full
  --
  -- Replace any of the layouts with any arbitrarily complicated layout.
  -- ifWider can also be used inside other layout combinators.
  
  ifWider :: (LayoutClass l1 a, LayoutClass l2 a)
                 => Dimension   -- ^ target screen width
                 -> (l1 a)      -- ^ layout to use when the screen is wide enough
                 -> (l2 a)      -- ^ layout to use otherwise
                 -> PerScreen l1 l2 a
  ifWider w = PerScreen w False
  
  data PerScreen l1 l2 a = PerScreen Dimension Bool (l1 a) (l2 a) deriving (Read, Show)
  
  -- | Construct new PerScreen values with possibly modified layouts.
  mkNewPerScreenT :: PerScreen l1 l2 a -> Maybe (l1 a) ->
                        PerScreen l1 l2 a
  mkNewPerScreenT (PerScreen w _ lt lf) mlt' =
      (\lt' -> PerScreen w True lt' lf) $ fromMaybe lt mlt'
  
  mkNewPerScreenF :: PerScreen l1 l2 a -> Maybe (l2 a) ->
                        PerScreen l1 l2 a
  mkNewPerScreenF (PerScreen w _ lt lf) mlf' =
      (\lf' -> PerScreen w False lt lf') $ fromMaybe lf mlf'
  
  instance (LayoutClass l1 a, LayoutClass l2 a, Show a) => LayoutClass (PerScreen l1 l2) a where
      runLayout (W.Workspace i p@(PerScreen w _ lt lf) ms) r
          | rect_width r > w    = do (wrs, mlt') <- runLayout (W.Workspace i lt ms) r
                                     return (wrs, Just $ mkNewPerScreenT p mlt')
          | otherwise           = do (wrs, mlt') <- runLayout (W.Workspace i lf ms) r
                                     return (wrs, Just $ mkNewPerScreenF p mlt')
  
      handleMessage (PerScreen w bool lt lf) m
          | bool      = handleMessage lt m >>= maybe (return Nothing) (\nt -> return . Just $ PerScreen w bool nt lf)
          | otherwise = handleMessage lf m >>= maybe (return Nothing) (\nf -> return . Just $ PerScreen w bool lt nf)
  
      description (PerScreen _ True  l1 _) = description l1
      description (PerScreen _ _     _ l2) = description l2
  