#![allow(clippy::needless_pass_by_value)]
use std::{process, sync::atomic::Ordering, thread};
use diskit::Diskit;
use legacytranslate::MessageHandler;
use crate::{
audio::print_info, config::Config, l10n::messages::Message, matcher::BigAction, songs::Repeat,
};
use super::Command;
fn increase_likelihood<D>(count: u32, config: &mut Config, _diskit: D) -> BigAction
where
D: Diskit,
{
if config.num == u32::MAX
{
config.l10n.write(Message::MaxLikelihoodReached);
}
else
{
config.num = config.num.saturating_add(count);
config.l10n.write(Message::LikelihoodIncreased(config.num));
}
BigAction::Nothing
}
fn decrease_likelihood<D>(count: u32, config: &mut Config, _diskit: D) -> BigAction
where
D: Diskit,
{
if config.num == 0
{
config.l10n.write(Message::SongAlreadyNever);
}
else
{
config.num = config.num.saturating_sub(count);
config.l10n.write(Message::LikelihoodDecreased(config.num));
if config.num == 0
{
config.l10n.write(Message::SongNever);
}
}
BigAction::Nothing
}
pub fn quit<D>(_: u32, config: &mut Config, _diskit: D) -> BigAction
where
D: Diskit,
{
config.l10n.write(Message::StoppingProgram);
BigAction::Quit
}
pub fn pause<D>(_: u32, config: &mut Config, _diskit: D) -> BigAction
where
D: Diskit,
{
if config.paused
{
config.l10n.write(Message::AlreadyPaused);
}
else
{
config.l10n.write(Message::Pausing);
config.paused = true;
config.audio_handler.pause();
}
config.arc_config.update_dbus.store(true, Ordering::SeqCst);
BigAction::Nothing
}
pub fn resume<D>(_: u32, config: &mut Config, _diskit: D) -> BigAction
where
D: Diskit,
{
if config.paused
{
config.l10n.write(Message::Resuming);
config.paused = false;
config.audio_handler.play();
}
else
{
config.l10n.write(Message::AlreadyRunning);
}
config.arc_config.update_dbus.store(true, Ordering::SeqCst);
BigAction::Nothing
}
pub fn skip<D>(count: u32, config: &mut Config, _diskit: D) -> BigAction
where
D: Diskit,
{
config.l10n.write(Message::SkippingSong);
config.paused = false;
config.audio_handler.skip();
config.arc_config.update_dbus.store(true, Ordering::SeqCst);
let _ = config.tx.send((Command::Skip, count - 1));
BigAction::Nothing
}
fn increase_volume<D>(count: u32, config: &mut Config, _diskit: D) -> BigAction
where
D: Diskit,
{
config.loud += 0.01 * count as f32;
config.l10n.write(Message::MakingLouder(config.loud as f64));
config.audio_handler.set_volume(config.loud);
BigAction::Nothing
}
fn decrease_volume<D>(count: u32, config: &mut Config, _diskit: D) -> BigAction
where
D: Diskit,
{
config.loud -= 0.01 * count as f32;
config
.l10n
.write(Message::MakingQuieter(config.loud as f64));
if config.loud < 0.0
{
config.l10n.write(Message::LoudZero);
config.loud = 0.0;
}
config.audio_handler.set_volume(config.loud);
BigAction::Nothing
}
fn show_duration<D>(_: u32, config: &mut Config, _diskit: D) -> BigAction
where
D: Diskit,
{
let pos = config.source.get_pos() as f64
/ config.source.sample_rate as f64
/ config.arc_config.channels.load(Ordering::SeqCst) as f64;
if let Some(len) = config.source.samples_len()
{
let len = len as f64
/ config.source.sample_rate as f64
/ config.arc_config.channels.load(Ordering::SeqCst) as f64;
config.l10n.write(Message::DurationKnown(pos, len));
}
else
{
config.l10n.write(Message::DurationUnknown(pos));
}
BigAction::Nothing
}
fn switch_play_pause<D>(count: u32, config: &mut Config, _diskit: D) -> BigAction
where
D: Diskit,
{
if count % 2 == 1
{
if config.paused
{
let _ = config.tx.send((Command::Resume, 1));
}
else
{
let _ = config.tx.send((Command::Pause, 1));
}
}
BigAction::Nothing
}
pub fn quit_after_song<D>(_: u32, config: &mut Config, _diskit: D) -> BigAction
where
D: Diskit,
{
if config.quit_after_song
{
config.l10n.write(Message::AlreadyQuitting);
}
else
{
config.l10n.write(Message::QuittingAfter);
config.quit_after_song = true;
};
BigAction::Nothing
}
pub fn pause_after_song<D>(_: u32, config: &mut Config, _diskit: D) -> BigAction
where
D: Diskit,
{
if config.pause_after_song
{
config.l10n.write(Message::AlreadyPausing);
}
else
{
config.l10n.write(Message::PausingAfter);
config.pause_after_song = true;
};
BigAction::Nothing
}
fn show_info<D>(count: u32, config: &mut Config, _diskit: D) -> BigAction
where
D: Diskit,
{
print_info(&config.tag, &config.l10n);
let _ = config.tx.send((Command::ShowInfo, count - 1));
BigAction::Nothing
}
fn open_cover<D>(count: u32, config: &mut Config, _diskit: D) -> BigAction
where
D: Diskit,
{
if let Ok(pic_path) = config.arc_config.pic_path.lock()
{
if let Some(pic_path) = pic_path.clone()
{
config.l10n.write(Message::OpeningPicture);
thread::spawn(|| {
let _ = process::Command::new("mimeopen")
.arg("-")
.arg(pic_path)
.spawn()
.and_then(|mut handle| handle.wait());
});
}
else
{
config.l10n.write(Message::NothingPlayingYet);
}
}
else
{
config.l10n.write(Message::CantOpenPicture);
}
let _ = config.tx.send((Command::ShowInfo, count - 1));
BigAction::Nothing
}
pub fn disable_repeat<D>(_: u32, config: &mut Config, _diskit: D) -> BigAction
where
D: Diskit,
{
if config.repeat == Repeat::Not
{
config.l10n.write(Message::NotRepeatingAlready);
}
else
{
config.song_index += 1;
config.l10n.write(Message::StoppingRepeating);
config.repeat = Repeat::Not;
}
BigAction::Nothing
}
pub fn repeat_once<D>(_: u32, config: &mut Config, _diskit: D) -> BigAction
where
D: Diskit,
{
if config.repeat == Repeat::Once
{
config.l10n.write(Message::AlreadyRepeatingOnce);
}
else
{
if config.repeat == Repeat::Not
{
config.song_index -= 1;
}
config.l10n.write(Message::RepeatingOnce);
config.repeat = Repeat::Once;
}
BigAction::Nothing
}
pub fn repeat_forever<D>(_: u32, config: &mut Config, _diskit: D) -> BigAction
where
D: Diskit,
{
if config.repeat == Repeat::Always
{
config.l10n.write(Message::AlreadyRepeatingForever);
}
else
{
if config.repeat == Repeat::Not
{
config.song_index -= 1;
}
config.l10n.write(Message::RepeatingForever);
config.repeat = Repeat::Always;
}
BigAction::Nothing
}
pub fn skip_to_previous<D>(count: u32, config: &mut Config, _diskit: D) -> BigAction
where
D: Diskit,
{
if config.song_index > 0
{
config.l10n.write(Message::Previous);
}
if count as usize > config.song_index
{
config.l10n.write(Message::AlreadyPlayingFirst);
}
config.song_index = config.song_index.saturating_sub(count as usize);
BigAction::Nothing
}
impl Command
{
pub fn get_handler<D>(self) -> fn(u32, &mut Config, D) -> BigAction
where
D: Diskit,
{
match self
{
Self::IncreaseLikelihood => increase_likelihood,
Self::DecreaseLikelihood => decrease_likelihood,
Self::Quit => quit,
Self::Pause => pause,
Self::Resume => resume,
Self::Skip => skip,
Self::IncreaseVolume => increase_volume,
Self::DecreaseVolume => decrease_volume,
Self::ShowDuration => show_duration,
Self::SwitchPlayPause => switch_play_pause,
Self::QuitAfterSong => quit_after_song,
Self::PauseAfterSong => pause_after_song,
Self::ShowInfo => show_info,
Self::OpenCover => open_cover,
Self::DisableRepeat => disable_repeat,
Self::RepeatOnce => repeat_once,
Self::RepeatForever => repeat_forever,
Self::SkipToPrevious => skip_to_previous,
}
}
}