use anyhow::Result;
use futures::future::OptionFuture;
use mpris::PlayerFinder;
use std::{thread, time::Duration};
use crate::{cache::Cache, fetchers, lyrics::Language, song::{Song, SongData}, to_pinyin};
pub const UPDATE_PERIOD: f64 = 0.1f64;
pub async fn run_default(dont_romanize: Vec<Language>, mut cache: Cache) -> Result<()> {
mandarin_to_pinyin::init_map(None).expect("Cant be bothered catching this one");
let player_finder = PlayerFinder::new()
.expect("Could not connect to D-Bus");
let mut song: Option<Song> = None;
let mut previous_line = "".to_string();
loop {
thread::sleep(Duration::from_secs_f64(UPDATE_PERIOD));
let players = player_finder.find_all()
.expect("D-Bus Error when finding players.");
let Some(player) = players.into_iter().reduce(|acc, e| {
match (acc.bus_name(), e.bus_name()) {
("spotify", _) => acc,
(_, "spotify") => e,
(_, _) => acc,
}
}) else { continue };
let data = SongData::get_data(&player);
if match (&data, &song) {
(Some(data), Some(song)) => data != &song.data,
(None, Some(_)) => true,
(Some(_), None) => true,
_ => false,
} {
song = OptionFuture::from(
data.map(|data| async {
let lyrics = fetchers::fetch_all(&data, &mut cache).await;
Song::new(data, lyrics)
}),
).await;
if let Some(song) = &song {
if let None = &song.lyrics {
println!("");
}
} else {
println!("");
}
}
let Some(song) = &song else { continue; };
let Some(lyrics) = &song.lyrics else { continue; };
let position = player.get_position().map_or(0., |d| d.as_secs_f64());
let line = lyrics.get_line_at_time(position);
if line == previous_line { continue }
previous_line = line.to_string();
let line = if !dont_romanize.iter().any(|l| *l == lyrics.language) {
match lyrics.language {
Language::Japanese => kakasi::convert(line).romaji,
Language::Korean => korean_romanize::convert(line),
Language::Chinese => to_pinyin(line),
Language::Other => line.to_string(),
}
} else { line.to_string() };
println!("{}", line);
}
}