package org.jabref.gui.keyboard;

import org.jabref.logic.l10n.Localization;

/// @implNote Cannot be sorted alphabetically, as [KeyBindingRepository#getKeyCombination(KeyBinding)] iterates over the enum in order and returns the first match.
/// Use `shortcut` for OS independent mapping of `ctrl` on Windows and `cmd`(meta)` on macOS
/// See also the description at [javafx.scene.input.KeyCombination]
public enum KeyBinding {
    EDITOR_DELETE("Delete", Localization.lang("Delete text"), "", KeyBindingCategory.EDITOR),
    // DELETE BACKWARDS = Rubout
    EDITOR_BACKWARD("Move caret left", Localization.lang("Move caret left"), "", KeyBindingCategory.EDITOR),
    EDITOR_FORWARD("Move caret right", Localization.lang("Move caret right"), "", KeyBindingCategory.EDITOR),
    EDITOR_WORD_BACKWARD("Move caret to previous word", Localization.lang("Move caret to previous word"), "", KeyBindingCategory.EDITOR),
    EDITOR_WORD_FORWARD("Move caret to next word", Localization.lang("Move caret to next word"), "", KeyBindingCategory.EDITOR),
    EDITOR_BEGINNING("Move caret to beginning of line", Localization.lang("Move caret to beginning of line"), "", KeyBindingCategory.EDITOR),
    EDITOR_END("Move caret to  of line", Localization.lang("Move caret to end of line"), "", KeyBindingCategory.EDITOR),
    EDITOR_BEGINNING_DOC("Move caret to beginning of text", Localization.lang("Move the caret to the beginning of text"), "", KeyBindingCategory.EDITOR),
    EDITOR_END_DOC("Move caret to end of text", Localization.lang("Move the caret to the end of text"), "", KeyBindingCategory.EDITOR),
    EDITOR_UP("Move caret up", Localization.lang("Move the caret up"), "", KeyBindingCategory.EDITOR),
    EDITOR_DOWN("Move caret down", Localization.lang("Move the caret down"), "", KeyBindingCategory.EDITOR),
    EDITOR_CAPITALIZE("Capitalize word", Localization.lang("Capitalize current word"), "", KeyBindingCategory.EDITOR),
    EDITOR_LOWERCASE("Lowercase word", Localization.lang("Make current word lowercase"), "", KeyBindingCategory.EDITOR),
    EDITOR_UPPERCASE("Uppercase word", Localization.lang("Make current word uppercase"), "", KeyBindingCategory.EDITOR),
    EDITOR_KILL_LINE("Remove all characters caret to end of line", Localization.lang("Remove line after caret"), "", KeyBindingCategory.EDITOR),
    EDITOR_KILL_WORD("Remove characters until next word", Localization.lang("Remove characters until next word"), "", KeyBindingCategory.EDITOR),
    EDITOR_KILL_WORD_BACKWARD("Characters until previous word", Localization.lang("Remove the current word backwards"), "", KeyBindingCategory.EDITOR),

    AUTOGENERATE_CITATION_KEYS("Autogenerate citation keys", Localization.lang("Autogenerate citation keys"), "shortcut+G", KeyBindingCategory.QUALITY),
    ACCEPT("Accept", Localization.lang("Accept"), "shortcut+ENTER", KeyBindingCategory.EDIT),
    AUTOMATICALLY_LINK_FILES("Automatically link files", Localization.lang("Automatically set file links"), "F7", KeyBindingCategory.QUALITY),
    CHECK_INTEGRITY("Check integrity", Localization.lang("Check integrity"), "shortcut+F8", KeyBindingCategory.QUALITY),
    CHECK_CONSISTENCY("Check consistency", Localization.lang("Check consistency"), "shortcut+F9", KeyBindingCategory.QUALITY),
    CLEANUP("Clean up", Localization.lang("Clean up entries"), "alt+F8", KeyBindingCategory.QUALITY),
    CLOSE_DATABASE("Close library", Localization.lang("Close library"), "shortcut+W", KeyBindingCategory.FILE),
    CLOSE("Close dialog", Localization.lang("Close dialog"), "Esc", KeyBindingCategory.VIEW),
    COPY("Copy", Localization.lang("Copy"), "shortcut+C", KeyBindingCategory.EDIT),
    COPY_TITLE("Copy title", Localization.lang("Copy title"), "shortcut+shift+alt+T", KeyBindingCategory.EDIT),
    JUMP_TO_FIELD("Jump to field", Localization.lang("Jump to field"), "shortcut+J", KeyBindingCategory.EDIT),

