use std::time::Duration;
use amberylib::{AmberyClient, Easing};
use clap::{Parser, Subcommand};
use owo_colors::OwoColorize;
#[derive(Parser)]
#[command(version, about, long_about = None)]
struct Cli {
#[command(subcommand)]
command: Option<Commands>,
}
#[derive(Subcommand)]
enum Commands {
Get,
Rgb {
r: u8,
g: u8,
b: u8,
#[arg(short, long)]
duration: Option<u64>,
#[arg(short, long)]
easing: Option<Easing>,
},
Temp {
temperature: u32,
#[arg(short, long)]
duration: Option<u64>,
#[arg(short, long)]
easing: Option<Easing>,
},
}
fn main() {
let cli = Cli::parse();
let mut client = match AmberyClient::connect() {
Ok(client) => client,
Err(e) => {
eprintln!("{} {}", "Failed to connect to Ambery:".red(), e);
eprintln!(
"{}",
"The daemon man not be running. Please try restarting it.".red()
);
std::process::exit(1);
}
};
match &cli.command {
Some(Commands::Get) => {
let rgb = match client.get() {
Ok(rgb) => rgb,
Err(e) => {
eprintln!("{} {}", "Failed to get current config:".red(), e);
std::process::exit(1);
}
};
println!("Red: {}", rgb.r);
println!("Blue: {}", rgb.b);
println!("Green: {}", rgb.g);
}
Some(Commands::Rgb {
r,
g,
b,
duration,
easing,
}) => {
let r = *r as f64 / 255.0;
let g = *g as f64 / 255.0;
let b = *b as f64 / 255.0;
let rgb = match client.animate(
Some(r),
Some(g),
Some(b),
Duration::from_millis(duration.unwrap_or(700)),
easing.unwrap_or(Easing::EaseInOutQuad),
) {
Ok(rgb) => rgb,
Err(e) => {
eprintln!("{} {}", "Failed to set config:".red(), e);
std::process::exit(1);
}
};
println!("Red: {}", rgb.r);
println!("Blue: {}", rgb.b);
println!("Green: {}", rgb.g);
}
Some(Commands::Temp {
temperature,
duration,
easing,
}) => {
let (r, g, b) = temperature_to_rgb(*temperature);
let rgb = match client.animate(
Some(r),
Some(g),
Some(b),
Duration::from_millis(duration.unwrap_or(700)),
easing.unwrap_or(Easing::EaseInOutQuad),
) {
Ok(rgb) => rgb,
Err(e) => {
eprintln!("{} {}", "Failed to set config:".red(), e);
std::process::exit(1);
}
};
println!("Red: {}", rgb.r);
println!("Blue: {}", rgb.b);
println!("Green: {}", rgb.g);
}
None => {}
}
}
fn temperature_to_rgb(kelvin: u32) -> (f64, f64, f64) {
let temp = kelvin as f64 / 100.0;
let red = if temp <= 66.0 {
1.0
} else {
(1.292_936_2 * (temp - 60.0).powf(-0.133_204_76)).clamp(0.0, 1.0)
};
let green = if temp <= 66.0 {
(0.390_081_58 * temp.ln() - 0.631_841_4).clamp(0.0, 1.0)
} else {
(1.129_890_86 * (temp - 60.0).powf(-0.075_514_846)).clamp(0.0, 1.0)
};
let blue = if temp >= 66.0 {
1.0
} else if temp <= 19.0 {
0.0
} else {
(0.543_206_79 * (temp - 10.0).ln() - 1.196_254_1).clamp(0.0, 1.0)
};
(red, green, blue)
}