goosemusic 1.3.2

A music player with YouTube search, local playback, and OS media controls
use super::Strings;
use crate::providers::ProviderId;

pub const STRINGS: Strings = Strings {
    search: "Search",
    downloads: "Downloads",
    settings: "Settings",
    library: "Library",
    nothing_saved_yet: "Nothing saved yet",
    new_playlist_name: "New playlist name",

    queue: "Queue",
    recently_played: "Recently played",
    now_playing_from: "Now playing from",
    now_playing: "Now playing",
    up_next: "Up next",
    no_track_playing: "No track playing",
    no_more_tracks_in_queue: "No more tracks in queue",
    no_recently_played_tracks: "No recently played tracks",

    not_playing: "Not playing",
    no_tracks_found: "No tracks found",

    searching: "Searching...",
    loading: "Loading...",
    load_more: "Load More",
    no_results_found: "No results found",
    no_recent_searches: "No recent searches",
    generating_radio: "Generating radio...",

    not_an_artist_page: "Not an artist page",
    provided_by: "Provided by",
    retry: "Retry",
    nothing_here: "Nothing here",
    most_popular_songs: "Most popular songs",
    albums: "Albums",
    playlists: "Playlists",
    fans_also_like: "Fans also like",

    looking_up_lyrics: "Looking up lyrics…",
    play_a_track_for_lyrics: "Play a track to see its lyrics.",
    lyrics_selectable: "Selectable",
    lyrics_synced: "Synced",
    lyrics_plain: "Plain",
    lyrics_translations: "Translations",
    lyrics_original: "Original",
    add_custom: "Add custom",
    lyrics_name: "Name",
    translate_with_ai: "Translate with AI",
    translate_title: "Translate lyrics with AI",
    translate_language_lbl: "Target language",
    translate_prompt_lbl: "Prompt",
    translate_submit: "Translate",
    translate_reset: "Reset prompt",
    translating: "Translating…",
    translation_ready: "Translation ready — review and save",
    translation_language_empty: "Enter a target language",
    no_lyrics_to_translate: "No lyrics to translate for this track.",
    translation_not_configured: "Set the translation server URL and model in Settings.",
    translation_failed: |e| format!("Translation failed: {e}"),
    sec_translation: "AI translation",
    translation_base_url_lbl: "Server URL (OpenAI-compatible)",
    translation_api_key_lbl: "API key (empty for local servers)",
    translation_model_lbl: "Model",
    translation_refresh_models: "Request model list",
    translation_no_models: "No models found on this server.",
    translation_models_failed: |e| format!("Couldn't load model list: {e}"),
    edit_lyrics: "Edit lyrics",
    lyrics_editor_hint: "One line per lyric. Prefix lines with [mm:ss.xx] for synced lyrics, or leave them plain. Add a `# note` line under any lyric for a note shown below the lyrics.",


    playlist_not_found: "Playlist not found",
    add_local: "Add local",
    downloaded_tracks: "Downloaded tracks",
    no_downloaded_tracks: "No downloaded tracks",

    ctx_play: "Play",
    ctx_play_local: "Play local",
    ctx_edit: "Edit",
    ctx_go_to_artist: "Go to artist",
    ctx_add_to_queue: "Add to Queue",
    ctx_add_to_playlist: "Add to Playlist",
    ctx_download: "Download",
    ctx_song_radio: "Song Radio",
    ctx_artist_radio: "Artist Radio",
    ctx_remove_from_queue: "Remove from Queue",
    ctx_remove_from_playlist: "Remove from Playlist",
    ctx_remove_from_recent: "Remove from Recent",
    ctx_clear_cache: "Clear cache",
    sub_play_via: "Play via",
    sub_download_from: "Download from",
    sub_via: "Via",
    sub_on: "On",
    sub_clear_cache_from: "Clear from",
    via_search_suffix: "(search)",

    current: "(current)",
    select: "select",
    find: "Find",
    finding: "Finding…",
    found_on: |p| format!("Found on {p}"),
    not_linked: "Not linked",
    providers: "Providers",
    no_provider_data: "This track has no provider data.",
    save: "Save",
    cancel: "Cancel",
    edit_track: "Edit Track",
    lbl_title: "Title",
    lbl_artist: "Artist",
    ph_track_title: "Track title",
    ph_track_artist: "Track artist",
    delete: "Delete",
    delete_playlist_q: "Delete playlist?",
    tracks_wont_be_deleted: "Tracks will not be deleted.",
    lbl_id: "ID",
    lbl_url: "URL",
    lbl_artist_id: "Artist ID",
    lbl_duration_secs: "Duration (in seconds)",
    lbl_thumbnail: "Thumbnail",
    lbl_album: "Album",

    sec_playback: "Playback",
    sec_storage: "Storage",
    sec_history: "History",
    sec_appearance: "Appearance",
    sec_dependencies: "Dependencies",
    theme_lbl: "Theme",
    language_lbl: "Language",
    default_provider_lbl: "Default stream & download provider",
    cookie_browser_lbl: "Browser cookies for age-restricted videos",
    cookies_off: "Off",
    normalize_volume_lbl: "Normalize volume across tracks",
    download_dir_lbl: "Download directory",
    cache_size_lbl: "Max stream cache size (MB)",
    hist_rows_lbl: "Search history rows shown",
    hist_entries_lbl: "Search history entries kept",
    recent_kept_lbl: "Recently played tracks kept",
    reset_defaults: "Reset to defaults",

    find_in_list: "Find in list…",
    scope_songs: "Songs",
    scope_videos: "Videos",
    scope_artists: "Artists",
    scope_albums: "Albums",
    scope_playlists: "Playlists",
    radio_word_song: "song",
    radio_word_artist: "artist",

    lyrics_copied: "Lyrics copied to clipboard",
    saved_to_library: "Saved to library",
    removed_from_library: "Removed from library",
    no_lyrics_found: "No lyrics found for this track.",
    lyrics_saved: "Custom lyrics saved",
    lyrics_deleted: "Custom lyrics deleted",
    lyrics_empty: "Lyrics can't be empty",
    lyrics_name_empty: "Give your lyrics a name",
    select_playlist_drop: "Select a playlist to drop tracks into",
    reordered_playlist: "Reordered playlist",
    max_panes_reached: "Maximum number of panes reached",

    n_saved: |n| format!("{n} saved"),
    n_plays: |n| format!("{} plays", crate::util::format_count(n)),
    search_placeholder: |p| match p {
        ProviderId::YouTube => "Search YouTube Music...".into(),
        ProviderId::Local => "Search...".into(),
        other => format!("Search {}...", other.label()),
    },
    added: |n| format!("Added {}", en_tracks(n)),
    added_to: |n, to| format!("Added {} to {to}", en_tracks(n)),
    removed_n: |n| format!("Removed {}", en_tracks(n)),
    removed_from: |n, from| format!("Removed {} from {from}", en_tracks(n)),
    pasted_into: |n, into| format!("Pasted {} into {into}", en_tracks(n)),
    saved_title: |t| format!("Saved \"{t}\" to library"),
    playlist_created: |n| format!("Playlist \"{n}\" created"),
    added_local: |n| format!("Added {} (select a playlist to organize)", en_tracks(n)),
    downloading_n: |n| format!("Downloading {}...", en_tracks(n)),
    resolving_on: |title, p| format!("Resolving \"{title}\" on {p}..."),
    resolving_player_client: "Resolving compatible player client...",
    resolved_player_client: |c| format!("Resolved player client: {c}"),
    player_client_unavailable: "No compatible player client found, using default one...",
    provider_no_radio: |p| format!("{p} does not support radio"),
    generating_radio_for: |w, name| format!("Generating radio for {w}: {name}..."),
    could_not_find_on: |name, p| format!("Could not find \"{name}\" on {p}"),
    opening: |l| format!("Opening: {l}..."),
    opening_artist: |name| format!("Opening artist: {name}..."),
    download_complete: |path| format!("Download complete! Saved to {path}"),
    failed_resolve_on: |title, p, e| format!("Failed to resolve \"{title}\" on {p}: {e}"),
    couldnt_load: |e| format!("Couldn't load: {e}"),
    couldnt_load_lyrics: |e| format!("Couldn't load lyrics: {e}"),
    search_failed: |e| format!("Search failed: {e}"),
    cache_cleared_for: |p| format!("Cache cleared for {p}"),
    radio_label: |w, name| format!("Radio ({w}): {name}"),
    ctx_add_to_playlist_n: |n| format!("Add {} to playlist", en_tracks(n)),
    ctx_add_to_queue_n: |n| format!("Add {} to queue", en_tracks(n)),
    ctx_download_n: |n| format!("Download {}", en_tracks(n)),
    ctx_remove_from_queue_n: |n| format!("Remove {} from queue", en_tracks(n)),
    ctx_remove_from_playlist_n: |n| format!("Remove {} from playlist", en_tracks(n)),
    ctx_remove_from_recent_n: |n| format!("Remove {} from recent", en_tracks(n)),

    import_playlist: "Import playlist",
    import_method_native: "Native",
    import_method_filelist: "File list",
    import_method_csv: "CSV",
    import_native_hint: "Imports playlists from a playlists.json file.",
    import_csv_name_col: "Name column",
    import_csv_artist_col: "Artist column",
    import_csv_album_col: "Album column",
    import_csv_preset: "Preset",
    import_csv_preset_default: "Default",
    import_csv_preset_exportify: "Exportify",
    import_csv_exportify_note: "Supports Spotify playlists exported from https://exportify.net/.",
    import_pattern_lbl: "Filename pattern",
    import_playlist_name: "Playlist name",
    import_add_pattern: "Add pattern",
    import_select_file: "Select file",
    import_select_folder: "Select folder",
    import_pattern_conflict: |a, b| {
        format!(
            "Patterns \"{a}\" and \"{b}\" can match the same file with conflicting fields. Remove or fix one."
        )
    },
    import_playlists_imported: |n| format!("Imported {} playlists", en_tracks(n)),
    import_imported_into: |n, into| format!("Imported {} into {}", en_tracks(n), into),
    import_no_tracks: "No tracks found to import.",
    import_no_match: "No files matched the patterns.",
    import_bad_file: "Could not read the selected file.",

    deps_title: "Missing dependencies",
    deps_intro: "Some tools the app uses are missing. Select which to install, or discard to continue (search/streaming may not work until they are present).",
    deps_install: "Install",
    deps_install_selected: "Install selected",
    deps_discard: "Discard",
    deps_installing: "Installing…",
    deps_installed: "Installed",
    deps_failed: "Failed",
    deps_installed_toast: "Selected dependencies installed.",
    deps_yt_dlp_desc: "Streams and downloads audio (required for YouTube and SoundCloud)",
    deps_ytmusicapi_desc: "YouTube Music search (optional, falls back to yt-dlp)",
    deps_python3_desc: "Required by ytmusicapi (YouTube Music search)",
    deps_ytmusicapi_requires_python: "Requires Python 3 (install it first)",
    deps_play_requires_yt_dlp: "Playback needs yt-dlp — install it from the startup dialog to play this.",
    deps_source_not_playable: "This source can't be played.",
    deps_found_section_title: "Found on your system",
    deps_found_section_intro: "These are already available. Check any to install a managed copy via the app (the app copy takes priority over the system one).",
    deps_found_on_system: "Found on your system",
    deps_managed_by_app: "Installed (managed by app)",
    deps_not_installed: "Not installed",
    deps_delete: "Delete",
    deps_deleting: "Deleting…",
    deps_deleted: "Deleted",
    deps_delete_failed: "Delete failed",

    sec_updates: "Updates",
    check_for_updates: "Check for updates",
    checking_for_updates: "Checking for updates…",
    up_to_date: "Up to date",
    current_version: |v| format!("Version {v}"),
    update_available: |v| format!("Version {v} is available. Go to Settings to update."),
    update_now: "Update now",
    updating: "Updating…",
    update_applied: |v| format!("Updated to {v}. Restarting…"),
    package_managed: "Cannot auto-update (no write access to the application directory). If installed via a package manager, use it to update.",
    update_failed: |e| format!("Update failed: {e}"),
    percent: |pct| format!("{pct}%"),
    list_match_pos: |pos, total| format!("{pos}/{total}"),
    sub_menu_label: |base, provider, suffix| format!("{base} {provider} {suffix}"),
    deps_failed_detail: |e| format!("Failed: {e}"),
    deps_delete_failed_detail: |e| format!("Delete failed: {e}"),

    sc_title: "Keyboard shortcuts",
    sc_sec_list: "Track list",
    sc_move: "Move through the focused list (wraps)",
    sc_focus_panel: "Focus queue panel or track list",
    sc_first_last: "First / last row",
    sc_page: "Page / half-page",
    sc_play: "Play the focused track",
    sc_sec_select: "Selection and editing",
    sc_extend: "Extend selection",
    sc_toggle_sel: "Toggle selection on focused row",
    sc_select_all: "Select all in focused list",
    sc_copy_paste: "Copy / paste selected tracks",
    sc_delete: "Delete selected tracks",
    sc_esc: "Close popup, then clear selection, then back to Search",
    sc_sec_search: "Search",
    sc_focus_search: "Focus search",
    sc_stage_provider: "Stage search provider (pending)",
    sc_stage_scope: "Stage search scope (pending)",
    sc_run_search: "Run the pending search",
    sc_find_list: "In-list fuzzy search (step matches)",
    sc_sec_playlists: "Playlists and history",
    sc_prev_next_pl: "Previous / next playlist",
    sc_jump: "Playlist jumper (Enter opens, Shift+Enter plays)",
    sc_back_fwd: "Back / forward in focused pane",
    sc_sec_playback: "Playback",
    sc_play_pause: "Play / pause",
    sc_next_prev: "Next / previous track",
    sc_mute: "Mute",
    sc_volume: "Volume down / up",
    sc_seek: "Seek 5s back / forward (Shift: 10s)",
    sc_toggles: "Queue / repeat / lyrics / queue tab",
    sc_sec_panes: "Panes",
    sc_split: "Split side by side / stacked",
    sc_close_pane: "Close focused pane",
    sc_adj_pane: "Focus adjacent pane",
    sc_cycle_pane: "Cycle / jump panes",
    sc_sec_menu: "Context menu",
    sc_open_menu: "Open for the focused track",
    sc_nav_menu: "Navigate the menu",
};

fn en_tracks(n: usize) -> String {
    if n == 1 {
        "1 track".into()
    } else {
        format!("{n} tracks")
    }
}