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

    -----------------------------------------------------------------------------
    -- |
    -- Module      :  XMonad.Layout.Roledex
    -- Copyright   :  (c) tim.thelion@gmail.com
    -- License     :  BSD
    --
    -- Maintainer  :  tim.thelion@gmail.com
    -- Stability   :  unstable
    -- Portability :  unportable
    --
    -- This is a completely pointless layout which acts like Microsoft's Flip 3D
    -----------------------------------------------------------------------------

    module XMonad.Layout.Roledex (
        -- * Usage
        -- $usage

        -- * Screenshots
        -- $screenshot
        Roledex(Roledex)) 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.Roledex
    --
    -- Then edit your @layoutHook@ by adding the Roledex layout:
    --
    -- > myLayout =  Roledex ||| etc..
    -- > main = xmonad def { layoutHook = myLayout }
    --
    -- For more detailed instructions on editing the layoutHook see:
    --
    -- "XMonad.Doc.Extending#Editing_the_layout_hook"

    -- $screenshot
    -- <<http://www.timthelion.com/rolodex.png>>

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

    instance LayoutClass Roledex Window where
        doLayout :: Roledex Window
    -> Rectangle
    -> Stack Window
    -> X ([(Window, Rectangle)], Maybe (Roledex Window))
    doLayout _ = Rectangle
    -> Stack Window
    -> X ([(Window, Rectangle)], Maybe (Roledex Window))
    forall a.
    Eq a =>
    Rectangle -> Stack a -> X ([(a, Rectangle)], Maybe (Roledex a))
    roledexLayout

    roledexLayout :: Eq a => Rectangle -> W.Stack a -> X ([(a, Rectangle)], Maybe (Roledex a))
    roledexLayout :: Rectangle -> Stack a -> X ([(a, Rectangle)], Maybe (Roledex a))
    roledexLayout sc :: Rectangle
    sc ws :: Stack a
    ws = ([(a, Rectangle)], Maybe (Roledex a))
    -> X ([(a, Rectangle)], Maybe (Roledex a))
    forall (m :: * -> *) a. Monad m => a -> m a
    return ([(Stack a -> a
    forall a. Stack a -> a
    W.focus Stack a
    ws, Rectangle
    mainPane)] [(a, Rectangle)] -> [(a, Rectangle)] -> [(a, Rectangle)]
    forall a. [a] -> [a] -> [a]
    ++
                                  ([a] -> [Rectangle] -> [(a, Rectangle)]
    forall a b. [a] -> [b] -> [(a, b)]
    zip [a]
    ups [Rectangle]
    tops) [(a, Rectangle)] -> [(a, Rectangle)] -> [(a, Rectangle)]
    forall a. [a] -> [a] -> [a]
    ++
                                  ([(a, Rectangle)] -> [(a, Rectangle)]
    forall a. [a] -> [a]
    reverse ([a] -> [Rectangle] -> [(a, Rectangle)]
    forall a b. [a] -> [b] -> [(a, b)]
    zip [a]
    dns [Rectangle]
    bottoms))
                                   ,Maybe (Roledex a)
    forall a. Maybe a
    Nothing)
     where ups :: [a]
    ups    = Stack a -> [a]
    forall a. Stack a -> [a]
    W.up Stack a
    ws
           dns :: [a]
    dns    = Stack a -> [a]
    forall a. Stack a -> [a]
    W.down Stack a
    ws
           c :: Int
    c = [a] -> Int
    forall (t :: * -> *) a. Foldable t => t a -> Int
    length [a]
    ups Int -> Int -> Int
    forall a. Num a => a -> a -> a
    + [a] -> Int
    forall (t :: * -> *) a. Foldable t => t a -> Int
    length [a]
    dns
           rect :: Rectangle
    rect = (Rectangle, Rectangle) -> Rectangle
    forall a b. (a, b) -> a
    fst ((Rectangle, Rectangle) -> Rectangle)
    -> (Rectangle, Rectangle) -> Rectangle
    forall a b. (a -> b) -> a -> b
    $ Ratio Int -> Rectangle -> (Rectangle, Rectangle)
    forall r. RealFrac r => r -> Rectangle -> (Rectangle, Rectangle)
    splitHorizontallyBy (2Int -> Int -> Ratio Int
    forall a. Integral a => a -> a -> Ratio a
    %3 :: Ratio Int) (Rectangle -> (Rectangle, Rectangle))
    -> Rectangle -> (Rectangle, Rectangle)
    forall a b. (a -> b) -> a -> b
    $ (Rectangle, Rectangle) -> Rectangle
    forall a b. (a, b) -> a
    fst (Ratio Int -> Rectangle -> (Rectangle, Rectangle)
    forall r. RealFrac r => r -> Rectangle -> (Rectangle, Rectangle)
    splitVerticallyBy (2Int -> Int -> Ratio Int
    forall a. Integral a => a -> a -> Ratio a
    %3 :: Ratio Int) Rectangle
    sc)
           gw :: Dimension
    gw = Dimension -> Dimension -> Dimension
    forall a. Integral a => a -> a -> a
    div' (Dimension
    w Dimension -> Dimension -> Dimension
    forall a. Num a => a -> a -> a
    - Dimension
    rw) (Int -> Dimension
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Int
    c)
                where
                (Rectangle _ _ w :: Dimension
    w _) = Rectangle
    sc
                (Rectangle _ _ rw :: Dimension
    rw _) = Rectangle
    rect
           gh :: Dimension
    gh = Dimension -> Dimension -> Dimension
    forall a. Integral a => a -> a -> a
    div' (Dimension
    h Dimension -> Dimension -> Dimension
    forall a. Num a => a -> a -> a
    - Dimension
    rh) (Int -> Dimension
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Int
    c)
                where
                (Rectangle _ _ _ h :: Dimension
    h) = Rectangle
    sc
                (Rectangle _ _ _ rh :: Dimension
    rh) = Rectangle
    rect
           mainPane :: Rectangle
    mainPane = Dimension -> Dimension -> Rectangle -> Rectangle
    forall a a.
    (Integral a, Integral a) =>
    a -> a -> Rectangle -> Rectangle
    mrect (Dimension
    gw Dimension -> Dimension -> Dimension
    forall a. Num a => a -> a -> a
    * Int -> Dimension
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Int
    c) (Dimension
    gh Dimension -> Dimension -> Dimension
    forall a. Num a => a -> a -> a
    * Int -> Dimension
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Int
    c) Rectangle
    rect
           mrect :: a -> a -> Rectangle -> Rectangle
    mrect  mx :: a
    mx my :: a
    my (Rectangle x :: Position
    x y :: Position
    y w :: Dimension
    w h :: Dimension
    h) = Position -> Position -> Dimension -> Dimension -> Rectangle
    Rectangle (Position
    x Position -> Position -> Position
    forall a. Num a => a -> a -> a
    + (a -> Position
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral a
    mx)) (Position
    y Position -> Position -> Position
    forall a. Num a => a -> a -> a
    + (a -> Position
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral a
    my)) Dimension
    w Dimension
    h
           tops :: [Rectangle]
    tops    = (Int -> Rectangle) -> [Int] -> [Rectangle]
    forall a b. (a -> b) -> [a] -> [b]
    map Int -> Rectangle
    forall a. Integral a => a -> Rectangle
    f ([Int] -> [Rectangle]) -> [Int] -> [Rectangle]
    forall a b. (a -> b) -> a -> b
    $ Int -> Int -> [Int]
    forall t. (Ord t, Num t) => t -> t -> [t]
    cd Int
    c ([a] -> Int
    forall (t :: * -> *) a. Foldable t => t a -> Int
    length [a]
    dns)
           bottoms :: [Rectangle]
    bottoms = (Int -> Rectangle) -> [Int] -> [Rectangle]
    forall a b. (a -> b) -> [a] -> [b]
    map Int -> Rectangle
    forall a. Integral a => a -> Rectangle
    f ([Int] -> [Rectangle]) -> [Int] -> [Rectangle]
    forall a b. (a -> b) -> a -> b
    $ [0..([a] -> Int
    forall (t :: * -> *) a. Foldable t => t a -> Int
    length [a]
    dns)]
           f :: a -> Rectangle
    f n :: a
    n = Dimension -> Dimension -> Rectangle -> Rectangle
    forall a a.
    (Integral a, Integral a) =>
    a -> a -> Rectangle -> Rectangle
    mrect (Dimension
    gw Dimension -> Dimension -> Dimension
    forall a. Num a => a -> a -> a
    * (a -> Dimension
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral a
    n)) (Dimension
    gh Dimension -> Dimension -> Dimension
    forall a. Num a => a -> a -> a
    * (a -> Dimension
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral a
    n)) Rectangle
    rect
           cd :: t -> t -> [t]
    cd n :: t
    n m :: t
    m = if t
    n t -> t -> Bool
    forall a. Ord a => a -> a -> Bool
    > t
    m
                    then (t
    n t -> t -> t
    forall a. Num a => a -> a -> a
    - 1) t -> [t] -> [t]
    forall a. a -> [a] -> [a]
    : (t -> t -> [t]
    cd (t
    nt -> t -> t
    forall a. Num a => a -> a -> a
    -1) t
    m)
                    else []

    div' :: Integral a => a -> a -> a
    div' :: a -> a -> a
    div' _ 0 = 0
    div' n :: a
    n o :: a
    o = a -> a -> a
    forall a. Integral a => a -> a -> a
    div a
    n a
    o