/*
 * Copyright (c) 2020 The ZMK Contributors
 *
 * SPDX-License-Identifier: MIT
 */

 /*****************************************
 *   - YOU MUST SET THE FOLLOWING CONFIG VALUES FOR THIS SETUP TO WORK PROPERLY IN YOUR BOARDS .conf FILE
 *     - CONFIG_ZMK_COMBO_MAX_COMBOS_PER_KEY=16
 *     - CONFIG_ZMK_COMBO_MAX_KEYS_PER_COMBO=8
 *     - CONFIG_ZMK_COMBO_MAX_PRESSED_COMBOS=8
 *****************************************/

////////////////////////////////////////
// Various includes
#include <behaviors.dtsi>
#include <dt-bindings/zmk/keys.h>
#include <dt-bindings/zmk/rgb.h>
#include <dt-bindings/zmk/ext_power.h>
#include <dt-bindings/zmk/bt.h>
#include <dt-bindings/zmk/outputs.h>

////////////////////////////////////////
// Layers
#define LAYER_ID_GLOBAL -1
#define LAYER_ID_DEFAULT 0
#define LAYER_ID_FUNC 1
#define LAYER_ID_ALT 2
#define LAYER_ID_BASE 3
#define LAYER_ID_NUMBERS 4
#define LAYER_ID_SYMBOLS 5
#define LAYER_ID_PARENTHETICALS 6
#define LAYER_ID_NAVIGATION 7
#define LAYER_ID_BT_SEL 8
#define LAYER_ID_CUSTOM 9
#define LAYER_ID_BIG_SYM 10
#define LAYER_ID_BIG_FUNCTION 11
#define LAYERS_ARTSEY LAYER_ID_BASE LAYER_ID_NUMBERS LAYER_ID_SYMBOLS LAYER_ID_PARENTHETICALS LAYER_ID_NAVIGATION LAYER_ID_BT_SEL LAYER_ID_CUSTOM LAYER_ID_BIG_SYM LAYER_ID_BIG_FUNCTION

////////////////////////////////////////
// Artsey definitions
#define ARTSEY_BT_TOP &out OUT_BLE
#define ARTSEY_BT_BOTTOM &out OUT_USB
#define TIMEOUT_COMBO_2 150
#define TIMEOUT_COMBO_3 150
#define TIMEOUT_COMBO_4 150
#define TIMEOUT_LAYER_HOLD 200
#define ARTSEY_BASE_A A
#define ARTSEY_BASE_R R
#define ARTSEY_BASE_T T
#define ARTSEY_BASE_S S
#define ARTSEY_BASE_E E
#define ARTSEY_BASE_Y Y
#define ARTSEY_BASE_I I
#define ARTSEY_BASE_O O
#define ARTSEY_COMBO_N N
#define KEY_A 16
#define KEY_R 15
#define KEY_T 14
#define KEY_S 13
#define KEY_E 28
#define KEY_Y 27
#define KEY_I 26
#define KEY_O 25
#define KEY_F_TOP 17
#define KEY_F_BOTTOM 29

////////////////////////////////////////
// Enable OLED
&pro_micro_i2c {
	status = "okay";
};

////////////////////////////////////////
// Sticky / Leader Keys
#define TIMEOUT_STICKY_LEADER_KEY 5000
&sk {
	release-after-ms = <TIMEOUT_STICKY_LEADER_KEY>;
};
&sl { 
	release-after-ms = <TIMEOUT_STICKY_LEADER_KEY>;
};

////////////////////////////////////////
// LED Strip Tweak
&led_strip {
    chain-length = <1>;
};

