//#include <ESP8266WiFi.h>//este para esp8266



/*
#include <SimpleDHT.h>
#include <Wire.h>
#include <Adafruit_BMP085.h>
*/
#include "MqttSensManager.h"
#include "MqttVarManager.h"
#include "MqttUtiles.h"

MqttSensor::MqttSensor()
{
  
}
//*******************************************************************
MqttSensArray::MqttSensArray()
{
  n=0;
}

MqttSensor* MqttSensArray:: Get(int i)
{
  return &(sens[i]);
}


int MqttSensArray::Add(MqttSensor* var)
{
  sens[n]=*var;
  n++;
  return n-1;
}
//*******************************************************************
MqttSensManager::MqttSensManager()
{
  
  n_inter=0;
  bloqueo_sens=false;
  tiempo_sens=0;
  incre_tsens=15*1000;//por defecto 15 segundos
  n_inter=0;
  pMqttSensManager=this;
}

void MqttSensManager::Config(MqttVarManager* var)
{
  vars=var;
}

MqttSensor* MqttSensManager::Get(int i)
{
  
}
int MqttSensManager::Add(MqttSensor* var)
{
  
}

void MqttSensManager::inicia()
{
  
}
void MqttSensManager::inicia(int i)
{
  
}
void MqttSensManager::loop()
{
  

  if(bloqueo_sens)
    return;
  procesaInterrupciones();

  if(MqttUtiles::pasa_incre(&tiempo_sens, incre_tsens))
  {
    procesaSens();   
  }
}

void MqttSensManager::AddSensor(MqttSensor* sens)
{
  
}
void MqttSensManager::AddDin(int pin, char* topic)
{
  MqttSensor s;
  s.tipo=(int)MqttSensor::SENS_DIGI_IN;
  s.pin=pin;
  s.ivar=vars->AddVar((byte)(MqttVar::IN_VAR|MqttVar::ACCION_VAR),topic);
  sens.Add(&s);
  pinMode(s.pin, INPUT);
  ConfiguraInterrupcion(n_inter++);
  
}
void MqttSensManager::AddDinAccion(int pin, char* topic)
{
  MqttSensor s;
  s.tipo=(int)MqttSensor::SENS_DIGI_IN_PULSANTE;
  s.pin=pin;
  s.ivar=vars->AddVar((byte)MqttVar::ACCION_VAR,topic);
  sens.Add(&s);
  pinMode(s.pin, INPUT);
  ConfiguraInterrupcion(n_inter++);
}
void MqttSensManager::AddHDT22(int pin, char* topic)
{
  char buffer_t[32];
  MqttSensor s;
  s.tipo=(int)MqttSensor::SENS_DHT22;
  s.pin=pin;
  s.ie.dht.p=&cdht;
  sprintf(buffer_t, "%s/t", topic);
  s.ivar=vars->AddVar((byte)MqttVar::IN_VAR| MqttVar::FLOAT_VAR,buffer_t);//variable temperatura
  sprintf(buffer_t, "%s/h", topic);
  s.ie.dht.ivarH=vars->AddVar((byte)MqttVar::IN_VAR| MqttVar::FLOAT_VAR,buffer_t);//variable humedad
  sens.Add(&s);
}

void MqttSensManager::AddBMP180(int sda,int scl, char* topic)
{
  /*
  if(bmppillado)
  return;
  bmppillado=true;
  */
  
  char buffer_t[32];
  MqttSensor s;
  s.tipo=(int)MqttSensor::SENS_BMP180;
  s.pin=sda;
  s.ie.bmp.p=bmp;
  s.ie.bmp.pinScl=scl;
  sprintf(buffer_t, "%s/t", topic);
  s.ivar=vars->AddVar((byte)MqttVar::IN_VAR | MqttVar::FLOAT_VAR,buffer_t);//variable temperatura
  sprintf(buffer_t, "%s/p", topic);
  s.ie.bmp.ivarP=vars->AddVar((byte)MqttVar::IN_VAR,buffer_t);//variable presion
  sprintf(buffer_t, "%s/a", topic);
  s.ie.bmp.ivarA=vars->AddVar((byte)MqttVar::IN_VAR| MqttVar::FLOAT_VAR,buffer_t);//variable altura
  sens.Add(&s);


  //inicia------------------
  Wire.begin( s.pin,s.ie.bmp.pinScl);
  int i=0;
  while(!bmp->begin(), i<300)
  {
     i++;
     delay(10);
  }
}
void MqttSensManager::procesaSens()
{
   for(int i=0; i<sens.n; i++)
      procesaSensor(i);

}
void MqttSensManager::procesaInterrupciones()
{
   bool res=false;
   for(int i=0; i<n_inter; i++)
   {
      MqttSensor* s=sens.Get(ind_interrup[i]);
      if(s->ie.din.change)
      {
        noInterrupts();
        s->ie.din.change=false;
        interrupts();
        //lee variable
        MqttVar *v=vars->Get(s->ivar);
        switch((int)s->tipo)
        {
          case((int)MqttSensor::SENS_DIGI_IN):
          {
            //lee y llama a cambio si es necesario
            byte val=digitalRead(s->pin);
            if(val!=v->val.i)
            {
              v->val.i=val;
              vars->OnChange(s->ivar);
            }
            break;
          }
          case((int)MqttSensor::SENS_DIGI_IN_PULSANTE):
          {
            //lee y llama a cambio si es necesario
            byte val=digitalRead(s->pin);
            v->val.i=val;
            vars->OnChange(s->ivar);
            
            break;
          }
          default:
            break;
        }
      }
   }
}