    // We migrated from "Copy \\cite{citation key}" to "Copy citation key with configured cite command", therefore we keep the "old string" for backwards comppatibility
    COPY_CITE_CITATION_KEY("Copy \\cite{citation key}", Localization.lang("Copy citation key with configured cite command"), "shortcut+K", KeyBindingCategory.EDIT),

    COPY_CITATION_KEY("Copy citation key", Localization.lang("Copy citation key"), "shortcut+shift+K", KeyBindingCategory.EDIT),
    COPY_CITATION_KEY_AND_TITLE("Copy citation key and title", Localization.lang("Copy citation key and title"), "shortcut+shift+alt+K", KeyBindingCategory.EDIT),
    COPY_CITATION_KEY_AND_LINK("Copy citation key and link", Localization.lang("Copy citation key and link"), "shortcut+alt+K", KeyBindingCategory.EDIT),
    COPY_PREVIEW("Copy preview", Localization.lang("Copy preview"), "shortcut+shift+C", KeyBindingCategory.VIEW),
    CUT("Cut", Localization.lang("Cut"), "shortcut+X", KeyBindingCategory.EDIT),
    // We have to put Entry Editor Previous before, because otherwise the decrease font size is found first
    ENTRY_EDITOR_PREVIOUS_PANEL_2("Entry editor, previous panel 2", Localization.lang("Entry editor, previous panel 2"), "shortcut+MINUS", KeyBindingCategory.VIEW),
    DELETE_ENTRY("Delete entry", Localization.lang("Delete entry"), "DELETE", KeyBindingCategory.BIBTEX),
    PERFORM_OCR("Perform OCR", Localization.lang("Perform OCR"), "shortcut+alt+r", KeyBindingCategory.FILE),
    DEFAULT_DIALOG_ACTION("Execute default action in dialog", Localization.lang("Execute default action in dialog"), "shortcut+ENTER", KeyBindingCategory.VIEW),
    DOWNLOAD_FULL_TEXT("Download full text documents", Localization.lang("Download full text documents"), "alt+F7", KeyBindingCategory.QUALITY),
    OPEN_CLOSE_ENTRY_EDITOR("Open / close entry editor", Localization.lang("Open / close entry editor"), "shortcut+E", KeyBindingCategory.VIEW),
    EXPORT("Export", Localization.lang("Export"), "shortcut+alt+e", KeyBindingCategory.FILE),
    EXPORT_SELECTED("Export Selected", Localization.lang("Export selected entries"), "shortcut+shift+e", KeyBindingCategory.FILE),
    EDIT_STRINGS("Edit strings", Localization.lang("Edit strings"), "shortcut+T", KeyBindingCategory.BIBTEX),
    ENTRY_EDITOR_NEXT_ENTRY("Entry editor, next entry", Localization.lang("Entry editor, next entry"), "alt+DOWN", KeyBindingCategory.VIEW),
    ENTRY_EDITOR_NEXT_PANEL("Entry editor, next panel", Localization.lang("Entry editor, next panel"), "shortcut+TAB", KeyBindingCategory.VIEW),
    ENTRY_EDITOR_NEXT_PANEL_2("Entry editor, next panel 2", Localization.lang("Entry editor, next panel 2"), "shortcut+PLUS", KeyBindingCategory.VIEW),
    ENTRY_EDITOR_PREVIOUS_ENTRY("Entry editor, previous entry", Localization.lang("Entry editor, previous entry"), "alt+UP", KeyBindingCategory.VIEW),
    ENTRY_EDITOR_PREVIOUS_PANEL("Entry editor, previous panel", Localization.lang("Entry editor, previous panel"), "shortcut+shift+TAB", KeyBindingCategory.VIEW),
    FILE_LIST_EDITOR_MOVE_ENTRY_DOWN("File list editor, move entry down", Localization.lang("File list editor, move entry down"), "shortcut+DOWN", KeyBindingCategory.VIEW),
    FILE_LIST_EDITOR_MOVE_ENTRY_UP("File list editor, move entry up", Localization.lang("File list editor, move entry up"), "shortcut+UP", KeyBindingCategory.VIEW),
    FIND_UNLINKED_FILES("Search for unlinked local files", Localization.lang("Search for unlinked local files"), "shift+F7", KeyBindingCategory.QUALITY),
    FOCUS_ENTRY_TABLE("Focus entry table", Localization.lang("Focus entry table"), "alt+1", KeyBindingCategory.VIEW),
    FOCUS_GROUP_LIST("Focus group list", Localization.lang("Focus group list"), "alt+s", KeyBindingCategory.VIEW),
    HELP("Help", Localization.lang("Help"), "F1", KeyBindingCategory.FILE),
    IMPORT_INTO_CURRENT_LIBRARY("Import into current library...", Localization.lang("Import into current library..."), "shortcut+I", KeyBindingCategory.FILE),
    IMPORT_INTO_NEW_LIBRARY("Import into new library...", Localization.lang("Import into new library..."), "shortcut+alt+I", KeyBindingCategory.FILE),
    MERGE_ENTRIES("Merge entries", Localization.lang("Merge entries"), "shortcut+M", KeyBindingCategory.TOOLS),

