#include QMK_KEYBOARD_H
#define KC_FN1 MO(_FN)
#define KC_FN2 LT(_FN, KC_CAPS)
#define KC_BLUP BL_INC   
#define KC_BLDN BL_DEC   
#define KC_BLTOG BL_TOGG 
#define KC_TERM TERM_ON  
#define KC_REC1 DM_REC1  
#define KC_PLY1 DM_PLY1  
#define KC_REC2 DM_REC2  
#define KC_PLY2 DM_PLY2  
#define KC_RSTP DM_RSTP  
enum {
    _QWERTY,
    _FN
};
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
[_QWERTY] = LAYOUT_68_ansi( 
    KC_GESC, KC_1  , KC_2  , KC_3  , KC_4  , KC_5  , KC_6  , KC_7  , KC_8  , KC_9  , KC_0  ,KC_MINS,KC_EQL ,  KC_BSPC  ,  KC_INS ,KC_PGUP, 
     KC_TAB  , KC_Q  , KC_W  , KC_E  , KC_R  , KC_T  , KC_Y  , KC_U  , KC_I  , KC_O  , KC_P  ,KC_LBRC,KC_RBRC, KC_BSLS ,  KC_DEL ,KC_PGDN, 
      KC_FN2   , KC_A  , KC_S  , KC_D  , KC_F  , KC_G  , KC_H  , KC_J  , KC_K  , KC_L  ,KC_SCLN,KC_QUOT,  KC_ENTER  ,         
       KC_LSFT   , KC_Z  , KC_X  , KC_C  , KC_V  , KC_B  , KC_N  , KC_M  ,KC_COMM,KC_DOT ,KC_SLSH,    KC_RSFT    ,   KC_UP ,  
    KC_LCTL ,KC_LGUI ,KC_LALT ,             KC_SPACE             ,KC_RALT , KC_FN1 ,KC_RCTL ,   KC_LEFT,KC_DOWN,KC_RGHT  ),
[_FN] = LAYOUT_68_ansi( 
    KC_GRV , 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_RSTP  ,  KC_PSCR,KC_HOME, 
  _______ ,KC_PLY1,KC_PLY2,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS, KC_7  , KC_8  , KC_9  ,KC_BLDN,KC_BLUP,KC_BLTOG ,KC_TRNS  ,KC_END , 
    _______ ,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS, KC_4  , KC_5  , KC_6  ,KC_TRNS,   KC_TERM  ,         
    _______   ,KC_REC1,KC_REC2,KC_TRNS,KC_TRNS,KC_MSTP,KC_TRNS,KC_MUTE, KC_1  , KC_2  , KC_3  ,KC_TRNS        ,  KC_VOLU,  
  _______,KC_TRNS ,KC_TRNS ,         KC_MPLY              ,  KC_0  ,KC_TRNS ,KC_TRNS ,   KC_MPRV,KC_VOLD,KC_MNXT  )
};
void keyboard_post_init_user(void) {
    backlight_level(2);
}
float cie1931(float x) {
    x *= 100.0 / BACKLIGHT_LEVELS;
    float y;
    if (x < 8) {
        y = x / 902.3;
    } else {
        y = (x + 16.0) / 116.0;
        y = y * y * y;
    }
    return round(y * 255);
}
void backlight_init_ports(void) {
    setPinOutput(BACKLIGHT_PIN);
    writePinLow(BACKLIGHT_PIN);
    TCCR1A = _BV(COM1A1) | _BV(WGM11);
    TCCR1B = _BV(WGM13) | _BV(WGM12) | _BV(CS10);
    ICR1 = 0xFFU;  }
void backlight_set(uint8_t level) {
    if (level > BACKLIGHT_LEVELS) {
        level = BACKLIGHT_LEVELS;
    }
    if (level == 0) {
        TCCR1A &= ~(_BV(COM1A1));      } else {
        TCCR1A |= _BV(COM1A1);      }
    OCR1A = cie1931(level);
}
void led_blink(void) {
    backlight_toggle();
    wait_ms(25);
    backlight_toggle();
}
void dynamic_macro_record_start_user(void) {
    led_blink();
}
void dynamic_macro_play_user(int8_t direction) {
    led_blink();
}
void dynamic_macro_record_key_user(int8_t direction, keyrecord_t *record) {
    led_blink();
}
void dynamic_macro_record_end_user(int8_t direction) {
    led_blink();
}
void led_set_user(uint8_t usb_led) {
            static bool prev_is_caps_on;
    bool is_caps_on = IS_LED_ON(usb_led, USB_LED_CAPS_LOCK);
    if (prev_is_caps_on != is_caps_on) {
        prev_is_caps_on = is_caps_on;
        if (is_caps_on) {
            backlight_set(BACKLIGHT_LEVELS / 2);
        } else {
            if (is_backlight_enabled()) {
                backlight_set(get_backlight_level());
            } else {
                backlight_set(0);
            }
        }
    }
        if (IS_LED_ON(usb_led, USB_LED_CAPS_LOCK)) {
                setPinOutput(B0);
        writePinLow(B0);
        setPinOutput(D5);
        writePinLow(D5);
    } else {
                setPinInput(B0);
        setPinInput(D5);
    }
}
static uint32_t timer;
static bool is_idle;
void matrix_scan_user() {
        if (!is_idle) {
        if (timer_elapsed32(timer) >= (uint32_t) BACKLIGHT_IDLE_TIMEOUT * 1000) {
            is_idle = true;
                                    backlight_set(0);
        }
    }
}
bool process_record_user(uint16_t keycode, keyrecord_t *record) {
        timer = timer_read32();
        if (is_idle) {
        is_idle = false;
                if (is_backlight_enabled()) {
                        backlight_set(get_backlight_level());
        }
    }
    return true;
}