////////////////////////////////////////
// Behaviors
/ {
    behaviors {
		tildeesc: tilde_escape {
			compatible = "zmk,behavior-mod-morph";
			label = "TILDE_ESCAPE";
			#binding-cells = <0>;
			bindings = <&kp ESC>, <&kp TILDE>;
            mods = <(MOD_LSFT)>;
		};
		layer_base_kp: layer_base_kp { compatible = "zmk,behavior-hold-tap"; label = "layer_base_kp"; 
						#binding-cells = <2>; tapping_term_ms = <TIMEOUT_LAYER_HOLD>; flavor = "tap-preferred"; 
						bindings = <&mo>, <&kp>; };
		layer_numbers_kp: layer_numbers_kp { compatible = "zmk,behavior-hold-tap"; label = "layer_numbers_kp"; 
						#binding-cells = <2>; tapping_term_ms = <TIMEOUT_LAYER_HOLD>; flavor = "tap-preferred"; 
						bindings = <&mo>, <&kp>; };
		layer_symbols_kp: layer_symbols_kp { compatible = "zmk,behavior-hold-tap"; label = "layer_symbols_kp"; 
						#binding-cells = <2>; tapping_term_ms = <TIMEOUT_LAYER_HOLD>; flavor = "tap-preferred"; 
						bindings = <&mo>, <&kp>; };
		layer_parentheticals_kp: layer_parentheticals_kp { compatible = "zmk,behavior-hold-tap"; label = "layer_parentheticals_kp";
						#binding-cells = <2>; tapping_term_ms = <TIMEOUT_LAYER_HOLD>; flavor = "tap-preferred";
						bindings = <&mo>, <&kp>; };
		layer_custom_kp: layer_custom_kp { compatible = "zmk,behavior-hold-tap"; label = "layer_custom_kp";
						#binding-cells = <2>; tapping_term_ms = <TIMEOUT_LAYER_HOLD>; flavor = "tap-preferred";
						bindings = <&mo>, <&kp>; };
		ctrl_alt_kp: ctrl_alt_kp { compatible = "zmk,behavior-hold-tap"; label = "ctrl_alt_kp";
						#binding-cells = <2>; tapping_term_ms = <TIMEOUT_LAYER_HOLD>; flavor = "tap-preferred";
						bindings = <&sk>, <&sk>; };
	};
};

