/* See LICENSE file for copyright and license details. */

/* appearance */
static const unsigned int borderpx       = 3;   /* border pixel of windows */
static const unsigned int snap           = 0;  /* snap pixel */
static const int swallowfloating         = 1;   /* 1 means swallow floating windows by default */
static const unsigned int gappih         = 10;  /* horiz inner gap between windows */
static const unsigned int gappiv         = 10;  /* vert inner gap between windows */
static const unsigned int gappoh         = 20;  /* horiz outer gap between windows and screen edge */
static const unsigned int gappov         = 30;  /* vert outer gap between windows and screen edge */
static const int smartgaps_fact          = 1;   /* gap factor when there is only one client; 0 = no gaps, 3 = 3x outer gaps */
static const int showbar                 = 1;   /* 0 means no bar */
static const int topbar                  = 1;   /* 0 means bottom bar */
/* Status is to be shown on: -1 (all monitors), 0 (a specific monitor by index), 'A' (active monitor) */
static const int statusmon               = 'A';

/* Indicators: see patch/bar_indicators.h for options */
static int tagindicatortype              = INDICATOR_NONE;
static int tiledindicatortype            = INDICATOR_NONE;
static int floatindicatortype            = INDICATOR_NONE;
static const char *fonts[]               = { "monospace:size=15" };
static const char dmenufont[]            = "monospace:size=15";

static char c000000[]                    = "#000000";

static char normfgcolor[]                = "#bbbbbb";
static char normbgcolor[]                = "#222222";
static char normbordercolor[]            = "#444444";
static char normfloatcolor[]             = "#db8fd9";

static char selfgcolor[]                 = "#eeeeee";
static char selbgcolor[]                 = "#005577";
static char selbordercolor[]             = "#005577";
static char selfloatcolor[]              = "#005577";

static char titlenormfgcolor[]           = "#bbbbbb";
static char titlenormbgcolor[]           = "#222222";
static char titlenormbordercolor[]       = "#444444";
static char titlenormfloatcolor[]        = "#db8fd9";

static char titleselfgcolor[]            = "#eeeeee";
static char titleselbgcolor[]            = "#005577";
static char titleselbordercolor[]        = "#005577";
static char titleselfloatcolor[]         = "#005577";

static char tagsnormfgcolor[]            = "#bbbbbb";
static char tagsnormbgcolor[]            = "#222222";
static char tagsnormbordercolor[]        = "#444444";
static char tagsnormfloatcolor[]         = "#db8fd9";

static char tagsselfgcolor[]             = "#eeeeee";
static char tagsselbgcolor[]             = "#005577";
static char tagsselbordercolor[]         = "#005577";
static char tagsselfloatcolor[]          = "#005577";

static char hidnormfgcolor[]             = "#005577";
static char hidselfgcolor[]              = "#227799";
static char hidnormbgcolor[]             = "#222222";
static char hidselbgcolor[]              = "#222222";

static char urgfgcolor[]                 = "#bbbbbb";
static char urgbgcolor[]                 = "#222222";
static char urgbordercolor[]             = "#ff0000";
static char urgfloatcolor[]              = "#db8fd9";



static const unsigned int baralpha = 0xff;
static const unsigned int borderalpha = OPAQUE;
static const unsigned int alphas[][3] = {
	/*                       fg      bg        border     */
	[SchemeNorm]         = { OPAQUE, baralpha, borderalpha },
	[SchemeSel]          = { OPAQUE, baralpha, borderalpha },
	[SchemeTitleNorm]    = { OPAQUE, baralpha, borderalpha },
	[SchemeTitleSel]     = { OPAQUE, baralpha, borderalpha },
	[SchemeTagsNorm]     = { OPAQUE, baralpha, borderalpha },
	[SchemeTagsSel]      = { OPAQUE, baralpha, borderalpha },
	[SchemeHidNorm]      = { OPAQUE, baralpha, borderalpha },
	[SchemeHidSel]       = { OPAQUE, baralpha, borderalpha },
	[SchemeUrg]          = { OPAQUE, baralpha, borderalpha },
};

