use crate::pixel_format::{get_a, get_b, get_g, get_r, set_a, set_b, set_g, set_r};
use crate::pixel_format::{new_rgba64, rgba_div, Rgba64};

use log::{debug, info};
use rhai::Engine;

pub fn engine_startup() -> Engine {
    let mut engine = Engine::new();

    // engine.on_print(|x| info!("PRINTED FROM SHADER: {}", x));

    // Any function or closure that takes a '&str', an 'Option<&str>' and a 'Position' argument
    // can be used to override 'debug'.
    engine.on_debug(|x, src, pos| {
        let src = src.unwrap_or("unknown");
        // debug!("SHADER DEBUG of {} at {:?}: {}", src, pos, x)
    });

    engine
        .register_type::<Rgba64>()
        .register_fn("RGBA", get_rgba_rhai)
        .register_fn("RGBA", get_rgba_from_int)
        .register_fn("RGBA", get_rgba_from_int)
        .register_fn("/", rgba_div)
        // .register_fn("*", rgba_mult)
        // .register_fn("+", rgba_add)
        // .register_fn("-", rgba_sub)
        ;

    // engine.register_global_module(RandomPackage::new().as_shared_module());

    engine
}
use rhai::INT;
pub fn get_rgba_rhai(r: INT, g: INT, b: INT, a: INT) -> Rgba64 {
    let mut pixel = 0;

    pixel |= set_r(pixel, r as u8);
    pixel |= set_g(pixel, g as u8);
    pixel |= set_b(pixel, b as u8);
    pixel |= set_a(pixel, a as u8);
    pixel
}

pub fn get_rgba_from_int(pixel: INT) -> Rgba64 {
    let mut pixel = pixel as u64;

    let r = get_r(pixel.try_into().unwrap());
    let g = get_g(pixel.try_into().unwrap());
    let b = get_b(pixel.try_into().unwrap());
    let a = get_a(pixel.try_into().unwrap());

    pixel |= set_r(pixel, r as u8);
    pixel |= set_g(pixel, g as u8);
    pixel |= set_b(pixel, b as u8);
    pixel |= set_a(pixel, a as u8);
    pixel
}