////////////////////////////////////////
// Combos
/ {
	combos {
		compatible = "zmk,combos";
		/*****************************************
		 * 2 key combos
		 *****************************************/
		// Function layer doesn't apply to non-big artsey presently
		#if defined ARTSEY_BIG
		combo_layer_functions { key-positions = <KEY_F_TOP KEY_F_BOTTOM>; bindings = <&sl LAYER_ID_BIG_FUNCTION>; };
		#endif
		combo_enter      { layers = <LAYERS_ARTSEY>; timeout-ms = <TIMEOUT_COMBO_2>; key-positions = <KEY_A KEY_E>; bindings = <&kp ENTER>; };
		combo_control    { layers = <LAYERS_ARTSEY>; timeout-ms = <TIMEOUT_COMBO_2>; key-positions = <KEY_E KEY_S>; bindings = <&sk RCTRL>; };
		combo_gui        { layers = <LAYERS_ARTSEY>; timeout-ms = <TIMEOUT_COMBO_2>; key-positions = <KEY_Y KEY_S>; bindings = <&sk LGUI>; };
		combo_alt        { layers = <LAYERS_ARTSEY>; timeout-ms = <TIMEOUT_COMBO_2>; key-positions = <KEY_I KEY_S>; bindings = <&sk LALT>; };
		combo_backspace  { layers = <LAYERS_ARTSEY>; timeout-ms = <TIMEOUT_COMBO_2>; key-positions = <KEY_E KEY_R>; bindings = <&kp BACKSPACE>; };
		combo_delete     { layers = <LAYERS_ARTSEY>; timeout-ms = <TIMEOUT_COMBO_2>; key-positions = <KEY_I KEY_R>; bindings = <&kp DELETE>; };
		combo_shift_lock { layers = <LAYERS_ARTSEY>; timeout-ms = <TIMEOUT_COMBO_2>; key-positions = <KEY_R KEY_Y>; bindings = <&kt LSHFT>; };

		combo_b           { layers = <LAYER_ID_BASE>; timeout-ms = <TIMEOUT_COMBO_2>; key-positions = <KEY_E KEY_O>; bindings = <&kp B>; };
		combo_c           { layers = <LAYER_ID_BASE>; timeout-ms = <TIMEOUT_COMBO_2>; key-positions = <KEY_E KEY_Y>; bindings = <&kp C>; };
		combo_n           { layers = <LAYER_ID_BASE>; timeout-ms = <TIMEOUT_COMBO_2>; key-positions = <KEY_I KEY_O>; bindings = <&kp ARTSEY_COMBO_N>; };
		combo_f           { layers = <LAYER_ID_BASE>; timeout-ms = <TIMEOUT_COMBO_2>; key-positions = <KEY_A KEY_R>; bindings = <&kp F>; };
		combo_g           { layers = <LAYER_ID_BASE>; timeout-ms = <TIMEOUT_COMBO_2>; key-positions = <KEY_R KEY_T>; bindings = <&kp G>; };
		combo_u           { layers = <LAYER_ID_BASE>; timeout-ms = <TIMEOUT_COMBO_2>; key-positions = <KEY_Y KEY_I>; bindings = <&kp U>; };
		combo_h           { layers = <LAYER_ID_BASE>; timeout-ms = <TIMEOUT_COMBO_2>; key-positions = <KEY_E KEY_I>; bindings = <&kp H>; };
		combo_v           { layers = <LAYER_ID_BASE>; timeout-ms = <TIMEOUT_COMBO_2>; key-positions = <KEY_R KEY_S>; bindings = <&kp V>; };
		combo_j           { layers = <LAYER_ID_BASE>; timeout-ms = <TIMEOUT_COMBO_2>; key-positions = <KEY_T KEY_S>; bindings = <&kp J>; };
		combo_w           { layers = <LAYER_ID_BASE>; timeout-ms = <TIMEOUT_COMBO_2>; key-positions = <KEY_A KEY_S>; bindings = <&kp W>; };
		combo_k           { layers = <LAYER_ID_BASE>; timeout-ms = <TIMEOUT_COMBO_2>; key-positions = <KEY_Y KEY_O>; bindings = <&kp K>; };
		combo_comma       { layers = <LAYER_ID_BASE>; timeout-ms = <TIMEOUT_COMBO_2>; key-positions = <KEY_A KEY_Y>; bindings = <&kp COMMA>; };
		combo_period      { layers = <LAYER_ID_BASE>; timeout-ms = <TIMEOUT_COMBO_2>; key-positions = <KEY_A KEY_I>; bindings = <&kp PERIOD>; };
		combo_slash       { layers = <LAYER_ID_BASE>; timeout-ms = <TIMEOUT_COMBO_2>; key-positions = <KEY_A KEY_O>; bindings = <&kp SLASH>; };
		combo_exclamation { layers = <LAYER_ID_BASE>; timeout-ms = <TIMEOUT_COMBO_2>; key-positions = <KEY_T KEY_I>; bindings = <&kp EXCL>; };
		
		combo_seven { layers = <LAYER_ID_NUMBERS>; timeout-ms = <TIMEOUT_COMBO_2>; key-positions = <KEY_A KEY_R>; bindings = <&kp N7>; };
		combo_eight { layers = <LAYER_ID_NUMBERS>; timeout-ms = <TIMEOUT_COMBO_2>; key-positions = <KEY_R KEY_T>; bindings = <&kp N8>; };
		combo_nine  { layers = <LAYER_ID_NUMBERS>; timeout-ms = <TIMEOUT_COMBO_2>; key-positions = <KEY_E KEY_Y>; bindings = <&kp N9>; };
		combo_zero  { layers = <LAYER_ID_NUMBERS>; timeout-ms = <TIMEOUT_COMBO_2>; key-positions = <KEY_Y KEY_I>; bindings = <&kp N0>; };

		/*****************************************
		 * 3 key combos
		 *****************************************/
		combo_esc              { layers = <LAYERS_ARTSEY>; timeout-ms = <TIMEOUT_COMBO_3>; key-positions = <KEY_A KEY_R KEY_O>; bindings = <&kp ESC>; };
		combo_layer_navigation { layers = <LAYERS_ARTSEY>; timeout-ms = <TIMEOUT_COMBO_3>; key-positions = <KEY_R KEY_E KEY_I>; bindings = <&tog LAYER_ID_NAVIGATION>; };

		combo_m            { layers = <LAYER_ID_BASE>; timeout-ms = <TIMEOUT_COMBO_3>; key-positions = <KEY_Y KEY_I KEY_O>; bindings = <&kp M>; };
		combo_d            { layers = <LAYER_ID_BASE>; timeout-ms = <TIMEOUT_COMBO_3>; key-positions = <KEY_A KEY_R KEY_T>; bindings = <&kp D>; };
		combo_p            { layers = <LAYER_ID_BASE>; timeout-ms = <TIMEOUT_COMBO_3>; key-positions = <KEY_E KEY_I KEY_O>; bindings = <&kp P>; };
		combo_q            { layers = <LAYER_ID_BASE>; timeout-ms = <TIMEOUT_COMBO_3>; key-positions = <KEY_A KEY_T KEY_S>; bindings = <&kp Q>; };
		combo_x            { layers = <LAYER_ID_BASE>; timeout-ms = <TIMEOUT_COMBO_3>; key-positions = <KEY_R KEY_T KEY_S>; bindings = <&kp X>; };
		combo_l            { layers = <LAYER_ID_BASE>; timeout-ms = <TIMEOUT_COMBO_3>; key-positions = <KEY_E KEY_Y KEY_I>; bindings = <&kp L>; };
		combo_single_quote { layers = <LAYER_ID_BASE>; timeout-ms = <TIMEOUT_COMBO_3>; key-positions = <KEY_A KEY_Y KEY_I>; bindings = <&kp SQT>; };
		
		/*****************************************
		 * 4 key combos
		 *****************************************/
		combo_tab             { layers = <LAYERS_ARTSEY>; timeout-ms = <TIMEOUT_COMBO_4>; key-positions = <KEY_A KEY_R KEY_T KEY_O>; bindings = <&kp TAB>; };
		combo_space           { layers = <LAYERS_ARTSEY>; timeout-ms = <TIMEOUT_COMBO_4>; key-positions = <KEY_E KEY_Y KEY_I KEY_O>; bindings = <&kp SPACE>; };
		combo_shift           { layers = <LAYERS_ARTSEY>; timeout-ms = <TIMEOUT_COMBO_4>; key-positions = <KEY_E KEY_R KEY_T KEY_S>; bindings = <&sk LSHFT>; };
		combo_layer_bt_select { layers = <LAYERS_ARTSEY>; timeout-ms = <TIMEOUT_COMBO_4>; key-positions = <KEY_A KEY_E KEY_S KEY_O>; bindings = <&tog LAYER_ID_BT_SEL>; };
		combo_bt_clr          { layers = <LAYERS_ARTSEY>; timeout-ms = <TIMEOUT_COMBO_4>; key-positions = <KEY_R KEY_Y KEY_T KEY_I>; bindings = <&bt BT_CLR>; };

		combo_z         { layers = <LAYER_ID_BASE>; timeout-ms = <TIMEOUT_COMBO_4>; key-positions = <KEY_A KEY_R KEY_T KEY_S>; bindings = <&kp Z>; };
		combo_caps_lock { layers = <LAYER_ID_BASE>; timeout-ms = <TIMEOUT_COMBO_4>; key-positions = <KEY_O KEY_I KEY_Y KEY_A>; bindings = <&kp CAPS>; };
	};
};

