#include "ltr390.h"


/****************************************************************/
bool LTR390::Initialize() {
    bool success(true);

    success &= ReadChipID();

    if(success) {
        WriteSettings();
    }
    m_initialized = success;
    return m_initialized;
}


/****************************************************************/
bool LTR390::ReadChipID() {
    uint8_t id;

    ReadRegister(ID_ADDR, &id, 1);

    switch(id) {
    case ChipModel_LTR390_REV0:
        m_chip_model = ChipModel_LTR390_REV0;
        break;
    case ChipModel_LTR390_REV1:
        m_chip_model = ChipModel_LTR390_REV1;
        break;
    case ChipModel_LTR390_REV2:
        m_chip_model = ChipModel_LTR390_REV2;
        break;
    case ChipModel_LTR390_REV3:
        m_chip_model = ChipModel_LTR390_REV3;
        break;
    default:
        m_chip_model = ChipModel_UNKNOWN;
        return false;
    }

    return true;
}


/****************************************************************/
void LTR390::WriteSettings() {
    WriteRegister(MAIN_CTRL, LTR390_ON | LTR390_MODE_UVS);
    WriteRegister(MEAS_RATE, LTR390_RESOLUTION_16BIT | LTR390_RATE_1000);
    WriteRegister(GAIN, LTR390_GAIN_18);

    // WriteRegister(THRESH_LOW, 100);
    // WriteRegister(THRESH_UP, 1000);
    // WriteRegister(INT_CFG, 0x30 | 0x04);
}


/****************************************************************/
bool LTR390::begin() {
    bool success = Initialize();
    success &= m_initialized;
    return success;
}

/****************************************************************/
bool LTR390::reset() {
    WriteRegister(RESET_ADDR, RESET_VALUE);
    delay(10); //max. startup time according to datasheet
    return(begin());
}

/****************************************************************/
bool LTR390::ReadData(int32_t data[SENSOR_DATA_LENGTH], uint32_t addr) {
    bool success;
    uint8_t buffer[SENSOR_DATA_LENGTH];

    // WriteSettings();

    success = ReadRegister(addr, buffer, SENSOR_DATA_LENGTH);

    for(int i = 0; i < SENSOR_DATA_LENGTH; ++i) {
        data[i] = static_cast<int32_t>(buffer[i]);
    }

    return success;
}


/****************************************************************/
uint32_t LTR390::uv() {
    if(!m_initialized) return 0;

    int32_t data[SENSOR_DATA_LENGTH];
    if(!ReadData(data, UVSDATA)) {
        return 0;
    }
    uint32_t rawUV = (data[2] << 16) | (data[1] << 8) | (data[0]);
    return rawUV;
}

void LTR390::read(uint32_t& uvs, uint32_t& uvi) {
    if(!m_initialized) return;
    uvs = uv();
    uvi = (uvs/ 2300)*2;
}


/****************************************************************/
LTR390::ChipModel LTR390::chipModel() {
    return m_chip_model;
}


/****************************************************************/
bool LTR390::WriteRegister(uint8_t addr, uint8_t data) {
    i2c->beginTransmission(LTR390_ADDRESS);
    i2c->write(addr);
    i2c->write(data);
    i2c->endTransmission();

    return true;
}


/****************************************************************/
bool LTR390::ReadRegister(uint8_t addr,uint8_t data[],uint8_t length) {
    uint8_t ord(0);

    i2c->beginTransmission(LTR390_ADDRESS);
    i2c->write(addr);
    i2c->endTransmission();

    i2c->requestFrom(static_cast<uint8_t>(LTR390_ADDRESS), length);

    while(i2c->available()) {
        data[ord++] = i2c->read();
    }

    return ord == length;
}