//! Driver for the MLX90614 Infrared Thermometer.
//!
//! SMBus Interface
//!
//! Usage
//! -----
//!
//! ```rust
//! let mux_i2c = components::i2c::I2CMuxComponent::new(&earlgrey::i2c::I2C)
//!     .finalize(components::i2c_mux_component_helper!());
//!
//! let mlx90614 = components::mlx90614::Mlx90614I2CComponent::new()
//!    .finalize(components::mlx90614_i2c_component_helper!(mux_i2c));
//! ```
//!

use crate::driver;
use core::cell::Cell;
use enum_primitive::cast::FromPrimitive;
use enum_primitive::enum_from_primitive;
use kernel::common::cells::{OptionalCell, TakeCell};
use kernel::common::registers::register_bitfields;
use kernel::hil::i2c::{self, Error};
use kernel::hil::sensors;
use kernel::{AppId, Callback, Driver, ReturnCode};

/// Syscall driver number.
pub const DRIVER_NUM: usize = driver::NUM::Mlx90614 as usize;

register_bitfields![u16,
    CONFIG [
        IIR OFFSET(0) NUMBITS(3) [],
        DUAL OFFSET(6) NUMBITS(1) [],
        FIR OFFSET(8) NUMBITS(3) [],
        GAIN OFFSET(11) NUMBITS(3) []
    ]
];

#[derive(Clone, Copy, PartialEq, Debug)]
enum State {
    Idle,
    IsPresent,
    ReadAmbientTemp,
    ReadObjTemp,
}

enum_from_primitive! {
    enum Mlx90614Registers {
        RAW1 = 0x04,
        RAW2 = 0x05,
        TA = 0x06,
        TOBJ1 = 0x07,
        TOBJ2 = 0x08,
        EMISSIVITY = 0x24,
        CONFIG = 0x25,
    }
}

pub struct Mlx90614SMBus<'a> {
    smbus_temp: &'a dyn i2c::SMBusDevice,
    callback: OptionalCell<Callback>,
    temperature_client: OptionalCell<&'a dyn sensors::TemperatureClient>,
    buffer: TakeCell<'static, [u8]>,
    state: Cell<State>,
}

impl<'a> Mlx90614SMBus<'_> {
    pub fn new(
        smbus_temp: &'a dyn i2c::SMBusDevice,
        buffer: &'static mut [u8],
    ) -> Mlx90614SMBus<'a> {
        Mlx90614SMBus {
            smbus_temp,
            callback: OptionalCell::empty(),
            temperature_client: OptionalCell::empty(),
            buffer: TakeCell::new(buffer),
            state: Cell::new(State::Idle),
        }
    }

    fn is_present(&self) {
        self.state.set(State::IsPresent);
        self.buffer.take().map(|buf| {
            // turn on i2c to send commands
            buf[0] = Mlx90614Registers::RAW1 as u8;
            self.smbus_temp.smbus_write_read(buf, 1, 1).unwrap();
        });
    }

    fn read_ambient_temperature(&self) {
        self.state.set(State::ReadAmbientTemp);
        self.buffer.take().map(|buf| {
            buf[0] = Mlx90614Registers::TA as u8;
            self.smbus_temp.smbus_write_read(buf, 1, 1).unwrap();
        });
    }

    fn read_object_temperature(&self) {
        self.state.set(State::ReadObjTemp);
        self.buffer.take().map(|buf| {
            buf[0] = Mlx90614Registers::TOBJ1 as u8;
            self.smbus_temp.smbus_write_read(buf, 1, 2).unwrap();
        });
    }
}

impl<'a> i2c::I2CClient for Mlx90614SMBus<'a> {
    fn command_complete(&self, buffer: &'static mut [u8], error: Error) {
        match self.state.get() {
            State::Idle => {
                self.buffer.replace(buffer);
            }
            State::IsPresent => {
                let present = if error == Error::CommandComplete && buffer[0] == 60 {
                    true
                } else {
                    false
                };

                self.callback.map(|callback| {
                    callback.schedule(if present { 1 } else { 0 }, 0, 0);
                });
                self.buffer.replace(buffer);
                self.state.set(State::Idle);
            }
            State::ReadAmbientTemp | State::ReadObjTemp => {
                let mut temp: usize = 0;

                let values = if error == Error::CommandComplete {
                    // Convert to centi celsius
                    temp = ((buffer[0] as usize | (buffer[1] as usize) << 8) * 2) - 27300;
                    self.temperature_client.map(|client| {
                        client.callback(temp as usize);
                    });
                    true
                } else {
                    self.temperature_client.map(|client| {
                        client.callback(0);
                    });
                    false
                };
                if values {
                    self.callback.map(|callback| {
                        callback.schedule(temp, 0, 0);
                    });
                } else {
                    self.callback.map(|callback| {
                        callback.schedule(0, 0, 0);
                    });
                }
                self.buffer.replace(buffer);
                self.state.set(State::Idle);
            }
        }
    }
}

impl<'a> Driver for Mlx90614SMBus<'a> {
    fn command(&self, command_num: usize, _data1: usize, _data2: usize, _: AppId) -> ReturnCode {
        match command_num {
            0 => ReturnCode::SUCCESS,
            // Check is sensor is correctly connected
            1 => {
                if self.state.get() == State::Idle {
                    self.is_present();
                    ReturnCode::SUCCESS
                } else {
                    ReturnCode::EBUSY
                }
            }
            // Read Ambient Temperature
            2 => {
                if self.state.get() == State::Idle {
                    self.read_ambient_temperature();
                    ReturnCode::SUCCESS
                } else {
                    ReturnCode::EBUSY
                }
            }
            // Read Object Temperature
            3 => {
                if self.state.get() == State::Idle {
                    self.read_object_temperature();
                    ReturnCode::SUCCESS
                } else {
                    ReturnCode::EBUSY
                }
            }
            // default
            _ => ReturnCode::ENOSUPPORT,
        }
    }

    fn subscribe(
        &self,
        subscribe_num: usize,
        callback: Option<Callback>,
        _app_id: AppId,
    ) -> ReturnCode {
        match subscribe_num {
            0 /* set the one shot callback */ => {
				self.callback.insert(callback);
				ReturnCode::SUCCESS
			},
            // default
            _ => ReturnCode::ENOSUPPORT,
        }
    }
}

impl<'a> sensors::TemperatureDriver<'a> for Mlx90614SMBus<'a> {
    fn set_client(&self, temperature_client: &'a dyn sensors::TemperatureClient) {
        self.temperature_client.replace(temperature_client);
    }

    fn read_temperature(&self) -> ReturnCode {
        self.read_object_temperature();
        ReturnCode::SUCCESS
    }
}
