------------------------------------------------------------------------------
-- |
-- Module      :  Obsolete
-- Copyright   :  (c) Mads N Noe 2009
-- Maintainer  :  mntnoe (@) gmail.com
-- License     :  as-is
--
-- Functions not used anymore, but might be useful later.
--
------------------------------------------------------------------------------

module Obsolete (
    ) where

-- Haskell modules
import Data.Char (toLower, toUpper)
import qualified Data.Map as M

-- XMonad modules
import XMonad
import XMonad.Prompt
import qualified XMonad.StackSet as W
import XMonad.Util.NamedWindows (getName)
import XMonad.Util.Run (runProcessWithInput)

-- My modules
import DMenu (dmenuArgs)

-- DMENU FUNCTIONS

-- | Spawn dmenu with the given prompt and completion list.  Return what the
--   user typed (which might not be an item in the list).
dmenu :: XPConfig -> String -> [String] -> X String
dmenu xpc prompt opts = io $ runProcessWithInput "dmenu" (dmenuArgs xpc prompt) (unlines opts)

-- | Like 'dzen', but look up the return value in a map.
dmenuMap :: XPConfig -> String -> M.Map String a -> X (Maybe a)
dmenuMap xpc prompt selectionMap = do
  selection <- (dmenu xpc prompt) (M.keys selectionMap)
  return $ M.lookup selection selectionMap

-- | Prompt for a window and focus it.
gotoMenu :: XPConfig -> X ()
gotoMenu xpc = actionMenu xpc "Window:" W.focusWindow

-- | Prompt for a window and perform an 'WindowSet' operation on it.
actionMenu :: XPConfig -> String -> (Window -> WindowSet -> WindowSet) -> X()
actionMenu xpc prompt action = windowMap >>= (dmenuMap xpc prompt) >>= flip whenJust (windows . action)

-- | Map from a formatted name to the corresponding 'Window' for use in a prompt.
windowMap :: X (M.Map String Window)
windowMap = do
  ws <- gets windowset
  M.fromList `fmap` concat `fmap` mapM keyValuePairs (W.workspaces ws)
 where keyValuePairs ws = mapM (keyValuePair ws) $ W.integrate' (W.stack ws)
       keyValuePair ws w = flip (,) w `fmap` formatWindowName ws w

-- | Return a formatted string representation of a 'Window'.
formatWindowName :: WindowSpace -> Window -> X String
formatWindowName ws w = do
  name <- fmap (take 15 . map toLower . show) $ getName w
  return $ name ++ " [" ++ [head $ W.tag ws] ++ "]"


-- FOCUS SLAVES

-- Cycle focus between \"slave windows\" in an XMonad workspace.  I found it
-- more confusing than helpful, though.

-- | Focus the previous window which is not the master window.  Wrap around the
--   end.
focusUpSlave :: WindowSet -> WindowSet
focusUpSlave = W.modify' focusUpSlave'
  where 
    focusUpSlave' :: W.Stack a -> W.Stack a
    focusUpSlave' (W.Stack t (l:[]) rs) = W.Stack x xs [] where (x:xs) = reverse (l:t:rs)
    focusUpSlave' (W.Stack t (l:ls) rs) = W.Stack l ls (t:rs)
    focusUpSlave' (W.Stack t []     rs) = W.Stack x xs [] where (x:xs) = reverse (t:rs)

-- | Focus the next window which is not the master window.  Wrap around the
--   end.
focusDownSlave :: WindowSet -> WindowSet
focusDownSlave = W.modify' focusDownSlave'
  where
    focusDownSlave' s@(W.Stack _ []   []) = s
    focusDownSlave' (W.Stack t ls (r:rs)) = W.Stack r (t:ls) rs
    focusDownSlave' (W.Stack t ls     []) = W.Stack x [m] xs where (m:x:xs) = reverse (t:ls)

-- | Swap position with the previous window which is not the master window.
--   Wrap around the end.
swapUpSlave :: WindowSet -> WindowSet
swapUpSlave = W.modify' swapUpSlave'
  where
    swapUpSlave' (W.Stack t (l:[]) rs) = W.Stack t (reverse (l:rs)) []
    swapUpSlave' (W.Stack t (l:ls) rs) = W.Stack t ls (l:rs)
    swapUpSlave' (W.Stack t []     rs) = W.Stack t (reverse rs) []

-- | Swap position with the next window which is not the master window. Wrap
--   around the end.
swapDownSlave :: WindowSet -> WindowSet
swapDownSlave = W.modify' swapDownSlave'
  where
    swapDownSlave' s@(W.Stack _ []     []) = s
    swapDownSlave' (W.Stack t ls   (r:rs)) = W.Stack t (r:ls) rs
    swapDownSlave' (W.Stack t ls@(_:_) []) = W.Stack t [x] xs where (x:xs) = (reverse ls)