#include QMK_KEYBOARD_H
#include "keymap_bepo.h"
#define BASE 0
#define FN 1
#define MOUSE 2
#define NUMS 3
#define SWAP 4
#define SYSLEDS 5
#define TAP_MACRO 0
#define ___ KC_TRANSPARENT
#define XXX KC_NO
#define ESC_FN    LT(FN, KC_ESC)        
#define M_RSFT    MT(MOD_RSFT, BP_M)    
#define W_RCTL    MT(MOD_RCTL, BP_W)    
#define SPC_RALT  MT(MOD_RALT, KC_SPC)  
#define PERC_FN    LT(FN, BP_PERC)      
#define MK_CUT    LSFT(KC_DEL)  
#define MK_COPY   LCTL(KC_INS)  
#define MK_PASTE  LSFT(KC_INS)  
enum {
          DYNAMIC_MACRO_RANGE = SAFE_RANGE,
};
#include "dynamic_macro.h"
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
    [BASE] = LAYOUT_ergodox(
    
    BP_DLR,   BP_DQOT, BP_LGIL, BP_RGIL, BP_LPRN, BP_RPRN, KC_DEL,
    KC_TAB,   BP_B,    BP_ECUT, BP_P,    BP_O,    BP_EGRV, KC_BSPC,
    KC_LSFT,  BP_A,    BP_U,    BP_I,    BP_E,    BP_COMM,
    KC_LCTRL, BP_AGRV, BP_Y,    BP_X,    BP_DOT,  BP_K,    KC_ENT,
    ESC_FN,   BP_ECRC, KC_LGUI, KC_LALT, SPC_RALT,
                                                          TT(SWAP), KC_MNXT,
                                                                    KC_MPLY,
                                                  TT(FN), TT(NUMS), KC_MPRV,
    
        KC_DEL,  BP_AT,   BP_PLUS,  BP_MINS, BP_SLSH,     BP_ASTR, BP_EQL,
        KC_BSPC, BP_DCRC, BP_V,     BP_D,    BP_L,        BP_J,    BP_Z,
                 BP_C,    BP_T,     BP_S,    BP_R,        BP_N,    M_RSFT,
        KC_ENT,  BP_APOS, BP_Q,     BP_G,    BP_H,        BP_F,    W_RCTL,
                          SPC_RALT, KC_LALT, TT(SYSLEDS), BP_CCED, PERC_FN,
    KC_LEFT, KC_RIGHT,
    KC_UP,
    KC_DOWN, TD(TAP_MACRO), TT(MOUSE)),
    [FN] = LAYOUT_ergodox(
    
    KC_SLEP, KC_F1, KC_F2,  KC_F3,   KC_F4,    KC_F5,    ___,
    ___,     ___,   ___,    ___,     ___,      ___,      ___,
    ___,     ___,   ___,    ___,     ___,      KC_LSFT,
    ___,     ___,   MK_CUT, MK_COPY, MK_PASTE, KC_LCTRL, ___,
    ___,     ___,   ___,    ___,     ___,
                                                     ___, KC_VOLU,
                                                          KC_VOLD,
                                             ___,    ___, KC_MUTE,
    
        ___, KC_F6, KC_F7,   KC_F8,   KC_F9,    KC_F10,  KC_F11,
        ___, ___,   KC_HOME, KC_UP,   KC_END,   KC_PGUP, KC_F12,
             ___,   KC_LEFT, KC_DOWN, KC_RIGHT, KC_PGDN, ___,
        ___, ___,   ___,     ___,     ___,      ___,     ___,
                    ___,     ___,     ___,      ___,     ___,
    KC_HOME, KC_END,
    KC_PGUP,
    KC_PGDN, ___,    ___),
        
    [MOUSE] = LAYOUT_ergodox(
    
    KC_SLEP, KC_F1, KC_F2,   KC_F3,   KC_F4,    KC_F5,    ___,
    ___,     ___,   KC_BTN4, KC_MS_U, KC_BTN5,  ___,      ___,
    ___,     ___,   KC_MS_L, KC_MS_D, KC_MS_R,  KC_LSFT,
    ___,     ___,   MK_CUT,  MK_COPY, MK_PASTE, KC_LCTRL, ___,
    ___,     ___,   ___,     ___,     ___,
                                                  ___, KC_VOLU,
                                                       KC_VOLD,
                                             ___, ___, KC_MUTE,
    
         ___, KC_F6, KC_F7,   KC_F8,   KC_F9,   KC_F10, KC_F11,
         ___, ___,   XXX,     KC_WH_U, XXX,     XXX,    KC_F12,
              ___,   KC_WH_L, KC_WH_D, KC_WH_R, XXX,    ___,
         ___, ___,   KC_ACL0, KC_ACL1, KC_ACL2, ___,    ___,
                     KC_BTN1, KC_BTN2, KC_BTN3, ___,    ___,
    ___, ___,
    ___,
    ___, ___, ___),
    [NUMS] = LAYOUT_ergodox(
    
    KC_PSCR, KC_INS, KC_PAUS,    ___,     ___,      ___, ___,
    ___,     ___,    ___,        ___,     ___,      ___, ___,
    ___,     ___,    ___,        ___,     ___,      ___,
    ___,     ___,    MK_CUT,     MK_COPY, MK_PASTE, ___, ___,
    ___,     ___,    ___,        ___,     ___,
                                              ___, ___,
                                                   ___,
                                         ___, ___, ___,
    
         ___,     ___,     ___,   ___,   ___,     ___,     KC_NLCK,
         ___,     KC_PEQL, KC_P7, KC_P8, KC_P9,   KC_PMNS, KC_SLCK,
                  KC_PCMM, KC_P4, KC_P5, KC_P6,   KC_PPLS, ___,
         KC_PENT, KC_P0,   KC_P1, KC_P2, KC_P3,   KC_PAST, ___,
                           ___,   ___,   ___,     KC_PSLS, ___,
    ___, ___,
    ___,
    ___, ___, ___),
        [SWAP] = LAYOUT_ergodox(
    
    ___, ___, ___, ___, ___, ___, ___,
    ___, ___, ___, ___, ___, ___, ___,
    ___, ___, ___, ___, ___, ___,
    ___, ___, ___, ___, ___, ___, ___,
    ___, ___, ___, ___, ___,
                             TT(SWAP), ___,
                                       ___,
                             ___, ___, ___,
    
         ___, ___, ___, ___, ___, ___, ___,
         ___, ___, ___, ___, ___, ___, ___,
              ___, ___, ___, ___, ___, ___,
         ___, ___, ___, ___, ___, ___, ___,
                   ___, ___, ___, ___, ___,
    ___, TT(SWAP),
    ___,
    ___, ___,      ___),
        [SYSLEDS] = LAYOUT_ergodox(
    
    ___, ___, ___, ___, ___, ___, ___,
    ___, ___, ___, ___, ___, ___, ___,
    ___, ___, ___, ___, ___, ___,
    ___, ___, ___, ___, ___, ___, ___,
    ___, ___, ___, ___, ___,
                                  ___, ___,
                                       ___,
                             ___, ___, ___,
    
         ___, ___, ___, ___, ___,         ___, ___,
         ___, ___, ___, ___, ___,         ___, ___,
              ___, ___, ___, ___,         ___, ___,
         ___, ___, ___, ___, ___,         ___, ___,
                   ___, ___, TT(SYSLEDS), ___, ___,
    ___, ___,
    ___,
    ___, ___, ___),
};
static bool is_macro1_recording = false;
static uint32_t current_layer_state = 0;
uint32_t layer_state_set_user(uint32_t state);
void macro_tapdance_fn(qk_tap_dance_state_t *state, void *user_data) {
  uint16_t keycode;
  keyrecord_t record;
  dprintf("macro_tap_dance_fn %d\n", state->count);
  if (is_macro1_recording) {
    keycode = DYN_REC_STOP;
    is_macro1_recording = false;
    layer_state_set_user(current_layer_state);
  } else if (state->count == 1) {
    keycode = DYN_MACRO_PLAY1;
  } else {
    keycode = DYN_REC_START1;
    is_macro1_recording = true;
    layer_state_set_user(current_layer_state);
  }
  record.event.pressed = true;
  process_record_dynamic_macro(keycode, &record);
  record.event.pressed = false;
  process_record_dynamic_macro(keycode, &record);
}
qk_tap_dance_action_t tap_dance_actions[] = {
    [TAP_MACRO] = ACTION_TAP_DANCE_FN(macro_tapdance_fn),
};
bool process_record_user(uint16_t keycode, keyrecord_t *record) {
  if (keycode != TD(TAP_MACRO)) {
                        if (!process_record_dynamic_macro(keycode, record)) {
      return false;
    }
  }
  return true; }
