content: {-# LANGUAGE PatternGuards #-}
  {-# OPTIONS_GHC -fno-warn-missing-signatures -fno-warn-orphans #-}
  -----------------------------------------------------------------------------
  -- |
  -- Copyright   :  (c) Spencer Janssen 2007
  -- License     :  BSD3-style (see LICENSE)
  --
  ------------------------------------------------------------------------
  
  module XMonad.Config.Droundy ( config, mytab ) where
  
  import XMonad hiding (keys, config, (|||))
  import qualified XMonad (keys)
  
  import qualified XMonad.StackSet as W
  import qualified Data.Map as M
  import System.Exit ( exitWith, ExitCode(ExitSuccess) )
  
  import XMonad.Layout.Tabbed ( tabbed,
                                shrinkText, Shrinker, shrinkIt, CustomShrink(CustomShrink) )
  import XMonad.Layout.Combo ( combineTwo )
  import XMonad.Layout.Named ( named )
  import XMonad.Layout.LayoutCombinators
  import XMonad.Layout.Square ( Square(Square) )
  import XMonad.Layout.WindowNavigation ( Navigate(Move,Swap,Go), Direction2D(U,D,R,L),
                                          windowNavigation )
  import XMonad.Layout.BoringWindows ( boringWindows, markBoring, clearBoring,
                                       focusUp, focusDown )
  import XMonad.Layout.NoBorders ( smartBorders )
  import XMonad.Layout.WorkspaceDir ( changeDir, workspaceDir )
  import XMonad.Layout.ToggleLayouts ( toggleLayouts, ToggleLayout(ToggleLayout) )
  import XMonad.Layout.ShowWName ( showWName )
  import XMonad.Layout.Magnifier ( maximizeVertical, MagnifyMsg(Toggle) )
  
  import XMonad.Prompt ( font, height, XPConfig )
  import XMonad.Prompt.Layout ( layoutPrompt )
  import XMonad.Prompt.Shell ( shellPrompt )
  
  import XMonad.Actions.CopyWindow ( kill1, copy )
  import XMonad.Actions.DynamicWorkspaces ( withNthWorkspace, withWorkspace,
                                            selectWorkspace, renameWorkspace, removeWorkspace )
  import XMonad.Actions.CycleWS ( moveTo, WSType( HiddenNonEmptyWS ),
                                  Direction1D( Prev, Next) )
  
  import XMonad.Hooks.ManageDocks ( avoidStruts, manageDocks )
  import XMonad.Hooks.EwmhDesktops ( ewmh )
  
  myXPConfig :: XPConfig
  myXPConfig = def {font="-*-lucida-medium-r-*-*-14-*-*-*-*-*-*-*"
                   ,height=22}
  
  
  ------------------------------------------------------------------------
  -- Key bindings:
  
  -- | The xmonad key bindings. Add, modify or remove key bindings here.
  --
  -- (The comment formatting character is used when generating the manpage)
  --
  keys :: XConfig Layout -> M.Map (KeyMask, KeySym) (X ())
  keys x = M.fromList $
      -- launching and killing programs
      [ ((modMask x .|. shiftMask, xK_c     ), kill1) -- %! Close the focused window
  
      , ((modMask x .|. shiftMask, xK_space ), sendMessage NextLayout) -- %! Rotate through the available layout algorithms
      , ((modMask x .|. controlMask .|. shiftMask, xK_L ), setLayout $ layoutHook x) -- %!  Reset the layouts on the current workspace to default
  
      -- move focus up or down the window stack
      , ((modMask x,               xK_Tab   ), focusDown) -- %! Move focus to the next window
      , ((modMask x,               xK_j     ), focusDown) -- %! Move focus to the next window
      , ((modMask x,               xK_k     ), focusUp  ) -- %! Move focus to the previous window
  
      , ((modMask x .|. shiftMask, xK_j     ), windows W.swapDown  ) -- %! Swap the focused window with the next window
      , ((modMask x .|. shiftMask, xK_k     ), windows W.swapUp    ) -- %! Swap the focused window with the previous window
  
      -- floating layer support
      , ((modMask x,               xK_t     ), withFocused $ windows . W.sink) -- %! Push window back into tiling
  
      -- quit, or restart
      , ((modMask x .|. shiftMask, xK_Escape), io (exitWith ExitSuccess)) -- %! Quit xmonad
      , ((modMask x              , xK_Escape), restart "xmonad" True) -- %! Restart xmonad
  
      , ((modMask x .|. shiftMask, xK_Right), moveTo Next HiddenNonEmptyWS)
      , ((modMask x .|. shiftMask, xK_Left), moveTo Prev HiddenNonEmptyWS)
      , ((modMask x, xK_Right), sendMessage $ Go R)
      , ((modMask x, xK_Left), sendMessage $ Go L)
      , ((modMask x, xK_Up), sendMessage $ Go U)
      , ((modMask x, xK_Down), sendMessage $ Go D)
      , ((modMask x .|. controlMask, xK_Right), sendMessage $ Swap R)
      , ((modMask x .|. controlMask, xK_Left), sendMessage $ Swap L)
      , ((modMask x .|. controlMask, xK_Up), sendMessage $ Swap U)
      , ((modMask x .|. controlMask, xK_Down), sendMessage $ Swap D)
      , ((modMask x .|. controlMask .|. shiftMask, xK_Right), sendMessage $ Move R)
      , ((modMask x .|. controlMask .|. shiftMask, xK_Left), sendMessage $ Move L)
      , ((modMask x .|. controlMask .|. shiftMask, xK_Up), sendMessage $ Move U)
      , ((modMask x .|. controlMask .|. shiftMask, xK_Down), sendMessage $ Move D)
  
      , ((0, xK_F2  ), spawn "gnome-terminal") -- %! Launch gnome-terminal
      , ((0, xK_F3  ), shellPrompt myXPConfig) -- %! Launch program
      , ((0, xK_F11   ), spawn "ksnapshot") -- %! Take snapshot
      , ((modMask x .|. shiftMask, xK_b     ), markBoring)
      , ((controlMask .|. modMask x .|. shiftMask, xK_b     ), clearBoring)
      , ((modMask x .|. shiftMask, xK_x     ), changeDir myXPConfig)
      , ((modMask x .|. shiftMask, xK_BackSpace), removeWorkspace)
      , ((modMask x .|. shiftMask, xK_v     ), selectWorkspace myXPConfig)
      , ((modMask x, xK_m     ), withWorkspace myXPConfig (windows . W.shift))
      , ((modMask x .|. shiftMask, xK_m     ), withWorkspace myXPConfig (windows . copy))
      , ((modMask x .|. shiftMask, xK_r), renameWorkspace myXPConfig)
      , ((modMask x, xK_l ), layoutPrompt myXPConfig)
      , ((modMask x .|. controlMask, xK_space), sendMessage ToggleLayout)
      , ((modMask x, xK_space), sendMessage Toggle)
  
      ]
  
      ++
      zip (zip (repeat $ modMask x) [xK_F1..xK_F12]) (map (withNthWorkspace W.greedyView) [0..])
      ++
      zip (zip (repeat (modMask x .|. shiftMask)) [xK_F1..xK_F12]) (map (withNthWorkspace copy) [0..])
  
  config = ewmh def
           { borderWidth = 1 -- Width of the window border in pixels.
           , XMonad.workspaces = ["mutt","iceweasel"]
           , layoutHook = showWName $ workspaceDir "~" $
                          boringWindows $ smartBorders $ windowNavigation $
                          maximizeVertical $ toggleLayouts Full $ avoidStruts $
                          named "tabbed" mytab |||
                          named "xclock" (mytab ****//* combineTwo Square mytab mytab) |||
                          named "three" (mytab **//* mytab *//* combineTwo Square mytab mytab) |||
                          named "widescreen" ((mytab *||* mytab)
                                                  ****//* combineTwo Square mytab mytab) --   |||
                          --mosaic 0.25 0.5
           , manageHook = manageHook def <+> manageDocks -- add panel-handling
           , terminal = "xterm" -- The preferred terminal program.
           , normalBorderColor = "#222222" -- Border color for unfocused windows.
           , focusedBorderColor = "#00ff00" -- Border color for focused windows.
           , XMonad.modMask = mod1Mask
           , XMonad.keys = keys
           }
  
  mytab = tabbed CustomShrink def
  
  instance Shrinker CustomShrink where
      shrinkIt shr s | Just s' <- dropFromHead " " s = shrinkIt shr s'
      shrinkIt shr s | Just s' <- dropFromTail " " s = shrinkIt shr s'
      shrinkIt shr s | Just s' <- dropFromTail "- Iceweasel" s = shrinkIt shr s'
      shrinkIt shr s | Just s' <- dropFromTail "- KPDF" s = shrinkIt shr s'
      shrinkIt shr s | Just s' <- dropFromHead "file://" s = shrinkIt shr s'
      shrinkIt shr s | Just s' <- dropFromHead "http://" s = shrinkIt shr s'
      shrinkIt _ s | n > 9 = s : map cut [2..(halfn-3)] ++ shrinkIt shrinkText s
                   where n = length s
                         halfn = n `div` 2
                         rs = reverse s
                         cut x = take (halfn - x) s ++ "..." ++ reverse (take (halfn-x) rs)
      shrinkIt _ s = shrinkIt shrinkText s
  
  dropFromTail :: String -> String -> Maybe String
  dropFromTail "" _ = Nothing
  dropFromTail t s | drop (length s - length t) s == t = Just $ take (length s - length t) s
                   | otherwise = Nothing
  
  dropFromHead :: String -> String -> Maybe String
  dropFromHead "" _ = Nothing
  dropFromHead h s | take (length h) s == h = Just $ drop (length h) s
                   | otherwise = Nothing
  
  {-
  data FocusUrgencyHook = FocusUrgencyHook deriving (Read, Show)
  
  instance UrgencyHook FocusUrgencyHook Window where
      urgencyHook _ w = modify copyAndFocus
          where copyAndFocus s
                    | Just w == W.peek (windowset s) = s
                    | has w $ W.stack $ W.workspace $ W.current $ windowset s =
                        s { windowset = until ((Just w ==) . W.peek)
                                        W.focusUp $ windowset s }
                    | otherwise =
                        let t = W.currentTag $ windowset s
                        in s { windowset = until ((Just w ==) . W.peek)
                               W.focusUp $ copyWindow w t $ windowset s }
                has _ Nothing         = False
                has x (Just (W.Stack t l rr)) = x `elem` (t : l ++ rr)
  
  -}
  