use mumu::parser::types::Value;
use mumu::parser::interpreter::Interpreter;
use crate::partials::{is_placeholder, make_three_arg_partial};
pub fn math_rotate_point_bridge(_interp: &mut Interpreter, args: Vec<Value>) -> Result<Value, String> {
match args.len() {
0 => Ok(make_three_arg_partial(rotate_point_finalize, None, None, None)),
1 => {
let a = &args[0];
if is_placeholder(a) {
Ok(make_three_arg_partial(rotate_point_finalize, None, None, None))
} else {
Ok(make_three_arg_partial(rotate_point_finalize, Some(a.clone()), None, None))
}
}
2 => {
let lp = is_placeholder(&args[0]);
let rp = is_placeholder(&args[1]);
Ok(make_three_arg_partial(
rotate_point_finalize,
if lp { None } else { Some(args[0].clone()) },
if rp { None } else { Some(args[1].clone()) },
None,
))
}
3 => {
let lp = is_placeholder(&args[0]);
let mp = is_placeholder(&args[1]);
let rp = is_placeholder(&args[2]);
if !lp && !mp && !rp {
rotate_point_finalize(vec![args[0].clone(), args[1].clone(), args[2].clone()])
} else {
Ok(make_three_arg_partial(
rotate_point_finalize,
if lp { None } else { Some(args[0].clone()) },
if mp { None } else { Some(args[1].clone()) },
if rp { None } else { Some(args[2].clone()) },
))
}
}
n => Err(format!("math:rotate_point expects 3 arguments, got {}", n)),
}
}
fn rotate_point_finalize(args: Vec<Value>) -> Result<Value, String> {
if args.len() != 3 {
return Err(format!("rotate_point_finalize => expected 3 args, got {}", args.len()));
}
let x = match &args[0] {
Value::Float(f) => *f,
Value::Int(i) => *i as f64,
other => return Err(format!("math:rotate_point: first arg (x) must be float or int, got {:?}", other)),
};
let y = match &args[1] {
Value::Float(f) => *f,
Value::Int(i) => *i as f64,
other => return Err(format!("math:rotate_point: second arg (y) must be float or int, got {:?}", other)),
};
let rad = match &args[2] {
Value::Float(f) => *f,
Value::Int(i) => *i as f64,
other => return Err(format!("math:rotate_point: third arg (rad) must be float or int, got {:?}", other)),
};
let cos_a = rad.cos();
let sin_a = rad.sin();
let out_x = x * cos_a - y * sin_a;
let out_y = x * sin_a + y * cos_a;
Ok(Value::FloatArray(vec![out_x, out_y]))
}