static char *colors[][ColCount] = {
	/*                       fg                bg                border                float */
	[SchemeNorm]         = { normfgcolor,      normbgcolor,      normbordercolor,      normfloatcolor },
	[SchemeSel]          = { selfgcolor,       selbgcolor,       selbordercolor,       selfloatcolor },
	[SchemeTitleNorm]    = { titlenormfgcolor, titlenormbgcolor, titlenormbordercolor, titlenormfloatcolor },
	[SchemeTitleSel]     = { titleselfgcolor,  titleselbgcolor,  titleselbordercolor,  titleselfloatcolor },
	[SchemeTagsNorm]     = { tagsnormfgcolor,  tagsnormbgcolor,  tagsnormbordercolor,  tagsnormfloatcolor },
	[SchemeTagsSel]      = { tagsselfgcolor,   tagsselbgcolor,   tagsselbordercolor,   tagsselfloatcolor },
	[SchemeHidNorm]      = { hidnormfgcolor,   hidnormbgcolor,   c000000,              c000000 },
	[SchemeHidSel]       = { hidselfgcolor,    hidselbgcolor,    c000000,              c000000 },
	[SchemeUrg]          = { urgfgcolor,       urgbgcolor,       urgbordercolor,       urgfloatcolor },
};



static const char *const autostart[] = {
	//"sh", "-c", "$HOME/.xprofile", NULL,
	NULL /* terminate */
};

const char *spcmd1[] = {"st", "-n", "spterm", "-g", "120x34", NULL };
static Sp scratchpads[] = {
   /* name          cmd  */
   {"spterm",      spcmd1},
};

/* Tags
 * In a traditional dwm the number of tags in use can be changed simply by changing the number
 * of strings in the tags array. This build does things a bit different which has some added
 * benefits. If you need to change the number of tags here then change the NUMTAGS macro in dwm.c.
 *
 * Examples:
 *
 *  1) static char *tagicons[][NUMTAGS*2] = {
 *         [DEFAULT_TAGS] = { "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F", "G", "H", "I" },
 *     }
 *
 *  2) static char *tagicons[][1] = {
 *         [DEFAULT_TAGS] = { "•" },
 *     }
 *
 * The first example would result in the tags on the first monitor to be 1 through 9, while the
 * tags for the second monitor would be named A through I. A third monitor would start again at
 * 1 through 9 while the tags on a fourth monitor would also be named A through I. Note the tags
 * count of NUMTAGS*2 in the array initialiser which defines how many tag text / icon exists in
 * the array. This can be changed to *3 to add separate icons for a third monitor.
 *
 * For the second example each tag would be represented as a bullet point. Both cases work the
 * same from a technical standpoint - the icon index is derived from the tag index and the monitor
 * index. If the icon index is is greater than the number of tag icons then it will wrap around
 * until it an icon matches. Similarly if there are two tag icons then it would alternate between
 * them. This works seamlessly with alternative tags and alttagsdecoration patches.
 */
static char *tagicons[][NUMTAGS] = {
	[DEFAULT_TAGS]        = { "1", "2", "3", "4", "5", "6", "7", "8", "9" },
	[ALTERNATIVE_TAGS]    = { "A", "B", "C", "D", "E", "F", "G", "H", "I" },
	[ALT_TAGS_DECORATION] = { "<1>", "<2>", "<3>", "<4>", "<5>", "<6>", "<7>", "<8>", "<9>" },
};


/* There are two options when it comes to per-client rules:
 *  - a typical struct table or
 *  - using the RULE macro
 *
 * A traditional struct table looks like this:
 *    // class      instance  title  wintype  tags mask  isfloating  monitor
 *    { "Gimp",     NULL,     NULL,  NULL,    1 << 4,    0,          -1 },
 *    { "Firefox",  NULL,     NULL,  NULL,    1 << 7,    0,          -1 },
 *
 * The RULE macro has the default values set for each field allowing you to only
 * specify the values that are relevant for your rule, e.g.
 *
 *    RULE(.class = "Gimp", .tags = 1 << 4)
 *    RULE(.class = "Firefox", .tags = 1 << 7)
 *
 * Refer to the Rule struct definition for the list of available fields depending on
 * the patches you enable.
 */
