#![no_std]
#![no_main]

use esp_backtrace as _;
use esp_hal::{
    analog::adc::{Adc, AdcConfig, Attenuation},
    clock::CpuClock,
    delay::Delay,
    gpio::{Level, Output},
    main,
};
use libm::pow;
use log::info;

const GAMMA: f64 = 0.7_f64;
const RL10: f64 = 50_f64;

#[main]
fn main() -> ! {
    esp_println::logger::init_logger_from_env();

    // Common Setup Code
    let config = esp_hal::Config::default().with_cpu_clock(CpuClock::max());
    let peripherals = esp_hal::init(config);
    let delay = Delay::new();
    // End Common Setup Code

    let analog_pin = peripherals.GPIO0;
    let mut adc_config = AdcConfig::new();
    let mut pin = adc_config.enable_pin(analog_pin, Attenuation::_11dB);

    let mut adc = Adc::new(peripherals.ADC1, adc_config);

    let mut output_pins = [
        Output::new(peripherals.GPIO10, Level::Low),
        Output::new(peripherals.GPIO9, Level::Low),
        Output::new(peripherals.GPIO8, Level::Low),
        Output::new(peripherals.GPIO7, Level::Low),
        Output::new(peripherals.GPIO6, Level::Low),
        Output::new(peripherals.GPIO5, Level::Low),
        Output::new(peripherals.GPIO4, Level::Low),
        Output::new(peripherals.GPIO3, Level::Low),
        Output::new(peripherals.GPIO2, Level::Low),
        Output::new(peripherals.GPIO1, Level::Low),
    ];

    loop {
        let reading: f64 = nb::block!(adc.read_oneshot(&mut pin)).unwrap() as f64;
        let voltage = reading * 5_f64 / 1_024_f64;
        let resistance = 2_000_f64 * voltage / (1_f64 - voltage / 5_f64);
        info!("Reading {reading}");
        info!("Voltage {voltage}");
        info!("Resistance {resistance}");
        // let lux = pow(RL10 * 1e3 * pow(10_f64, GAMMA) / resistance, 1_f64 / GAMMA);
        // let leds_lit_up = output_pins.len()
        //     - map_linear(lux, 0_f64, 1_016_f64, 0_f64, output_pins.len() as f64) as usize;
        // for led in &mut output_pins[..leds_lit_up] {
        //     led.set_high();
        // }
        // for led in &mut output_pins[leds_lit_up..] {
        //     led.set_low();
        // }
        delay.delay_millis(1000);
    }
}

fn map_linear(x: f64, min_in: f64, max_in: f64, min_out: f64, max_out: f64) -> f64 {
    ((x - min_in) * (max_out - min_out) / (max_in - min_in)) + min_out
}