    {-# LANGUAGE FlexibleInstances, MultiParamTypeClasses, TypeSynonymInstances #-}

    -----------------------------------------------------------------------------
    -- |
    -- Module      :  XMonad.Layout.Accordion
    -- Copyright   :  (c) glasser@mit.edu
    -- License     :  BSD
    --
    -- Maintainer  :  glasser@mit.edu
    -- Stability   :  stable
    -- Portability :  unportable
    --
    -- LayoutClass that puts non-focused windows in ribbons at the top and bottom
    -- of the screen.
    -----------------------------------------------------------------------------

    module XMonad.Layout.Accordion (
        -- * Usage
        -- $usage
        Accordion(Accordion)) where

    import XMonad
    import qualified XMonad.StackSet as W
    import Data.Ratio

    -- $usage
    -- You can use this module with the following in your @~\/.xmonad\/xmonad.hs@:
    --
    -- > import XMonad.Layout.Accordion
    --
    -- Then edit your @layoutHook@ by adding the Accordion layout:
    --
    -- > myLayout = Accordion ||| Full ||| etc..
    -- > main = xmonad def { layoutHook = myLayout }
    --
    -- For more detailed instructions on editing the layoutHook see:
    --
    -- "XMonad.Doc.Extending#Editing_the_layout_hook"

    data Accordion a = Accordion deriving ( ReadPrec [Accordion a]
    ReadPrec (Accordion a)
    Int -> ReadS (Accordion a)
    ReadS [Accordion a]
    (Int -> ReadS (Accordion a))
    -> ReadS [Accordion a]
    -> ReadPrec (Accordion a)
    -> ReadPrec [Accordion a]
    -> Read (Accordion a)
    forall a. ReadPrec [Accordion a]
    forall a. ReadPrec (Accordion a)
    forall a. Int -> ReadS (Accordion a)
    forall a. ReadS [Accordion a]
    forall a.
    (Int -> ReadS a)
    -> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
    readListPrec :: ReadPrec [Accordion a]
    $creadListPrec :: forall a. ReadPrec [Accordion a]
    readPrec :: ReadPrec (Accordion a)
    $creadPrec :: forall a. ReadPrec (Accordion a)
    readList :: ReadS [Accordion a]
    $creadList :: forall a. ReadS [Accordion a]
    readsPrec :: Int -> ReadS (Accordion a)
    $creadsPrec :: forall a. Int -> ReadS (Accordion a)
    Read, Int -> Accordion a -> ShowS
    [Accordion a] -> ShowS
    Accordion a -> String
    (Int -> Accordion a -> ShowS)
    -> (Accordion a -> String)
    -> ([Accordion a] -> ShowS)
    -> Show (Accordion a)
    forall a. Int -> Accordion a -> ShowS
    forall a. [Accordion a] -> ShowS
    forall a. Accordion a -> String
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    showList :: [Accordion a] -> ShowS
    $cshowList :: forall a. [Accordion a] -> ShowS
    show :: Accordion a -> String
    $cshow :: forall a. Accordion a -> String
    showsPrec :: Int -> Accordion a -> ShowS
    $cshowsPrec :: forall a. Int -> Accordion a -> ShowS
    Show )

    instance LayoutClass Accordion Window where
        pureLayout :: Accordion Window
    -> Rectangle -> Stack Window -> [(Window, Rectangle)]
    pureLayout _ sc :: Rectangle
    sc ws :: Stack Window
    ws = [Window] -> [Rectangle] -> [(Window, Rectangle)]
    forall a b. [a] -> [b] -> [(a, b)]
    zip [Window]
    ups [Rectangle]
    tops [(Window, Rectangle)]
    -> [(Window, Rectangle)] -> [(Window, Rectangle)]
    forall a. [a] -> [a] -> [a]
    ++ [(Stack Window -> Window
    forall a. Stack a -> a
    W.focus Stack Window
    ws, Rectangle
    mainPane)] [(Window, Rectangle)]
    -> [(Window, Rectangle)] -> [(Window, Rectangle)]
    forall a. [a] -> [a] -> [a]
    ++ [Window] -> [Rectangle] -> [(Window, Rectangle)]
    forall a b. [a] -> [b] -> [(a, b)]
    zip [Window]
    dns [Rectangle]
    bottoms
         where
           ups :: [Window]
    ups    = [Window] -> [Window]
    forall a. [a] -> [a]
    reverse ([Window] -> [Window]) -> [Window] -> [Window]
    forall a b. (a -> b) -> a -> b
    $ Stack Window -> [Window]
    forall a. Stack a -> [a]
    W.up Stack Window
    ws
           dns :: [Window]
    dns    = Stack Window -> [Window]
    forall a. Stack a -> [a]
    W.down Stack Window
    ws
           (top :: Rectangle
    top,  allButTop :: Rectangle
    allButTop) = Ratio Int -> Rectangle -> (Rectangle, Rectangle)
    forall r. RealFrac r => r -> Rectangle -> (Rectangle, Rectangle)
    splitVerticallyBy (1Int -> Int -> Ratio Int
    forall a. Integral a => a -> a -> Ratio a
    %8 :: Ratio Int) Rectangle
    sc
           (center :: Rectangle
    center,  bottom :: Rectangle
    bottom) = Ratio Int -> Rectangle -> (Rectangle, Rectangle)
    forall r. RealFrac r => r -> Rectangle -> (Rectangle, Rectangle)
    splitVerticallyBy (6Int -> Int -> Ratio Int
    forall a. Integral a => a -> a -> Ratio a
    %7 :: Ratio Int) Rectangle
    allButTop
           (allButBottom :: Rectangle
    allButBottom, _) = Ratio Int -> Rectangle -> (Rectangle, Rectangle)
    forall r. RealFrac r => r -> Rectangle -> (Rectangle, Rectangle)
    splitVerticallyBy (7Int -> Int -> Ratio Int
    forall a. Integral a => a -> a -> Ratio a
    %8 :: Ratio Int) Rectangle
    sc
           mainPane :: Rectangle
    mainPane | [Window]
    ups [Window] -> [Window] -> Bool
    forall a. Eq a => a -> a -> Bool
    /= [] Bool -> Bool -> Bool
    && [Window]
    dns [Window] -> [Window] -> Bool
    forall a. Eq a => a -> a -> Bool
    /= [] = Rectangle
    center
                    | [Window]
    ups [Window] -> [Window] -> Bool
    forall a. Eq a => a -> a -> Bool
    /= []              = Rectangle
    allButTop
                    | [Window]
    dns [Window] -> [Window] -> Bool
    forall a. Eq a => a -> a -> Bool
    /= []              = Rectangle
    allButBottom
                    | Bool
    otherwise              = Rectangle
    sc
           tops :: [Rectangle]
    tops    = if [Window]
    ups [Window] -> [Window] -> Bool
    forall a. Eq a => a -> a -> Bool
    /= [] then Int -> Rectangle -> [Rectangle]
    splitVertically ([Window] -> Int
    forall (t :: * -> *) a. Foldable t => t a -> Int
    length [Window]
    ups) Rectangle
    top    else []
           bottoms :: [Rectangle]
    bottoms = if [Window]
    dns [Window] -> [Window] -> Bool
    forall a. Eq a => a -> a -> Bool
    /= [] then Int -> Rectangle -> [Rectangle]
    splitVertically ([Window] -> Int
    forall (t :: * -> *) a. Foldable t => t a -> Int
    length [Window]
    dns) Rectangle
    bottom else []