local awful = require("awful")
local gears = require("gears")
local hotkeys_popup = require("awful.hotkeys_popup")
local menubar = require("menubar")
local pavolctld = require("lib.pavolctld")
-- Enable hotkeys help widget for VIM and other apps
-- when client with a matching name is opened:
-- require("awful.hotkeys_popup.keys")

-- Shortcuts for readable keybinds
local super = "Mod4"
local alt   = "Mod1"
local shift = "Shift"
local ctrl  = "ctrl"

local key = awful.key
local a  = { alt }
local as = { alt, shift }
local w  = { super }
local s  = { shift }
local c  = { ctrl }
local wc = { super, ctrl }
local ws = { super, shift }
local wa = { super, alt }


-- Functions
function focus_previous()
	awful.client.focus.history.previous()
	if client.focus then
		client.focus:raise()
	end
end

-- Key bindings
globalkeys = gears.table.join(
	-- Applications
	key(a , "Return", function () awful.spawn(terminal)                           end, { group = "launcher", description = "open a terminal" }),
	key(a , "f",      function () awful.spawn("pcmanfm")                          end, { group = "launcher", description = "launch pcmanfm" }),
	key(a , "b",      function () awful.spawn("launch firefox")                   end, { group = "launcher", description = "launch firefox" }),
	key(a , "c",      function () awful.spawn("launch chrome")                    end, { group = "launcher", description = "launch firefox (alt profile)" }),
	-- Wallpaper
	key(w , "w",      function () awful.spawn("seasonalwallpaper")                end, { group = "launcher", description = "change wallpaper" }),
	-- Awesome
	key(w , "F1",     hotkeys_popup.show_help                                        , { group = "awesome" , description = "show help" }),
	key(w , "F10",    awesome.restart                                                , { group = "awesome" , description = "reload awesome" }),
	key(ws, "F10",    awesome.quit                                                   , { group = "awesome" , description = "quit awesome" }),
	key(w , "Tab",    awful.tag.history.restore                                      , { group = "tag"     , description = "go back" }),
	-- Window Management
	key(w , "j",      function () awful.client.focus.byidx( 1)                    end, { group = "client"  , description = "focus next by index" }),
	key(w , "k",      function () awful.client.focus.byidx(-1)                    end, { group = "client"  , description = "focus previous by index" }),
	key(ws, "j",      function () awful.client.swap.byidx(  1)                    end, { group = "client"  , description = "swap with next client by index" }),
	key(ws, "k",      function () awful.client.swap.byidx( -1)                    end, { group = "client"  , description = "swap with previous client by index" }),
	key(w , ",",      function () awful.screen.focus_relative(-1)                 end, { group = "screen"  , description = "focus the previous screen" }),
	key(w , ".",      function () awful.screen.focus_relative( 1)                 end, { group = "screen"  , description = "focus the next screen" }),
	key(w , "u",      awful.client.urgent.jumpto                                     , { group = "client"  , description = "jump to urgent client" }),
	key(a , "Tab",    focus_previous                                                 , { group = "client"  , description = "focus previous client" }),
	key(w , "l",      function () awful.tag.incmwfact( 0.05)                      end, { group = "layout"  , description = "increase master width factor" }),
	key(w , "h",      function () awful.tag.incmwfact(-0.05)                      end, { group = "layout"  , description = "decrease master width factor" }),
	key(ws, "h",      function () awful.tag.incnmaster( 1, nil, true)             end, { group = "layout"  , description = "increase the number of master clients" }),
	key(ws, "l",      function () awful.tag.incnmaster(-1, nil, true)             end, { group = "layout"  , description = "decrease the number of master clients" }),
	--key(wc, "h",      function () awful.tag.incncol( 1, nil, true)                end, { group = "layout"  , description = "increase the number of columns" }),
	--key(wc, "l",      function () awful.tag.incncol(-1, nil, true)                end, { group = "layout"  , description = "decrease the number of columns" }),
	key(w , "m",      function () awful.layout.set(awful.layout.suit.max)         end, { group = "layout"  , description = "change to max layout" }),
	key(w , "t",      function () awful.layout.set(awful.layout.suit.tile)        end, { group = "layout"  , description = "change to tile layout" }),
	key(w , "b",      function () awful.layout.set(awful.layout.suit.tile.bottom) end, { group = "layout"  , description = "change to tile bottom layout" }),
	key(w , "r",      function () awful.screen.focused().mypromptbox:run()        end, { group = "launcher", description = "run prompt" }),
	key(w , "p",      function () menubar.show()                                  end, { group = "launcher", description = "show the menubar" }),
	-- PC Controls
	key(w , "Escape", function () awful.spawn("shutdownprompt")                   end, { group = "system"  , description = "show shutdown prompt" }),
	key(w , "Escape", function () awful.spawn("shutdownprompt")                   end, { group = "system"  , description = "show shutdown prompt" }),
	key(w , "F9",     function () awful.spawn("shutdownprompt Restart")           end, { group = "system"  , description = "restart system" }),
	key(w , "F11",    function () awful.spawn("shutdownprompt Suspend")           end, { group = "system"  , description = "suspend system" }),
	key(w , "F12",    function () awful.spawn("shutdownprompt Shutdown")          end, { group = "system"  , description = "shutdown system" }),
	key(a , "m",      function () awful.spawn("mounter -m")                       end, { group = "system"  , description = "mount drive prompt" }),
	key(as, "m",      function () awful.spawn("mounter -u")                       end, { group = "system"  , description = "unmount drive prompt" }),
	-- Screenshots
	key({}, "Print",  function () awful.spawn("screenshot -x")                    end, { group = "misc"    , description = "screenshot, copy to clipboard" }),
	key(a , "Print",  function () awful.spawn("screenshot -xc")                   end, { group = "misc"    , description = "screenshot, crop, copy to clipboard" }),
	key(w , "Print",  function () awful.spawn("screenshot")                       end, { group = "misc"    , description = "screenshot, save to screenshots dir" }),
	key(wa, "Print",  function () awful.spawn("screenshot -c")                    end, { group = "misc"    , description = "screenshot, crop, save to screenshots dir" }),
	-- Monitor Controls
	key(w , "F5",     function () awful.spawn("bl set 0")                         end, { group = "monitor" , description = "set monitor brightness to 0%" }),
	key(w , "F6",     function () awful.spawn("bl set 25")                        end, { group = "monitor" , description = "set monitor brightness to 25%" }),
	key(w , "F7",     function () awful.spawn("bl set 50")                        end, { group = "monitor" , description = "set monitor brightness to 50%" }),
	key(w , "F8",     function () awful.spawn("bl set 100")                       end, { group = "monitor" , description = "set monitor brightness to 100%" }),
	key({}, "XF86MonBrightnessUp",   function () awful.spawn("bl inc 10")         end, { group = "monitor" , description = "increase monitor brightness by 10%" }),
	key({}, "XF86MonBrightnessDown", function () awful.spawn("bl dec 10")         end, { group = "monitor" , description = "decrease monitor brightness by 10%" })
)

