import System.IO
import System.Exit

import XMonad

import qualified Data.Map        as M
import qualified XMonad.StackSet as W

import XMonad.Hooks.DynamicLog
import XMonad.Hooks.ManageDocks
import XMonad.Hooks.ManageHelpers
import XMonad.Hooks.EwmhDesktops

import XMonad.Config.Desktop

import XMonad.Util.Run

import XMonad.Layout.LayoutHints
import XMonad.Layout.Maximize
import XMonad.Layout.NoBorders
import XMonad.Layout.PerWorkspace
import XMonad.Layout.Reflect
import XMonad.Layout.ResizableTile
import XMonad.Layout.SimplestFloat
import XMonad.Layout.WindowNavigation

import XMonad.Actions.Navigation2D

--------------------------------------

-- Options
-- -------
myBorderWidth        = 2
myModMask            = mod1Mask
myNormalBorderColor = "#202020"
myFocusedBorderColor = "#819a67"
myTerminal           = "termite -e /home/jake/scripts/tmux/new-session.sh"
myWorkspaces         = ["tile","float","max", "xtra"]


-- Keybinds
-- --------
myKeys conf@(XConfig {XMonad.modMask = modm}) = M.fromList $

   [ ((modm .|. shiftMask, xK_Return), spawn $ XMonad.terminal conf)
   , ((modm,               xK_p     ), spawn "dmenu_run -p 'Run:'")
   , ((modm .|. shiftMask, xK_c     ), kill)
   , ((modm,               xK_space ), sendMessage NextLayout)
   , ((modm .|. shiftMask, xK_space ), setLayout $ XMonad.layoutHook conf)
   , ((modm,               xK_Tab   ), windows W.focusDown)
   , ((modm,               xK_j     ), windowGo D False )
   , ((modm,               xK_k     ), windowGo U False )
   , ((modm,               xK_l     ), windowGo R False )
   , ((modm,               xK_h     ), windowGo L False )
   , ((modm,               xK_Return), windows W.swapMaster)
   , ((modm .|. shiftMask, xK_j     ), windowSwap D False )
   , ((modm .|. shiftMask, xK_k     ), windowSwap U False )
   , ((modm .|. shiftMask, xK_l     ), windowSwap R False )
   , ((modm .|. shiftMask, xK_h     ), windowSwap L False )
   , ((modm .|. controlMask,  xK_h     ), sendMessage Shrink)
   , ((modm .|. controlMask,  xK_l     ), sendMessage Expand)
   , ((modm,               xK_t     ), withFocused $ windows . W.sink)
   , ((modm,               xK_m     ), withFocused (sendMessage . maximizeRestore))
   , ((modm,               xK_comma ), sendMessage (IncMasterN 1))
   , ((modm,               xK_period), sendMessage (IncMasterN (-1)))
   , ((modm .|. shiftMask, xK_q     ), io (exitWith ExitSuccess))
   , ((modm .|. shiftMask, xK_r     ), restart "xmonad" True)
   , ((modm,               xK_b     ), sendMessage ToggleStruts)
   , ((modm .|. controlMask, xK_j     ), sendMessage MirrorShrink)
   , ((modm .|. controlMask, xK_k     ), sendMessage MirrorExpand)

   -- Manual Movements
   -- ------ ---------
   , ((modm .|. controlMask, xK_Right), sendMessage $ Move R)
   , ((modm .|. controlMask, xK_Left ), sendMessage $ Move L)
   , ((modm .|. controlMask, xK_Up   ), sendMessage $ Move U)
   , ((modm .|. controlMask, xK_Down ), sendMessage $ Move D)

   -- App Shortcuts
   , ((mod4Mask .|. shiftMask, xK_Return), spawn "termite")

   , ((mod4Mask,   xK_w), spawn "termite -e /home/jake/scripts/weelaunch.sh")
   , ((mod4Mask .|. shiftMask,   xK_w), spawn "termite --profile=Writing -- vim -c Goyo -c Limelight")

   , ((modm, xK_F10), spawn "/home/jake/scripts/nkjv/nkjv-menu.sh")
   , ((modm, xK_F11), spawn "/home/jake/scripts/nkjv/nkjv-menu.sh md")
   , ((modm, xK_F12), spawn "/home/jake/scripts/nkjv/nkjv-menu.sh marp")
   ]

    ++
   [((m .|. modm, k), windows $ f i)
        | (i, k) <- zip (XMonad.workspaces conf) [xK_1 .. xK_9]
       , (f, m) <- [(W.greedyView, 0), (W.shift, shiftMask)]]