void matrix_init_user(void) {
  ergodox_right_led_1_off();
  ergodox_right_led_2_off();
  ergodox_right_led_3_off();
};
void matrix_scan_user(void) {
};
static uint8_t sys_led_state = 0;
static const uint8_t sys_led_mask_num_lock = 1 << USB_LED_NUM_LOCK;
static const uint8_t sys_led_mask_caps_lock = 1 << USB_LED_CAPS_LOCK;
static const uint8_t sys_led_mask_scroll_lock = 1 << USB_LED_SCROLL_LOCK;
static const uint8_t max_led_value = 20;
#define LAYER_ON(layer) (current_layer_state & (1<<layer))
void led_1_on(void) {
  ergodox_right_led_1_on();
  ergodox_right_led_1_set(max_led_value);
}
void led_2_on(void) {
  ergodox_right_led_2_on();
  ergodox_right_led_2_set(max_led_value);
}
void led_3_on(void) {
  ergodox_right_led_3_on();
  ergodox_right_led_3_set(max_led_value);
}
void led_1_off(void) {
  ergodox_right_led_1_off();
}
void led_2_off(void) {
  ergodox_right_led_2_off();
}
void led_3_off(void) {
  ergodox_right_led_3_off();
}
void led_set_user(uint8_t usb_led) {
  sys_led_state = usb_led;
  if (LAYER_ON(SYSLEDS)) {
    if (sys_led_state & sys_led_mask_caps_lock) {
      led_1_on();
    } else {
      led_1_off();
    }
    if (sys_led_state & sys_led_mask_num_lock) {
      led_2_on();
    } else {
      led_2_off();
    }
    if (sys_led_state & sys_led_mask_scroll_lock) {
      led_3_on();
    } else {
      led_3_off();
    }
  }
}
uint32_t layer_state_set_user(uint32_t state) {
  current_layer_state = state;
  swap_hands = LAYER_ON(SWAP);
  if (is_macro1_recording) {
    led_1_on();
    led_2_on();
    led_3_on();
    return state;
  }
  if (LAYER_ON(SYSLEDS)) {
    led_set_user(sys_led_state);
    return state;
  }
  if (LAYER_ON(FN)) {
    led_1_on();
  } else {
    led_1_off();
  }
  if (LAYER_ON(NUMS)) {
    led_2_on();
  } else {
    led_2_off();
  }
  if (LAYER_ON(MOUSE)) {
    led_3_on();
  } else {
    led_3_off();
  }
  return state;
};