#include "Ads1115V2.h"
#define ADSV2_DEBUG

Ads1115V2::Ads1115V2() : ads1(ADS1115_ADDRESS_ADDR_GND), ads2(ADS1115_ADDRESS_ADDR_VDD)
{
  #ifdef ADSV2_DEBUG
  Serial.println("Ads1115 constructor called");
  #endif
}

Ads1115V2::~Ads1115V2()
{
  
}

void Ads1115V2::begin()
{
  #ifdef ADSV2_DEBUG
  Serial.println("Ads1115V2 : begin");
  #endif
  Wire.begin();
  //We set the adcs up:
  ads1.initialize();
  ads2.initialize();
  ads1.setMode(ADS1115_MODE_SINGLESHOT);
  ads2.setMode(ADS1115_MODE_SINGLESHOT);
  ads1.setRate(ADS1115_RATE_250);
  ads2.setRate(ADS1115_RATE_250);
  ads1.setGain(ADS1115_PGA_4P096);
  ads2.setGain(ADS1115_PGA_4P096);
}

double Ads1115V2::getQuantum()
{
  return 0.125;
}

double Ads1115V2::sampleValue(int16_t channel, boolean sgl)
{
  double total(0);
  for(int i(0); i < getAdcSetting().getMeasureIteration(); i++)
  {
    delay(getAdcSetting().getDelayBetweenIteration());
    total += getReading(channel, sgl);
  }

  //We divide
  total /= (double)getAdcSetting().getMeasureIteration();
  
  //We return
  return total;
}

double Ads1115V2::sampleValue()
{
  return sampleValue(-1);
}

double Ads1115V2::sampleVoltage(int16_t channel, boolean sgl)
{
  return sampleValue(channel, sgl)*0.125;
}

double Ads1115V2::sampleVoltage()
{
  return sampleValue()*0.125;
}

uint16_t Ads1115V2::getReading(int16_t channel, boolean sgl)
{
  int16_t chan(channel == -1 ? _lastChannel : channel);

  _lastChannel = chan > 8 ? 0 : chan;

  if(chan < 4)
  {
    ads1.setMultiplexer(chan+4);
    return ads1.getConversion(true);
  }
  else if(chan < 8)
  {
    ads2.setMultiplexer(chan);
    return ads2.getConversion(true);
  }
  else return 0;
}


//Async part
void Ads1115V2::startSample(int16_t channel, boolean sgl)
{
  switch(_state)
  {
    case IDLING:
      _state = SAMPLING;
      _elapsedTime = millis();
      _sampledValue = 0.0;
      _numOfSamples = 0;
      //We set the last channel attribute
      if(channel != -1)
      {
        _lastChannel = channel > 8 ? _lastChannel : channel;
      }
      
      break;
    case SAMPLING:
      //If enough time elapsed, we can sample a value again
      if(millis() - _elapsedTime > getAdcSetting().getDelayBetweenIteration())
      {
        _sampledValue += getReading(channel, sgl);
        _elapsedTime = millis();
        _numOfSamples ++;
      }

      //All samples are done:
      if(_numOfSamples == getAdcSetting().getMeasureIteration())
      {
        _sampledValue /= (double)_numOfSamples;
        _sampledValue += channel > 3 ? 82.0 : 0.0;
        _state = RESULT_READY;
      }
      break;
  }
}

void Ads1115V2::startSample()
{
  startSample(-1);
}

double Ads1115V2::getSampleVoltage()
{
  return getSampleValue() * 0.125;
}