static const Rule rules[] = {
	/* xprop(1):
	 *	WM_CLASS(STRING) = instance, class
	 *	WM_NAME(STRING) = title
	 *	WM_WINDOW_ROLE(STRING) = role
	 *	_NET_WM_WINDOW_TYPE(ATOM) = wintype
	 */
	RULE(.wintype = WTYPE "DIALOG", .isfloating = 1)
	RULE(.wintype = WTYPE "UTILITY", .isfloating = 1)
	RULE(.wintype = WTYPE "TOOLBAR", .isfloating = 1)
	RULE(.wintype = WTYPE "SPLASH", .isfloating = 1)
	//RULE(.class = "Gimp", .tags = 1 << 4)
	//RULE(.class = "Firefox", .tags = 1 << 7)
	RULE(.instance = "spterm", .tags = SPTAG(0), .isfloating = 1)
};



/* Bar rules allow you to configure what is shown where on the bar, as well as
 * introducing your own bar modules.
 *
 *    monitor:
 *      -1  show on all monitors
 *       0  show on monitor 0
 *      'A' show on active monitor (i.e. focused / selected) (or just -1 for active?)
 *    bar - bar index, 0 is default, 1 is extrabar
 *    alignment - how the module is aligned compared to other modules
 *    widthfunc, drawfunc, clickfunc - providing bar module width, draw and click functions
 *    name - does nothing, intended for visual clue and for logging / debugging
 */
static const BarRule barrules[] = {
	/* monitor   bar    alignment         widthfunc                 drawfunc                clickfunc                hoverfunc                name */
	{ -1,        0,     BAR_ALIGN_LEFT,   width_tags,               draw_tags,              click_tags,              hover_tags,              "tags" },
	{ -1,        0,     BAR_ALIGN_LEFT,   width_ltsymbol,           draw_ltsymbol,          click_ltsymbol,          NULL,                    "layout" },
	{ statusmon, 0,     BAR_ALIGN_RIGHT,  width_status,             draw_status,            click_status,            NULL,                    "status" },
	{ -1,        0,     BAR_ALIGN_NONE,   width_wintitle,           draw_wintitle,          click_wintitle,          NULL,                    "wintitle" },
};

/* layout(s) */
static const float mfact     = 0.55; /* factor of master area size [0.05..0.95] */
static const int nmaster     = 1;    /* number of clients in master area */
static const int resizehints = 0;    /* 1 means respect size hints in tiled resizals */
static const int lockfullscreen = 1; /* 1 will force focus on the fullscreen window */



static const Layout layouts[] = {
	/* symbol     arrange function */
	{ " master",      tile },    /* first entry is default */
	{ " float",      NULL },    /* no layout function means floating behavior */
};

/* key definitions */
#define MODKEY Mod4Mask
#define TAGKEYS(KEY,TAG) \
	{ MODKEY,                       KEY,      view,           {.ui = 1 << TAG} }, \
	{ MODKEY|ControlMask,           KEY,      toggleview,     {.ui = 1 << TAG} }, \
	{ MODKEY|ShiftMask,             KEY,      tag,            {.ui = 1 << TAG} }, \
	{ MODKEY|ControlMask|ShiftMask, KEY,      toggletag,      {.ui = 1 << TAG} },

/* helper for spawning shell commands in the pre dwm-5.0 fashion */
#define SHCMD(cmd) { .v = (const char*[]){ "/bin/sh", "-c", cmd, NULL } }

/* commands */
static char dmenumon[2] = "0"; /* component of dmenucmd, manipulated in spawn() */
static const char *dmenucmd[] = {
	"dmenu_run",
	"-m", dmenumon,
	"-fn", dmenufont,
	"-nb", normbgcolor,
	"-nf", normfgcolor,
	"-sb", selbgcolor,
	"-sf", selfgcolor,
	NULL
};

static const char *termcmd[]  = { "st", NULL };

///////////////////////////////////////////////KEYBINDS//////////////////////////////////////////////
#include <X11/XF86keysym.h>
//different commands per OS
#ifdef __linux__
	#define VOL_UP "pamixer --allow-boost -i 10; kill -44 $(pidof dwmblocks)"
	#define XK_UP "pamixer --allow-boost -i 5; kill -44 $(pidof dwmblocks)"
	#define VOL_DOWN "pamixer --allow-boost -d 10; kill -44 $(pidof dwmblocks)"
	#define XK_DOWN "pamixer --allow-boost -d 5; kill -44 $(pidof dwmblocks)"
	#define VOL_MUTE "pamixer -t; kill -44 $(pidof dwmblocks)"
	#define VOL_KILL "kill -44 $(pidof dwmblocks)"