-- Volume Controls
if pavolctld then globalkeys = gears.table.join(globalkeys,
	key({}, "XF86AudioRaiseVolume",  function () pavolctld.volume_inc(5)          end, { group = "volume"  , description = "increase volume by 5%" }),
	key({}, "XF86AudioLowerVolume",  function () pavolctld.volume_dec(5)          end, { group = "volume"  , description = "decrease volume by 5%" }),
	key({}, "XF86AudioMute",         pavolctld.mute_toggle                           , { group = "volume"  , description = "toggle audio mute" })
) end


-- Client protection
local beautiful = require("beautiful")
local function protectClient(c)
	c.prevent_kill = true
	c.screen:emit_signal("arrange")
end
local function unProtectClient(c)
	c.prevent_kill = false
	c.screen:emit_signal("arrange")
end
local function killClient(c)
	if not c.prevent_kill then
		c:kill()
	end
end

-- Client swap with master (more similar to dwm)
local function masterswap(c)
	local m = awful.client.getmaster()
	if m ~= c then
		c:swap(awful.client.getmaster())
	else
		c:swap(awful.client.next(1, c))
	end
end

-- Client keys
clientkeys = gears.table.join(
	key(w , "q",      killClient                                           , { description = "close",                group = "client" }),
	key(w , "x",      protectClient                                        , { description = "prevent closing",      group = "client" }),
	key(ws, "x",      unProtectClient                                      , { description = "allow closing",        group = "client" }),
	key(wc, "space",  awful.client.floating.toggle                         , { description = "toggle floating",      group = "client" }),
	key(w , "Return", masterswap                                           , { description = "move to master",       group = "client" }),
	key(ws, ",",      function (c) c:move_to_screen(c.screen.index - 1) end, { description = "move to left screen",  group = "client" }),
	key(ws, ".",      function (c) c:move_to_screen()                   end, { description = "move to right screen", group = "client" })
)

-- Bind all key numbers to tags.
-- Be careful: we use keycodes to make it work on any keyboard layout.
-- This should map on the top row of your keyboard, usually 1 to 9.
-- Functions

for i = 1, 9 do
	globalkeys = gears.table.join(globalkeys,
		-- View tag only.
		awful.key({ super }, "#" .. i + 9,
				  function ()
						local screen = awful.screen.focused()
						local tag = screen.tags[i]
						if tag then
						   tag:view_only()
						end
				  end,
				  {description = "view tag #"..i, group = "tag"}),
		-- Toggle tag display.
		awful.key({ super, "Control" }, "#" .. i + 9,
				  function ()
					  local screen = awful.screen.focused()
					  local tag = screen.tags[i]
					  if tag then
						 awful.tag.viewtoggle(tag)
					  end
				  end,
				  {description = "toggle tag #" .. i, group = "tag"}),
		-- Move client to tag.
		awful.key({ super, "Shift" }, "#" .. i + 9,
				  function ()
					  if client.focus then
						  local tag = client.focus.screen.tags[i]
						  if tag then
							  client.focus:move_to_tag(tag)
						  end
					 end
				  end,
				  {description = "move focused client to tag #"..i, group = "tag"}),
		-- Toggle tag on focused client.
		awful.key({ super, "Control", "Shift" }, "#" .. i + 9,
				  function ()
					  if client.focus then
						  local tag = client.focus.screen.tags[i]
						  if tag then
							  client.focus:toggle_tag(tag)
						  end
					  end
				  end,
				  {description = "toggle focused client on tag #" .. i, group = "tag"})
	)
end

-- Set keys
root.keys(globalkeys)