#include "SAB.h"

SAB::SAB() : _screenConfig(128, 64, 0x3C),
_sdCardConfig(SPI_FULL_SPEED), 
_display(_screenConfig.getWidth(), 
_screenConfig.getHeight(), &Wire), 
_screenManager(_display), _rtc(), 
_rtcManager(_rtc), _sdCardManager(), 
_connectivityManager(NULL), 
_webServerManager(80, &_sdCardManager),
_pcf(0x27, Wire),
_ioManager(_pcf),
_taskSchedulerManager(_rtcManager),
_error(0)
{
  //We set the gpio up
  initGPIO();
  //Serial.begin(9600);
  Serial.begin(115200, SERIAL_8N1, SERIAL_TX_ONLY);
  delay(200);
  
  //We initialize the pins for the  I2C communication
  Wire.begin(_pinConfig.getI2C_sda(), _pinConfig.getI2C_scl());
  if(!_rtc.begin()) _error |= RTC_BEGIN_ERR;
  if(!_display.begin(SSD1306_SWITCHCAPVCC, _screenConfig.getAddress())){ _error |= DISP_BEGIN_ERR; }
  if(!_sdCardManager.begin(_sdCardConfig.getSPISpeed(), _pinConfig.getSPI_sdCard_cs())){ _error |= SDCARD_INIT_ERR; Serial.print("Failed to init SDCard : SPI_SPEED : "); Serial.print(_sdCardConfig.getSPISpeed()); Serial.print(" CS PIN : "); Serial.println(_pinConfig.getSPI_sdCard_cs());}
  _connectivityManager = new ConnectivityManager(_sdCardManager);
  if(!_pcf.begin()){_error |= IO_INIT_ERR;}
}

SAB::SAB(const PinMapping pinConfig, const ScreenConfig screenConfig, const SDCardConfig sdCardConfig, const unsigned int webServerPort) : _pinConfig(pinConfig), 
_screenConfig(screenConfig), 
_sdCardConfig(sdCardConfig), 
_display(_screenConfig.getWidth(), _screenConfig.getHeight(), &Wire), 
_screenManager(_display), 
_rtc(), 
_rtcManager(_rtc), 
_sdCardManager(), 
_connectivityManager(NULL), 
_webServerManager(webServerPort, &_sdCardManager),
_pcf(0x27, Wire), 
_ioManager(_pcf),
_taskSchedulerManager(_rtcManager),
_error(0)
{
  //We set the gpio up
  initGPIO();
  //Serial.begin(9600);
  Serial.begin(115200, SERIAL_8N1, SERIAL_TX_ONLY);
  delay(200);
  //We initialize the pins for the  I2C communication
  Wire.begin(_pinConfig.getI2C_sda(), _pinConfig.getI2C_scl());
  if(!_rtc.begin()) _error |= RTC_BEGIN_ERR;
  if(!_display.begin(SSD1306_SWITCHCAPVCC, _screenConfig.getAddress())) _error |= DISP_BEGIN_ERR;
  if(!_sdCardManager.begin(_sdCardConfig.getSPISpeed(), _pinConfig.getSPI_sdCard_cs())){ _error |= SDCARD_INIT_ERR; Serial.print("Failed to init SDCard : SPI_SPEED : "); Serial.print(_sdCardConfig.getSPISpeed()); Serial.print(" CS PIN : "); Serial.println(_pinConfig.getSPI_sdCard_cs());}
  _connectivityManager = new ConnectivityManager(_sdCardManager);
  if(!_pcf.begin()){_error |= IO_INIT_ERR;}
}

void SAB::initGPIO()
{
  pinMode(GPIO_0, INPUT);
}

ScreenManager& SAB::getScreenManager()
{
  return _screenManager;
}

RtcManager& SAB::getRtcManager()
{
  return _rtcManager;
}

SDCardManager& SAB::getSdCardManager()
{
  return _sdCardManager;
}

ConnectivityManager& SAB::getConnectivityManager()
{
  return *_connectivityManager;
}

WEBServerManager& SAB::getWebServerManager()
{
  return _webServerManager;
}

IOManager& SAB::getIoManager()
{
  return _ioManager;
}

TaskSchedulerManager& SAB::getTaskSchedulerManager()
{
  return _taskSchedulerManager;
}

ScreenConfig SAB::getScreenConfig() const
{
  return _screenConfig;
}

PinMapping SAB::getPinConfig() const
{
  return _pinConfig;
}

SDCardConfig SAB::getSdCardConfig() const
{
  return _sdCardConfig;
}

PowerInfo SAB::getPowerInfo(const unsigned char nbOfMeasures) const
{
  uint16_t batteryMeasures(0), temp(0);
  unsigned char i(0);
  int checkLevel(0);
  PowerInfo p;

  for(;i < nbOfMeasures;i++)
  {
    temp = analogRead(ADC);
    batteryMeasures += temp;
  }
  
  batteryMeasures /= nbOfMeasures;
  
  if(batteryMeasures <= USB_THRESHOLD)
  {
    p.powerType = USB;
    p.level = 0;
  }
  else 
  {
    p.powerType = BATTERY; 
    checkLevel = ((double)(batteryMeasures-BATT_EMPTY)*100.0/(double)BATT_DIFF);
    
    if(checkLevel > 100)
      p.level = 100;
    else if (checkLevel < 0)
      p.level = 0;
    else
      p.level = checkLevel;
  }
  
  return p;
}

const char *SAB::getSoftVersion() const
{
  return SOFT_VERSION;
}

unsigned char SAB::getError() const
{
  return _error;
}
