// Copyright 2024 binaryDiv (@binaryDiv)
// SPDX-License-Identifier: GPL-2.0-or-later

#include QMK_KEYBOARD_H

// Define layer names for better readability
enum layer_names {
    // Base layer
    L_BASE,

    // "Code" key: Moving the cursor around via WASD, F-keys on number keys, etc.
    L_CODE,

    // Fn / keyboard control layer: Used for keyboard configuration
    L_FN,
};

// Custom keycodes
enum custom_keycodes {
    // Macro to select the current word (Ctrl-Left, Shift-Ctrl-Right)
    MACRO_SELECT_WORD = SAFE_RANGE,
};

const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
    // Base layer
    [L_BASE] = LAYOUT_ortho_6x13(
        KC_ESC,        KC_F1,   KC_F2,   KC_F3,       KC_F4,       KC_F5,    KC_F6,   KC_F7,        KC_F8,    _______,       _______,      _______,         KC_KB_MUTE,
        KC_GRAVE,      KC_1,    KC_2,    KC_3,        KC_4,        KC_5,     KC_6,    KC_7,         KC_8,     KC_9,          KC_0,         KC_MINUS,        KC_EQUAL,
        KC_TAB,        KC_Q,    KC_W,    KC_E,        KC_R,        KC_T,     KC_Y,    KC_U,         KC_I,     KC_O,          KC_P,         KC_LEFT_BRACKET, KC_RIGHT_BRACKET,
        KC_ESC,        KC_A,    KC_S,    KC_D,        KC_F,        KC_G,     KC_H,    KC_J,         KC_K,     KC_L,          KC_SEMICOLON, KC_QUOTE,        KC_BACKSLASH,
        KC_LEFT_SHIFT, KC_HOME, KC_Z,    KC_X,        KC_C,        KC_V,     KC_B,    KC_N,         KC_M,     KC_COMMA,      KC_DOT,       KC_SLASH,        KC_RIGHT_SHIFT,
        KC_LEFT_CTRL,  KC_END,  KC_LGUI, KC_LEFT_ALT, OSL(L_CODE), KC_SPACE, _______, KC_BACKSPACE, KC_ENTER, OSM(MOD_RALT), KC_DELETE,    MO(L_FN),        KC_RIGHT_CTRL
    ),

    // "Code" key layer
    [L_CODE] = LAYOUT_ortho_6x13(
        _______, DM_PLY1,       DM_PLY2,           _______,        _______,  _______, _______, _______,       KC_PRINT_SCREEN, _______,             _______,              _______, _______,
        KC_ESC,  KC_F1,         KC_F2,             KC_F3,          KC_F4,    KC_F5,   KC_F6,   KC_F7,         KC_F8,           KC_F9,               KC_F10,               KC_F11,  KC_F12,
        _______, KC_HOME,       KC_UP,             KC_END,         KC_PGUP,  _______, _______, KC_UNDERSCORE, KC_EQUAL,        KC_LEFT_BRACKET,     KC_RIGHT_BRACKET,     _______, _______,
        _______, KC_LEFT,       KC_DOWN,           KC_RIGHT,       KC_PGDN,  _______, _______, KC_MINUS,      KC_PLUS,         KC_LEFT_CURLY_BRACE, KC_RIGHT_CURLY_BRACE, _______, _______,
        _______, LCTL(KC_LEFT), MACRO_SELECT_WORD, LCTL(KC_RIGHT), KC_ENTER, _______, _______, _______,       _______,         _______,             _______,              _______, _______,
        _______, _______,       _______,           _______,        _______,  _______, _______, _______,       _______,         _______,             _______,              _______, _______
    ),

    // "Fn" key layer
    [L_FN] = LAYOUT_ortho_6x13(
        DM_RSTP, DM_REC1, DM_REC2, _______, _______, _______, _______, _______, _______, _______, _______, _______,         _______,
        _______, _______, _______, _______, _______, _______, _______, _______, _______, OS_TOGG, _______, RGB_MOD,         RGB_TOG,
        _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, RGB_SPD,         RGB_SPI,
        _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,         _______,
        _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, QK_CLEAR_EEPROM, QK_REBOOT,
        _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,         QK_BOOTLOADER
    )
};

// Define mapping for rotary encoder
#if defined(ENCODER_MAP_ENABLE)
const uint16_t PROGMEM encoder_map[][NUM_ENCODERS][NUM_DIRECTIONS] = {
    // Base layer: Volume control
    [L_BASE] = {
        ENCODER_CCW_CW(KC_KB_VOLUME_DOWN, KC_KB_VOLUME_UP)
    },
    // Code layer: Scroll wheel
    [L_CODE] = {
        ENCODER_CCW_CW(KC_MS_WH_UP, KC_MS_WH_DOWN)
    },
    // Fn layer: RGB LED brightness control
    [L_FN] = {
        ENCODER_CCW_CW(RGB_VAD, RGB_VAI)
    }
};
#endif

bool process_record_user(uint16_t keycode, keyrecord_t *record) {
    switch (keycode) {
        case MACRO_SELECT_WORD:
            // Run macro when keycode is pressed
            if (record->event.pressed) {
                // Select word
                SEND_STRING(SS_LCTL(SS_TAP(X_LEFT)) SS_LSFT(SS_LCTL(SS_TAP(X_RIGHT))));
            }
            break;
    }
    return true;
}