-- Multi monitor stuff?
   -- ++
   --[((m .|. modm, key), screenWorkspace sc >>= flip whenJust (windows . f))
       -- | (key, sc) <- zip [xK_w, xK_e, xK_r] [0..]
       --, (f, m) <- [(W.view, 0), (W.shift, shiftMask)]]


-- Mouse
-- -----
myMouseBindings (XConfig {XMonad.modMask = modMask}) = M.fromList $

   [ ((modMask, button1), (\w -> focus w >> mouseMoveWindow w))
   , ((modMask, button2), (\w -> focus w >> windows W.swapMaster))
   , ((modMask, button3), (\w -> focus w >> mouseResizeWindow w))
   ]

myFocusFollowsMouse :: Bool
myFocusFollowsMouse = True


-- Layouts
-- -------
myLayout = smartBorders $ maximize ( lays )
 where
    tiled   = ResizableTall 1 (1/100) (132/227) []
    tiled2  = ResizableTall 1 (1/100) (1/2) []
    w1 = onWorkspace "float" simplestFloat (tiled2)
    w2 = reflectHoriz tiled
    w3 = ResizableTall 2 (1/100) (55/100) []
    lays = onWorkspace "max" Full (w1) ||| Mirror w3 ||| tiled


-- Kludges
-- -------
myManageHook = composeAll
   [ className =? "feh"            --> doFloat
   , className =? "lxappearance"   --> doFloat
   , className =? "Xmessage"       --> doFloat
   , className =? "sxiv"           --> doFloat
   , className =? "Sxiv"           --> doFloat
   , resource  =? "desktop_window" --> doIgnore
   , isFullscreen                  --> doFullFloat ]
   where unfloat = ask >>= doF . W.sink


-- Log, Startup
-- -------
myLogHook = return ()
myStartupHook = do
     spawn "$HOME/.config/polybar/launch.sh xmonad"
     -- spawn "nitrogen --restore"


-- XMobar PP
-- ------ --
-- myPP :: PP
-- myPP = defaultPP
--        { ppCurrent = xmobarColor "#7a8f65" ""
--        , ppSep = xmobarColor "#acacab" "" " // "
--        , ppLayout = xmobarColor "#658f8f" ""
--        , ppUrgent = xmobarColor "8f6f65" ""
--        , ppTitle = xmobarColor "#acacab" "" . pad }


-- Get Ready
-- --- -----
myconfig = desktopConfig {
       terminal           = myTerminal,
       focusFollowsMouse  = myFocusFollowsMouse,
       borderWidth        = myBorderWidth,
       modMask            = myModMask,
       workspaces         = myWorkspaces,
       normalBorderColor  = myNormalBorderColor,
       focusedBorderColor = myFocusedBorderColor,

       keys               = myKeys,
       mouseBindings      = myMouseBindings,

       layoutHook         = desktopLayoutModifiers $ myLayout,
       manageHook         = myManageHook
           <+> manageDocks <+> manageHook desktopConfig,
       logHook            = myLogHook,
       handleEventHook    = handleEventHook desktopConfig <+> fullscreenEventHook,
       startupHook        = myStartupHook <+> startupHook desktopConfig
   }

-- Make it rain
-- ---- -- ----
main = do
      -- xmobar <- spawnPipe "xmobar"
      xmonad $ ewmh $ myconfig
             -- { logHook = dynamicLogWithPP $ myPP { ppOutput = hPutStrLn xmobar } }