void MqttSensManager::procesaSensor(int i)
{
  MqttSensor *s=sens.Get(i);
  MqttVar *v=vars->Get(s->ivar);
  switch((int)s->tipo)
  {
    case((int)MqttSensor::SENS_DHT22)://pilla temperatura y humedad
    {
      MqttVar *vh=vars->Get(s->ie.dht.ivarH);
      float t,h;
      for(int i=0; i<4; i++)
      {
        if (s->ie.dht.p->read2(s->pin, &t, &h, NULL) != SimpleDHTErrSuccess)
        {
          delay(20);
          continue;
        }
        v->val.f=t;
        vh->val.f=h;
        break;
      }
      break;
   }
   case((int)MqttSensor::SENS_BMP180)://pilla temperatura y humedad
   {
      MqttVar *vp=vars->Get(s->ie.bmp.ivarP);
      MqttVar *va=vars->Get(s->ie.bmp.ivarA);
      v->val.f=s->ie.bmp.p->readTemperature();
      vp->val.i=s->ie.bmp.p->readPressure();//pascales;
      va->val.f=s->ie.bmp.p->readAltitude();
   }
  default:
    {
      break;
    }
  }
}

 //funciones auxiliares de interrupcion-------------------------------
 void MqttSensManager::OnInterrupcion(int i)
 {
  MqttSensor* s=sens.Get(ind_interrup[i]);
   s->ie.din.change=true;
 }
 void MqttSensManager::ConfiguraInterrupcion(int i)
 {
    int pin=sens.Get(ind_interrup[i])->pin;
    switch(i)
  {
     case(0):
     attachInterrupt(digitalPinToInterrupt(pin), MqttSensManagerInterrupcion0, CHANGE);
     break;
      case(1):
     attachInterrupt(digitalPinToInterrupt(pin), MqttSensManagerInterrupcion1, CHANGE);
     break;
      case(2):
     attachInterrupt(digitalPinToInterrupt(pin), MqttSensManagerInterrupcion2, CHANGE);
     break;
      case(3):
     attachInterrupt(digitalPinToInterrupt(pin), MqttSensManagerInterrupcion3, CHANGE);
     break;
      case(4):
     attachInterrupt(digitalPinToInterrupt(pin), MqttSensManagerInterrupcion4, CHANGE);
     break;
      case(5):
     attachInterrupt(digitalPinToInterrupt(pin), MqttSensManagerInterrupcion5, CHANGE);
     break;
      case(6):
     attachInterrupt(digitalPinToInterrupt(pin), MqttSensManagerInterrupcion6, CHANGE);
     break;
      case(7):
     attachInterrupt(digitalPinToInterrupt(pin), MqttSensManagerInterrupcion7, CHANGE);
     break;
      case(8):
     attachInterrupt(digitalPinToInterrupt(pin), MqttSensManagerInterrupcion8, CHANGE);
     break;
      case(9):
     attachInterrupt(digitalPinToInterrupt(pin), MqttSensManagerInterrupcion9, CHANGE);
     break;
      case(10):
     attachInterrupt(digitalPinToInterrupt(pin), MqttSensManagerInterrupcion10, CHANGE);
     break;
      case(11):
     attachInterrupt(digitalPinToInterrupt(pin), MqttSensManagerInterrupcion11, CHANGE);
     break;
      case(12):
     attachInterrupt(digitalPinToInterrupt(pin), MqttSensManagerInterrupcion12, CHANGE);
    break;
  }
  
 }
 //chapuza que no se como hacerlo de otra manera
 ICACHE_RAM_ATTR void MqttSensManagerInterrupcion0()
 {
    MqttSensManager::pMqttSensManager->OnInterrupcion(0);
 }
 
 ICACHE_RAM_ATTR void MqttSensManagerInterrupcion1()
 {
     MqttSensManager::pMqttSensManager->OnInterrupcion(1);
 }
 ICACHE_RAM_ATTR void MqttSensManagerInterrupcion2()
 {
     MqttSensManager::pMqttSensManager->OnInterrupcion(2);
 }
 ICACHE_RAM_ATTR void MqttSensManagerInterrupcion3()
 {
     MqttSensManager::pMqttSensManager->OnInterrupcion(3);
 }
 ICACHE_RAM_ATTR void MqttSensManagerInterrupcion4()
 {
     MqttSensManager::pMqttSensManager->OnInterrupcion(4);
 }
 ICACHE_RAM_ATTR void MqttSensManagerInterrupcion5()
 {
    MqttSensManager::pMqttSensManager->OnInterrupcion(5);
 }
 ICACHE_RAM_ATTR void MqttSensManagerInterrupcion6()
 {
     MqttSensManager::pMqttSensManager->OnInterrupcion(6);
 }
 ICACHE_RAM_ATTR void MqttSensManagerInterrupcion7()
 {
     MqttSensManager::pMqttSensManager->OnInterrupcion(7);
 }
 ICACHE_RAM_ATTR void MqttSensManagerInterrupcion8()
 {
     MqttSensManager::pMqttSensManager->OnInterrupcion(8);
 }
 ICACHE_RAM_ATTR void MqttSensManagerInterrupcion9()
 {
     MqttSensManager::pMqttSensManager->OnInterrupcion(9);
 }
ICACHE_RAM_ATTR void MqttSensManagerInterrupcion10()
 {
    MqttSensManager::pMqttSensManager->OnInterrupcion(10);
 }
 ICACHE_RAM_ATTR void MqttSensManagerInterrupcion11()
 {
     MqttSensManager::pMqttSensManager->OnInterrupcion(11);
 }
 ICACHE_RAM_ATTR void MqttSensManagerInterrupcion12()
 {
    MqttSensManager::pMqttSensManager->OnInterrupcion(12);
 }
