//SSD1306:
//SDA -> GPIO21
//SCL -> GPIO22

//DHT22:
//DATA -> GPIO18


use esp_idf_hal::i2c::*;
use esp_idf_hal::prelude::*;
use esp_idf_hal::delay::FreeRtos;
use esp_idf_svc::hal::{delay, gpio::PinDriver, peripherals::Peripherals};
use ssd1306::{prelude::*, I2CDisplayInterface, Ssd1306};
use std::thread;
use std::time::Duration;
use dht_sensor::{dht22, DhtReading};


use embedded_graphics::{
    mono_font::{ascii::FONT_6X10, MonoTextStyleBuilder},
    pixelcolor::BinaryColor,
    prelude::*,
    text::{Baseline, Text},
    primitives::{Circle, PrimitiveStyleBuilder}
};

fn main() -> anyhow::Result<()> {
    esp_idf_svc::sys::link_patches();
    let peripherals = Peripherals::take().unwrap();
    let i2c = peripherals.i2c0;
    let sda = peripherals.pins.gpio21;
    let scl = peripherals.pins.gpio22;

    let mut pin = PinDriver::input_output_od(peripherals.pins.gpio18).unwrap();
    pin.set_high().unwrap();
    // The DHT datasheet suggests waiting 1 second
    thread::sleep(Duration::from_millis(1000));

    let mut d = delay::Ets;
    let mut iterations = 1500;


    let config = I2cConfig::new().baudrate(100.kHz().into());
    let i2c = I2cDriver::new(i2c, sda, scl, &config)?;

    let interface = I2CDisplayInterface::new(i2c);
    let mut display = Ssd1306::new(interface, DisplaySize128x64, DisplayRotation::Rotate0)
        .into_buffered_graphics_mode();
    display.init().unwrap();

    let text_style = MonoTextStyleBuilder::new()
        .font(&FONT_6X10)
        .text_color(BinaryColor::On)
        .build();

    let off = PrimitiveStyleBuilder::new()
        .stroke_width(1)
        .stroke_color(BinaryColor::Off)
        .build();

    let on = PrimitiveStyleBuilder::new()
        .stroke_width(1)
        .stroke_color(BinaryColor::On)
        .build();

    let mut i = 0;
    let mut dir = 1;

    Text::with_baseline("Hello world!", Point::new(30, 0), text_style, Baseline::Top)
        .draw(&mut display)
        .unwrap();

    Text::with_baseline("with Rust!!", Point::new(30, 16), text_style, Baseline::Top)
        .draw(&mut display)
        .unwrap();

    loop {

           while iterations > 0 {
              thread::sleep(Duration::from_secs(3));
              iterations -= 1;
              match dht22::Reading::read(&mut d, &mut pin) {
                Ok(r) => println!(
                  "Temperature: {}\tHumidity: {}",
                  r.temperature, r.relative_humidity
              ),
              Err(e) => println!("Failed with error: {:?}", e),
        }


        
        Circle::new(Point::new(i, 40), 16)
            .into_styled(off)
            .draw(&mut display)
            .unwrap();

        Text::with_baseline("Start....", Point::new(30, 24), text_style, Baseline::Top)
            .draw(&mut display)
            .unwrap();
        

        if i > 100 { 
            dir = -1; 
        } 

        if i == 0 {
            dir = 1;
        }

        i += dir << 4;

        Circle::new(Point::new(i, 40), 16)
            .into_styled(on)
            .draw(&mut display)
            .unwrap();

        display.flush().unwrap();

        FreeRtos::delay_ms(100);
    }
  }  
}