#elif __OpenBSD__
	#define VOL_UP "sndioctl output.level=+0.10; pkill -SIGUSR1 dwmblocks"
	#define XK_UP "sndioctl output.level=+0.05; pkill -SIGUSR1 dwmblocks"
	#define VOL_DOWN "sndioctl output.level=-0.10; pkill -SIGUSR1 dwmblocks"
	#define XK_DOWN "sndioctl output.level=-0.05; pkill -SIGUSR1 dwmblocks"
	#define VOL_MUTE "sndioctl output.mute=!; pkill -SIGUSR1 dwmblocks"
	#define VOL_KILL "pkill -SIGUSR1 dwmblocks"
#elif __FreeBSD__
	#define VOL_UP "sndioctl output.level=+0.10"
	#define XK_UP "sndioctl output.level=+0.05"
	#define VOL_DOWN "sndioctl output.level=-0.10"
	#define XK_DOWN "sndioctl output.level=-0.05"
	#define VOL_MUTE "sndioctl output.level=-1"
	#define VOL_KILL "pkill -SIGUSR2 dwmblocks"
#endif

static Key keys[] = {
	/*modifierkey			function		argument */
	{ MODKEY,				XK_r,			spawn,					{.v = dmenucmd } },
	{ MODKEY,				XK_j,			focusstack,				{.i = +1 } },
	{ MODKEY,				XK_k,			focusstack,				{.i = -1 } },
	{ MODKEY,				XK_Down,		moveresize,				{.v = "0x 25y 0w 0h" } },
	{ MODKEY,				XK_Up,			moveresize,				{.v = "0x -25y 0w 0h" } },
	{ MODKEY,				XK_Right,		moveresize,				{.v = "25x 0y 0w 0h" } },
	{ MODKEY,				XK_Left,		moveresize,				{.v = "-25x 0y 0w 0h" } },
	{ MODKEY|ShiftMask,		XK_Down,		moveresize,				{.v = "0x 0y 0w 25h" } },
	{ MODKEY|ShiftMask,		XK_Up,			moveresize,				{.v = "0x 0y 0w -25h" } },
	{ MODKEY|ShiftMask,		XK_Right,		moveresize,				{.v = "0x 0y 25w 0h" } },
	{ MODKEY|ShiftMask,		XK_Left,		moveresize,				{.v = "0x 0y -25w 0h" } },
	{ MODKEY,				XK_Tab,			view,					{0} },
	{ MODKEY|ShiftMask,		XK_F5,			xrdb,					{.v = NULL } },
	{ MODKEY,				XK_t,			setlayout,				{.v = &layouts[0]} },
	{ MODKEY,				XK_space,		setlayout,				{0} },
	{ MODKEY|ShiftMask,		XK_space,		togglefloating,			{0} },
	{ MODKEY,				XK_grave,		togglescratch,			{.ui = 0 } },
	{ MODKEY|ControlMask,	XK_grave,		setscratch,				{.ui = 0 } },
	{ MODKEY|ShiftMask,		XK_grave,		removescratch,			{.ui = 0 } },
	{ MODKEY,				XK_w,			togglefullscreen,		{0} },
	{ MODKEY,				XK_0,			view,					{.ui = ~SPTAGMASK } },
	{ MODKEY|ShiftMask,		XK_0,			tag,					{.ui = ~SPTAGMASK } },
	
	  TAGKEYS(				XK_1,									0)
	  TAGKEYS(				XK_2,									1)
	  TAGKEYS(				XK_3,									2)
	  TAGKEYS(				XK_4,									3)
	  TAGKEYS(				XK_5,									4)
	  TAGKEYS(				XK_6,									5)
	  TAGKEYS(				XK_7,									6)
	  TAGKEYS(				XK_8,									7)
	  TAGKEYS(				XK_9,									8)

	{ MODKEY,				XK_h,			setmfact,				{.f = -0.05} },
	{ MODKEY,				XK_l,			setmfact,				{.f = +0.05} },
	{ MODKEY|ShiftMask,     XK_q,quit,								{0} },
	{ MODKEY|ShiftMask,     XK_e,quit,								{0} },
	{ MODKEY,				XK_b,			togglebar,				{0} },
	{ MODKEY,				XK_d,			spawn,					{.v = dmenucmd } },
	{ MODKEY,				XK_w,			togglefullscreen,		{0} },
	{ MODKEY,				XK_m,			zoom,					{0} },
	{ MODKEY,				XK_o,			incnmaster,				{.i = +1 } },
	{ MODKEY,				XK_Return,		spawn,					{.v = termcmd } },
	{ MODKEY|ShiftMask,		XK_o,			incnmaster,				{.i = -1 } },
	{ MODKEY,				XK_s,			killclient,				{0} },
	{ MODKEY|ShiftMask,     XK_j,			movestack,				{.i = +1 } },
	{ MODKEY|ShiftMask,     XK_k,			movestack,				{.i = -1 } },
	{ MODKEY|ShiftMask,		XK_Return,		togglescratch,			{.ui = 0 } },
	{ 0,					XK_F12,			togglescratch,			{.ui = 0 } },

	//volume control
	{ Mod1Mask,				XK_equal, 		spawn,					SHCMD(VOL_UP) },
	{ Mod1Mask,				XK_minus, 		spawn,					SHCMD(VOL_DOWN) },
	{ Mod1Mask,				XK_m,			spawn,					SHCMD(VOL_MUTE) },
	{ 0, 					XF86XK_AudioMute, spawn,				SHCMD(VOL_MUTE) },
	{ 0, 					XF86XK_AudioRaiseVolume, spawn,			SHCMD(XK_UP) },
	{ 0, 					XF86XK_AudioLowerVolume, spawn,			SHCMD(XK_DOWN) },

	{ 0,					XK_Print,		spawn,			SHCMD("screenie")},
};
/////////////////////////////////////////////////////////////////////////////////////////////////////