////////////////////////////////////////
// Keymap (main THEN artsey)
/ {
	keymap {
		compatible = "zmk,keymap";
		default_layer {
			label = "ANSI";
			bindings = <
&tildeesc &kp N1 &kp N2 &kp N3   &kp N4   &kp N5                                   &kp N6 &kp N7      &kp N8    &kp N9  &kp N0   &kp BSPC
&kp TAB   &kp Q  &kp W  &kp E    &kp R    &kp T                                    &kp Y  &kp U       &kp I     &kp O   &kp P    &kp SQT
&kp LSHFT &kp A  &kp S  &kp D    &kp F    &kp G                                    &kp H  &kp J       &kp K     &kp L   &kp SEMI &kp RET
&kp LCTRL &kp Z  &kp X  &kp C    &kp V    &kp B     &tog LAYER_ID_BASE  &none      &kp N  &kp M       &kp COMMA &kp DOT &kp FSLH &kp BSLH
                        &kp LGUI &kp LALT &kp LBKT  &kp SPACE           &kp SPACE  &mo LAYER_ID_FUNC  &kp RBKT  &kp RCTRL
			>;
		};

		function_layer {
			label = "Function";
			bindings = <
&kp F1           &kp F2     &kp F3    &kp F4      &kp F5           &kp F6                                         &kp F7             &kp F8      &kp F9           &kp F10  &kp F11  &kp F12
&kp GRAVE        &kp PG_UP  &kp HOME  &kp UP      &kp END          &trans                                         &trans             &trans      &trans           &trans   &trans   &kp DEL
&mo LAYER_ID_ALT &kp PG_DN  &kp LEFT  &kp DOWN    &kp RIGHT        &trans                                         &trans             &trans      &trans           &trans   &trans   &kp INSERT
&trans           &trans     &trans    &trans      &trans           &trans             &bt BT_NXT    &bt BT_PRV    &trans             &trans      &trans           &trans   &trans   &kp PSCRN
                                      &bt BT_CLR  &ext_power EP_ON &ext_power EP_OFF  &kp C_VOL_UP  &kp C_VOL_DN  &mo LAYER_ID_FUNC  &kp C_MUTE  &kp C_PLAY_PAUSE
			>;
		};

		alt_layer {
            label = "Alt";
			bindings = <
&kp LA(F1) &kp LA(F2) &kp LA(F3) &kp LA(F4) &kp LA(F5) &kp LA(F6) &kp LA(F7) &kp LA(F8) &kp LA(F9) &kp LA(F10) &kp LA(F11) &kp LA(F12)
&trans &trans  &trans  &trans  &trans  &trans                &trans  &trans  &trans  &trans  &trans  &trans
&trans &trans  &trans  &trans  &trans  &trans                &trans  &trans  &trans  &trans  &trans  &trans
&trans &trans  &trans  &trans  &trans  &trans  &trans  &trans  &trans  &trans  &trans  &trans  &trans  &trans
                           &trans  &trans  &trans  &trans  &trans  &trans  &trans  &trans
			>;
		};

artsey_base {
			label = "*ARTSEY*";
            bindings = <
&none &none  &none  &none  &none  &none                &none  &none  &none  &none  &none  &none
&none &layer_numbers_kp LAYER_ID_NUMBERS ARTSEY_BASE_S    &kp ARTSEY_BASE_T     &kp ARTSEY_BASE_R     &layer_parentheticals_kp LAYER_ID_PARENTHETICALS ARTSEY_BASE_A &kp MINUS                &none  &none  &none  &none  &none  &none
&none &layer_custom_kp LAYER_ID_CUSTOM ARTSEY_BASE_O      &kp ARTSEY_BASE_I     &kp ARTSEY_BASE_Y     &layer_symbols_kp LAYER_ID_SYMBOLS ARTSEY_BASE_E               &sk LSHFT                &none  &none  &none  &none  &none  &none
&none &ctrl_alt_kp LALT RCTRL                             &kp AT                &kp DEL               &kp EQUAL                                                      &kp TAB  &tog LAYER_ID_BASE  &none  &none  &none  &none  &none  &none  &none
                           &none  &mo LAYER_ID_BIG_SYM                                &kp SPACE  &none  &none  &none  &none
			>;
		};
        artsey_numbers {
			label = "Number";
            bindings = <
&none &none  &none  &none  &none  &none                &none  &none  &none  &none  &none  &none
&none &mo LAYER_ID_NUMBERS                        &kp N3    &kp N2    &kp N1  &none                &none  &none  &none  &none  &none  &none
&none &none                                       &kp N6    &kp N5    &kp N4  &none                &none  &none  &none  &none  &none  &none
&none &none  &none  &none  &none  &none  &none  &none  &none  &none  &none  &none  &none  &none
                           &none  &none  &none  &none  &none  &none  &none  &none
            >;
		};
        artsey_symbols {
			label = "Symbol";
            bindings = <
&none &none  &none  &none  &none  &none                &none  &none  &none  &none  &none  &none
&none &kp GRAVE                                   &kp SEMI  &kp BSLH  &kp EXCL  &none                &none  &none  &none  &none  &none  &none
&none &kp EQUAL                                   &kp MINUS &kp QMARK &mo LAYER_ID_SYMBOLS  &none                &none  &none  &none  &none  &none  &none
&none &none  &none  &none  &none  &none  &none  &none  &none  &none  &none  &none  &none  &none
                           &none  &none  &none  &none  &none  &none  &none  &none
            >;
		};
        artsey_parentheticals {
			label = "Paren";
            bindings = <
&none &none  &none  &none  &none  &none                &none  &none  &none  &none  &none  &none
&none &kp LBRC                                    &kp LPAR  &kp RPAR  &mo LAYER_ID_PARENTHETICALS  &none                &none  &none  &none  &none  &none  &none
&none &kp RBRC                                    &kp LBKT  &kp RBKT  &none  &none                &none  &none  &none  &none  &none  &none
&none &none  &none  &none  &none  &none  &none  &none  &none  &none  &none  &none  &none  &none
                           &none  &none  &none  &none  &none  &none  &none  &none
            >;
		};
        artsey_navigation {
			label = "Nav";
            bindings = <
&none &none  &none  &none  &none  &none                &none  &none  &none  &none  &none  &none
&none &kp PG_UP                                   &kp HOME  &kp UP    &kp END  &none                &none  &none  &none  &none  &none  &none
&none &kp PG_DN                                   &kp LEFT  &kp DOWN  &kp RIGHT  &none                &none  &none  &none  &none  &none  &none
&none &none  &none  &none  &none  &none  &none  &none  &none  &none  &none  &none  &none  &none
                           &none  &none  &none  &none  &none  &none  &none  &none
            >;
		};
        artsey_bt {
			label = "BT";
            bindings = <
&none &none  &none  &none  &none  &none                &none  &none  &none  &none  &none  &none
&none ARTSEY_BT_TOP    &bt BT_SEL 2 &bt BT_SEL 1 &bt BT_SEL 0  &none                &none  &none  &none  &none  &none  &none
&none ARTSEY_BT_BOTTOM &bt BT_SEL 5 &bt BT_SEL 4 &bt BT_SEL 3  &none                &none  &none  &none  &none  &none  &none
&none &none  &none  &none  &none  &none  &none  &none  &none  &none  &none  &none  &none  &none
                           &none  &none  &none  &none  &none  &none  &none  &none
            >;
		};
        artsey_custom {
			label = "Custom";
            bindings = <
&none &none  &none  &none  &none  &none                &none  &none  &none  &none  &none  &none
&none &none               &kp C_VOL_UP  &kp INS   &kp C_MUTE  &none                &none  &none  &none  &none  &none  &none
&none &mo LAYER_ID_CUSTOM &kp C_VOL_DN  &kp PSCRN &sk RSHFT  &none                &none  &none  &none  &none  &none  &none
&none &none  &none  &none  &none  &none  &none  &none  &none  &none  &none  &none  &none  &none
                           &none  &none  &none  &none  &none  &none  &none  &none
            >;
		};
        big_artsey_symbol {
			label = "*Symbol*";
            bindings = <
&none &none  &none  &none  &none  &none                &none  &none  &none  &none  &none  &none
&none &kp CARET &kp LBRC &kp RBRC &kp HASH  &kp GRAVE                &none  &none  &none  &none  &none  &none
&none &kp AMPS  &kp LPAR &kp RPAR &kp DLLR  &kp BSLH                &none  &none  &none  &none  &none  &none
&none &kp ASTRK &kp LBKT &kp RBKT &kp PRCNT &kp PIPE  &none  &none  &none  &none  &none  &none  &none  &none
                           &none  &none &kp SEMI  &none    &none  &none  &none  &none
            >;
		};
        big_artsey_function {
			label = "*Func*";
            bindings = <
&none &none  &none  &none  &none  &none                &none  &none  &none  &none  &none  &none
&none &kp F4  &kp F3  &kp F2  &kp F1  &none                &none  &none  &none  &none  &none  &none
&none &kp F8  &kp F7  &kp F6  &kp F5  &none                &none  &none  &none  &none  &none  &none
&none &kp F12 &kp F11 &kp F10 &kp F9  &none  &none  &none  &none  &none  &none  &none  &none  &none
                           &none  &none  &none  &none  &none  &none  &none  &none
            >;
		};
	};
};