    BACK("Back", Localization.lang("Back"), "alt+LEFT", KeyBindingCategory.VIEW),
    FORWARD("Forward", Localization.lang("Forward"), "alt+RIGHT", KeyBindingCategory.VIEW),

    ADD_ENTRY("Add entry", Localization.lang("Add entry"), "shortcut+N", KeyBindingCategory.BIBTEX),
    ADD_ENTRY_IDENTIFIER("Enter identifier", Localization.lang("Enter identifier"), "shortcut+alt+shift+N", KeyBindingCategory.BIBTEX),
    ADD_ENTRY_PLAINTEXT("Interpret citations", Localization.lang("Interpret citations"), "shortcut+shift+N", KeyBindingCategory.BIBTEX),
    NEW_ARTICLE("New article", Localization.lang("New article"), "shortcut+shift+A", KeyBindingCategory.BIBTEX),
    NEW_BOOK("New book", Localization.lang("New book"), "shortcut+shift+B", KeyBindingCategory.BIBTEX),
    NEW_INBOOK("New inbook", Localization.lang("New inbook"), "shortcut+shift+I", KeyBindingCategory.BIBTEX),
    NEW_MASTERSTHESIS("New mastersthesis", Localization.lang("New mastersthesis"), "shortcut+shift+M", KeyBindingCategory.BIBTEX),
    NEW_PHDTHESIS("New phdthesis", Localization.lang("New phdthesis"), "shortcut+shift+T", KeyBindingCategory.BIBTEX),
    NEW_PROCEEDINGS("New proceedings", Localization.lang("New proceedings"), "shortcut+shift+P", KeyBindingCategory.BIBTEX),
    NEW_UNPUBLISHED("New unpublished", Localization.lang("New unpublished"), "shortcut+shift+U", KeyBindingCategory.BIBTEX),
    NEW_TECHREPORT("New technical report", Localization.lang("New technical report"), "", KeyBindingCategory.BIBTEX),
    NEW_INPROCEEDINGS("New inproceesings", Localization.lang("New inproceedings"), "", KeyBindingCategory.BIBTEX),