/* button definitions */
/* click can be ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle, ClkClientWin, or ClkRootWin */
static Button buttons[] = {
	/* click                event mask           button          function        argument */
	{ ClkLtSymbol,          0,                   Button1,        setlayout,      {0} },
	{ ClkLtSymbol,          0,                   Button3,        setlayout,      {.v = &layouts[2]} },
	{ ClkWinTitle,          0,                   Button2,        zoom,           {0} },
	{ ClkStatusText,        0,                   Button2,        spawn,          {.v = termcmd } },
	{ ClkClientWin,         MODKEY,              Button1,        movemouse,      {0} },
	{ ClkClientWin,         MODKEY,              Button2,        togglefloating, {0} },
	{ ClkClientWin,         MODKEY,              Button3,        resizemouse,    {0} },
	{ ClkTagBar,            0,                   Button1,        view,           {0} },
	{ ClkTagBar,            0,                   Button3,        toggleview,     {0} },
	{ ClkTagBar,            MODKEY,              Button1,        tag,            {0} },
	{ ClkTagBar,            MODKEY,              Button3,        toggletag,      {0} },
};

/* signal definitions */
/* signum must be greater than 0 */
/* trigger signals using `xsetroot -name "fsignal:<signame> [<type> <value>]"` */
static Signal signals[] = {
	/* signum                    function */
	{ "focusstack",              focusstack },
	{ "setmfact",                setmfact },
	{ "togglebar",               togglebar },
	{ "incnmaster",              incnmaster },
	{ "togglefloating",          togglefloating },
	{ "focusmon",                focusmon },
	{ "tagmon",                  tagmon },
	{ "zoom",                    zoom },
	{ "incrgaps",                incrgaps },
	{ "incrigaps",               incrigaps },
	{ "incrogaps",               incrogaps },
	{ "incrihgaps",              incrihgaps },
	{ "incrivgaps",              incrivgaps },
	{ "incrohgaps",              incrohgaps },
	{ "incrovgaps",              incrovgaps },
	{ "togglegaps",              togglegaps },
	{ "defaultgaps",             defaultgaps },
	{ "setgaps",                 setgapsex },
	{ "view",                    view },
	{ "viewall",                 viewallex },
	{ "viewex",                  viewex },
	{ "toggleview",              toggleview },
	{ "toggleviewex",            toggleviewex },
	{ "tag",                     tag },
	{ "tagall",                  tagallex },
	{ "tagex",                   tagex },
	{ "toggletag",               toggletag },
	{ "toggletagex",             toggletagex },
	{ "togglefullscreen",        togglefullscreen },
	{ "fullscreen",              fullscreen },
	{ "togglescratch",           togglescratch },
	{ "killclient",              killclient },
	{ "xrdb",                    xrdb },
	{ "quit",                    quit },
	{ "setlayout",               setlayout },
	{ "setlayoutex",             setlayoutex },
};