    NEXT_PREVIEW_LAYOUT("Next preview layout", Localization.lang("Next preview layout"), "F9", KeyBindingCategory.VIEW),
    NEXT_LIBRARY("Next library", Localization.lang("Next library"), "shortcut+PAGE_DOWN", KeyBindingCategory.VIEW),
    OPEN_CONSOLE("Open terminal here", Localization.lang("Open terminal here"), "shortcut+shift+L", KeyBindingCategory.TOOLS),
    OPEN_LIBRARY("Open library...", Localization.lang("Open library..."), "shortcut+O", KeyBindingCategory.FILE),
    OPEN_FILE("Open file", Localization.lang("Open file"), "F4", KeyBindingCategory.TOOLS),
    OPEN_FOLDER("Open folder", Localization.lang("Open folder"), "shortcut+shift+O", KeyBindingCategory.TOOLS),
    OPEN_OPEN_OFFICE_LIBRE_OFFICE_CONNECTION("Open OpenOffice/LibreOffice connection", Localization.lang("Open OpenOffice/LibreOffice connection"), "alt+0", KeyBindingCategory.TOOLS),
    SHOW_PREFS("Preferences", Localization.lang("Preferences"), "shortcut+,", KeyBindingCategory.FILE),
    OPEN_URL_OR_DOI("Open URL or DOI", Localization.lang("Open URL or DOI"), "F3", KeyBindingCategory.TOOLS),
    PASTE("Paste", Localization.lang("Paste"), "shortcut+V", KeyBindingCategory.EDIT),
    PULL_CHANGES_FROM_SHARED_DATABASE("Pull changes from shared database", Localization.lang("Pull changes from shared database"), "shortcut+shift+R", KeyBindingCategory.FILE),
    PREVIOUS_PREVIEW_LAYOUT("Previous preview layout", Localization.lang("Previous preview layout"), "shift+F9", KeyBindingCategory.VIEW),
    PREVIOUS_LIBRARY("Previous library", Localization.lang("Previous library"), "shortcut+PAGE_UP", KeyBindingCategory.VIEW),
    SCROLL_TO_NEXT_MATCH_CATEGORY("Scroll to next match category", Localization.lang("Scroll to next match category"), "right", KeyBindingCategory.VIEW),
    SCROLL_TO_PREVIOUS_MATCH_CATEGORY("Scroll to previous match category", Localization.lang("Scroll to previous match category"), "left", KeyBindingCategory.VIEW),
    PUSH_TO_APPLICATION("Push to application", Localization.lang("Push to application"), "shortcut+L", KeyBindingCategory.TOOLS),
    QUIT_JABREF("Quit JabRef", Localization.lang("Quit JabRef"), "shortcut+Q", KeyBindingCategory.FILE),
    REDO("Redo", Localization.lang("Redo"), "shortcut+Y", KeyBindingCategory.EDIT),
    REFRESH_OO("Refresh OO", Localization.lang("Refresh OpenOffice/LibreOffice"), "shortcut+alt+O", KeyBindingCategory.TOOLS),
    REPLACE_STRING("Replace string", Localization.lang("Replace string"), "shortcut+R", KeyBindingCategory.SEARCH),
    RESOLVE_DUPLICATE_CITATION_KEYS("Resolve duplicate citation keys", Localization.lang("Resolve duplicate citation keys"), "shortcut+shift+D", KeyBindingCategory.BIBTEX),
    SAVE_ALL("Save all", Localization.lang("Save all"), "shortcut+alt+S", KeyBindingCategory.FILE),
    SAVE_LIBRARY("Save library", Localization.lang("Save library"), "shortcut+S", KeyBindingCategory.FILE),
    SAVE_LIBRARY_AS("Save library as ...", Localization.lang("Save library as..."), "shortcut+shift+S", KeyBindingCategory.FILE),
    SEARCH("Search", Localization.lang("Search"), "shortcut+F", KeyBindingCategory.SEARCH),
    OPEN_GLOBAL_SEARCH_DIALOG("Open global search window", Localization.lang("Open global search window"), "shortcut+shift+F", KeyBindingCategory.SEARCH),
    SELECT_ALL("Select all", Localization.lang("Select all"), "shortcut+A", KeyBindingCategory.EDIT),
    SELECT_FIRST_ENTRY("Select first entry", Localization.lang("Select first entry"), "HOME", KeyBindingCategory.EDIT),
    SELECT_LAST_ENTRY("Select last entry", Localization.lang("Select last entry"), "END", KeyBindingCategory.EDIT),
    STRING_DIALOG_ADD_STRING("String dialog, add string", Localization.lang("String dialog, add string"), "shortcut+N", KeyBindingCategory.FILE),
    STRING_DIALOG_REMOVE_STRING("String dialog, remove string", Localization.lang("String dialog, remove string"), "shift+DELETE", KeyBindingCategory.FILE),
    SYNCHRONIZE_FILES("Synchronize files", Localization.lang("Synchronize files"), "shortcut+shift+F7", KeyBindingCategory.QUALITY),
    TOGGLE_GROUPS_INTERFACE("Toggle groups interface", Localization.lang("Toggle groups interface"), "alt+3", KeyBindingCategory.VIEW),
    UNDO("Undo", Localization.lang("Undo"), "shortcut+Z", KeyBindingCategory.EDIT),
    WEB_SEARCH("Web search", Localization.lang("Web search"), "alt+4", KeyBindingCategory.SEARCH),
    WRITE_METADATA_TO_PDF("Write metadata to PDF file(s)", Localization.lang("Write metadata to PDF file(s)"), "F6", KeyBindingCategory.TOOLS),
    CLEAR_SEARCH("Clear search", Localization.lang("Clear search"), "Esc", KeyBindingCategory.SEARCH),
    CLEAR_READ_STATUS("Clear read status", Localization.lang("Clear read status"), "", KeyBindingCategory.EDIT),
    READ("Set read status to read", Localization.lang("Set read status to read"), "", KeyBindingCategory.EDIT),
    SKIMMED("Set read status to skimmed", Localization.lang("Set read status to skimmed"), "", KeyBindingCategory.EDIT),
    GROUP_RENAME("Rename group", Localization.lang("Rename group"), "F2", KeyBindingCategory.EDIT),
    MERGE_WITH_FETCHED_ENTRY("Get bibliographic data from %0, \"DOI/ISBN/...\"", Localization.lang("Get bibliographic data from %0", "DOI/ISBN/..."), "F5", KeyBindingCategory.EDIT),
    LOOKUP_DOC_IDENTIFIER("Search document identifier online", Localization.lang("Search document identifier online"), "alt+F", KeyBindingCategory.EDIT),
    RENAME_FILE_TO_NAME("Rename file(s) to configured filename format pattern", Localization.lang("Rename file(s) to configured filename format pattern"), "shortcut+P", KeyBindingCategory.EDIT);

    private final String constant;
    private final String localization;
    private final String defaultBinding;
    private final KeyBindingCategory category;

    KeyBinding(String constantName, String localization, String defaultKeyBinding, KeyBindingCategory category) {
        this.constant = constantName;
        this.localization = localization;
        this.defaultBinding = defaultKeyBinding;
        this.category = category;
    }

    /// This method returns the enum constant value
    public String getConstant() {
        return constant;
    }

    public String getLocalization() {
        return localization;
    }

    /// This method returns the default key binding, the key(s) which are assigned
    ///
    /// @return The default key binding
    public String getDefaultKeyBinding() {
        return defaultBinding;
    }

    public KeyBindingCategory getCategory() {
        return category;
    }
}
