#include "mbed.h"
#include "stm32746g_discovery_lcd.h"
#include "stm32746g_discovery_ts.h"
#include "MQ2.h"
#include "DS18B20.h"

#define ecran_initialisation 0
#define ecran_supervision 1
#define ecran_parametres 2
#define ecran_alarme 3
#define maj_value 255

//define pour les tailles et position de bouton
#define bt_param_tx 100
#define bt_param_ty 75
#define bt_param_px 350
#define bt_param_py 190

#define bt_test_tx 100
#define bt_test_ty 75
#define bt_test_px 100
#define bt_test_py 190

#define bt_retour_tx 100
#define bt_retour_ty 75
#define bt_retour_px 150
#define bt_retour_py 200

#define posX_barre_temp 50
#define posY_barre_temp 70
#define tY_barre_temp 10
#define tX_barre_temp 375

#define bt_oui_tx 75
#define bt_oui_ty 50
#define bt_oui_px 100
#define bt_oui_py 120
#define bt_nn_tx 75
#define bt_nn_ty 50
#define bt_nn_px 180
#define bt_nn_py 120

#define bt_ack_tx 300
#define bt_ack_ty 250
#define bt_ack_px 10
#define bt_ack_py 10




MQ2 MQ2(A0);
PwmOut buzzer(PB_4);
DigitalInOut sensor(D8);     // ds1820 connected to pin D8
Timer timer;                // used for our microsec timing



// definition des différents seuils à l'initialisation
uint16_t seuil_temp=50;
uint8_t seuil_fumee=20;

//variables globales de stockage pour tmp et fumee
float temperature;
float smoke;

int etat_detec_fum=0; //si 0 désactivé, si 1 activé

uint8_t switchEcran(uint8_t ecran);


int main()
{
    TS_StateTypeDef TS_State;
    uint16_t x, y;
    uint8_t text[30];
    char buf[50];
    
    uint8_t idx;
    uint8_t result;
    uint8_t cleared = 0;
    uint8_t prev_nb_touches = 0;
    uint8_t ecran = ecran_initialisation;
    uint8_t prec_ecran = 255;
    int ack_alarme=0;
    
 
    BSP_LCD_Init();
    BSP_LCD_LayerDefaultInit(LTDC_ACTIVE_LAYER, LCD_FB_START_ADDRESS);
    BSP_LCD_SelectLayer(LTDC_ACTIVE_LAYER);
    

   // BSP_LCD_SetFont(&Font12);//modification de la taille d'écriture
    //BSP_LCD_SetBackColor(LCD_COLOR_BLUE);//modification de la couleur de fond de l'ecriture
    //BSP_LCD_SetTextColor(LCD_COLOR_WHITE);//modification de la couleur de l'ecriture
    
    //init du MQ2
    printf("\n\r=====================================================\n\r");
    printf("MQ2 Configuration\n\r");
    MQ2.begin();
    
    //init ds1820 sensor
    printf("\n\r=====================================================\n\r");
    printf("DS18B20 Configuration\n\r");
    sensor.mode(PullUp);
    
    ROM_Code_t ROM_Code = ReadROM();
    printf("Family code: 0x%X\n\r", ROM_Code.BYTES.familyCode);
    printf("Serial Number: ");
    for (uint32_t i = 6; i != 0; --i) {
        printf("%02X%s", ROM_Code.BYTES.serialNo[i-1], (i != 1)?":":"\r\n");
    }
    printf("CRC: 0x%X\r\n", ROM_Code.BYTES.crc);
    printf("\n\rRunning temperature conversion...\n\r"); 
    
    
    //init pwm pour buzzer 
    printf("\n\r=====================================================\n\r");
    printf("Buzzer Configuration\n\r");
    buzzer = 0.0;
    buzzer.period_us(50);  
        while(1) 
        {   
            temperature = displayTemperature();
            smoke = MQ2.readSmoke();
            printf("smoke is %d\n\r", (int)(smoke));    // display in 2.1 format
            if(prec_ecran!=ecran) //pour le changement d'ecran
            {
                prec_ecran=ecran;
                ecran=switchEcran(ecran);
            }
            if(ecran==ecran_supervision)
            {
                BSP_LCD_SetFont(&Font24); //modification de la taille d'écriture
                sprintf(buf,"Temperature : %d C",(int)temperature);
                BSP_LCD_DisplayStringAt(0, LINE(3), (uint8_t *)buf, LEFT_MODE);
                sprintf(buf,"Fumee : %d  ppm",(int)smoke);
                BSP_LCD_DisplayStringAt(0, LINE(5), (uint8_t *)buf, LEFT_MODE);
                
                //gestion des alarmes >> si la temp depasse le seuil / si la fumee est detectee / si l'alarme n'a pas ete ack recement
                if ((temperature>= seuil_temp || (smoke >=20 && etat_detec_fum))&&ack_alarme==0)//
                {
                    printf("Alerte !\n\r");
                    ecran = ecran_alarme;
                }
            }
            
                
            BSP_TS_GetState(&TS_State);
            if (TS_State.touchDetected) //si on touche l'écran
            {
                x = TS_State.touchX[0];
                y = TS_State.touchY[0];     
                BSP_LCD_DrawPixel(TS_State.touchX[0], TS_State.touchY[0], LCD_COLOR_ORANGE);
                
                if(ecran==ecran_supervision) //si on est sur l'ecran de supervision
                {
                    if((x>=bt_param_px) && (x<=bt_param_px+bt_param_tx))
                    {
                        if((y>=bt_param_py)  && (y<=bt_param_py+bt_param_ty)) //si on appuie sur le bt parametre
                        {
                            ecran=ecran_parametres;
                            BSP_LCD_Clear(LCD_COLOR_RED);
                        }
                    }
                    if((x>=bt_test_px) && (x<=bt_test_px+bt_test_tx))
                    {
                        if((y>=bt_test_py)  && (y<=bt_test_py+bt_test_ty)) //si on appuie sur le bt de test alarm
                        {
                            ecran=ecran_alarme;
                            BSP_LCD_Clear(LCD_COLOR_RED);
                        }
                    }
                }
                
                else if(ecran==ecran_parametres) //si on est sur l'ecran de parametre
                {
                    
                    if((x>=bt_retour_px) && (x<=bt_retour_px+bt_retour_tx))
                    {
                        if((y>=bt_retour_py)  && (y<=bt_retour_py+bt_retour_ty))//si on appuie sur le bt retour a la supervision
                        {
                            ecran=ecran_supervision;
                            BSP_LCD_Clear(LCD_COLOR_RED);
                        }
                    }
                    
                    if((x>=posX_barre_temp) && (x<=posX_barre_temp+tX_barre_temp))
                    {
                        if((y>=posY_barre_temp)  && (y<=posY_barre_temp+tY_barre_temp))//si on appuie sur la barre de gestion de temperature
                        {
                            seuil_temp = (x - posX_barre_temp) /3;   //320 >> 320-50 = 270/3 = 90
                            if(seuil_temp<0)
                            {
                                seuil_temp=0;
                            }
                            else if(seuil_temp>125)
                            {
                                seuil_temp=125;
                            }
                            prec_ecran=maj_value;
                            BSP_LCD_Clear(LCD_COLOR_RED);
                        }
                    }
            
                    if((x>=bt_oui_px) && (x<=bt_oui_px+bt_oui_tx))
                    {
                        if((y>=bt_oui_py)  && (y<=bt_oui_py+bt_oui_ty))//si on appuie sur le bt oui
                        {
                            etat_detec_fum=1;
                            prec_ecran=maj_value;
                        }
                    }
                    if((x>=bt_nn_px) && (x<=bt_nn_px+bt_nn_tx))
                    {
                        if((y>=bt_nn_py)  && (y<=bt_nn_py+bt_nn_ty))//si on appuie sur le bt retour non
                        {
                            etat_detec_fum=0;
                            prec_ecran=maj_value;
                        }
                    }                         
                }
                else if(ecran==ecran_alarme)
                {
                    printf("Alarme ACK\n\r");
                    buzzer=0.0;
                    ack_alarme = 1;
                                       
                }         
            }
            if(ack_alarme == 1)
            {
                sprintf(buf,"Attente fin alerte");
                BSP_LCD_DisplayStringAt(0, LINE(6), (uint8_t *)buf, LEFT_MODE);
                HAL_Delay(5000);
                ack_alarme = 0;
                ecran=ecran_supervision;
                BSP_LCD_Clear(LCD_COLOR_RED); 
            }
        }
    
}
    
    uint8_t switchEcran(uint8_t ecran)
    {
        char buf[50];
        uint8_t status;
        uint16_t temp_affiche;
        
        switch(ecran)
        {
            case ecran_initialisation:   
                // 1er affichage
                BSP_LCD_SetFont(&Font20); //modification de la taille d'écriture
                BSP_LCD_Clear(LCD_COLOR_RED); //modification de la couleur de fond de l'écran
                BSP_LCD_SetBackColor(LCD_COLOR_RED); //modification de la couleur de fond de l'ecriture
                BSP_LCD_DisplayStringAt(0, LINE(5), (uint8_t *)"SYSTEME DE DETECTION INCENDIE", CENTER_MODE);
                BSP_LCD_DisplayStringAt(0, LINE(0), (uint8_t *)"Emeline Genest", RIGHT_MODE);
                HAL_Delay(2000);
                
                status = BSP_TS_Init(BSP_LCD_GetXSize(), BSP_LCD_GetYSize());
                if (status != TS_OK) {
                    BSP_LCD_Clear(LCD_COLOR_ORANGE);
                    BSP_LCD_SetBackColor(LCD_COLOR_RED);
                    BSP_LCD_SetTextColor(LCD_COLOR_WHITE);
                    BSP_LCD_DisplayStringAt(0, LINE(5), (uint8_t *)"TOUCHSCREEN INIT FAIL", CENTER_MODE);
                } else {
                    BSP_LCD_Clear(LCD_COLOR_GREEN);
                    BSP_LCD_SetBackColor(LCD_COLOR_GREEN);
                    BSP_LCD_SetTextColor(LCD_COLOR_WHITE);
                    BSP_LCD_DisplayStringAt(0, LINE(5), (uint8_t *)"TOUCHSCREEN INIT OK", CENTER_MODE);
                    ecran = ecran_supervision;
                    //ecran = ecran_alarme;
                    BSP_LCD_Clear(LCD_COLOR_RED);
                    
                }
                
                
                break;
                
            case ecran_supervision:
                BSP_LCD_SetTextColor(LCD_COLOR_WHITE);//modification de la couleur de l'ecriture
                BSP_LCD_FillRect( bt_param_px,  bt_param_py,  bt_param_tx,  bt_param_ty);
                BSP_LCD_FillRect( bt_test_px,  bt_test_py,  bt_test_tx,  bt_test_ty);
                BSP_LCD_SetFont(&Font12); //modification de la taille d'écriture
                BSP_LCD_SetTextColor(LCD_COLOR_BLACK);//modification de la couleur de l'ecriture
                BSP_LCD_SetBackColor(LCD_COLOR_WHITE); //modification de la couleur de fond de l'ecriture
                BSP_LCD_DisplayStringAt(bt_test_px, bt_test_py, (uint8_t *)"Test Alarme", LEFT_MODE);
                BSP_LCD_DisplayStringAt(bt_param_tx+250, bt_param_py, (uint8_t *)"Parametres", LEFT_MODE);
                
                BSP_LCD_SetFont(&Font16); //modification de la taille d'écriture
                BSP_LCD_SetBackColor(LCD_COLOR_RED); //modification de la couleur de fond de l'ecriture
                BSP_LCD_SetTextColor(LCD_COLOR_WHITE);//modification de la couleur de l'ecriture
                
                BSP_LCD_DisplayStringAt(0, LINE(0), (uint8_t *)"Ecran de supervision : ", CENTER_MODE);
                break;
            
            case ecran_parametres:
                
                BSP_LCD_SetTextColor(LCD_COLOR_WHITE);//modification de la couleur de l'ecriture
                BSP_LCD_SetBackColor(LCD_COLOR_RED); //modification de la couleur de fond de l'ecriture
                
                BSP_LCD_FillRect( bt_retour_px,  bt_retour_py,  bt_retour_tx,  bt_retour_ty);
                //on veut prendre la température de 0 à 125, proportionnellement, on affichera a échelle *3 pour le max : 125*3 = 375
                temp_affiche = seuil_temp * 3;  //90*3 = 270
                BSP_LCD_FillRect( posX_barre_temp, posY_barre_temp ,  tX_barre_temp,  tY_barre_temp);
                BSP_LCD_FillCircle(temp_affiche+posX_barre_temp,75,10);
                
                BSP_LCD_SetFont(&Font16); //modification de la taille d'écriture
                
                sprintf(buf,"Seuil de temperature : %d C",seuil_temp);
                BSP_LCD_DisplayStringAt(0, LINE(3), (uint8_t *)buf, LEFT_MODE);
                BSP_LCD_DisplayStringAt(posX_barre_temp-20, posY_barre_temp+5, (uint8_t *)"0", LEFT_MODE);
                BSP_LCD_DisplayStringAt(posX_barre_temp+tX_barre_temp+10, posY_barre_temp+5, (uint8_t *)"125", LEFT_MODE);
                BSP_LCD_DisplayStringAt(0, LINE(0), (uint8_t *)"Ecran des parametres : ", CENTER_MODE);
                BSP_LCD_DisplayStringAt(0, LINE(6), (uint8_t *)"Detection de la fumee : ", LEFT_MODE);
                
                //gestion de l'affichage de la detection de fumee
                if(etat_detec_fum)
                {
                    BSP_LCD_SetTextColor(LCD_COLOR_GREEN);//modification de la couleur de l'ecriture
                    BSP_LCD_FillRect( bt_oui_px,  bt_oui_py,  bt_oui_tx,  bt_oui_ty);
                    BSP_LCD_SetTextColor(LCD_COLOR_WHITE);//modification de la couleur de l'ecriture
                    BSP_LCD_FillRect( bt_nn_px,  bt_nn_py,  bt_nn_tx,  bt_nn_ty);
                } 
                else
                {
                    BSP_LCD_SetTextColor(LCD_COLOR_WHITE);//modification de la couleur de l'ecriture
                    BSP_LCD_FillRect( bt_oui_px,  bt_oui_py,  bt_oui_tx,  bt_oui_ty);
                    BSP_LCD_SetTextColor(LCD_COLOR_GREEN);//modification de la couleur de l'ecriture
                    BSP_LCD_FillRect( bt_nn_px,  bt_nn_py,  bt_nn_tx,  bt_nn_ty);
                }
                BSP_LCD_SetTextColor(LCD_COLOR_BLACK);//modification de la couleur de l'ecriture
                BSP_LCD_DisplayStringAt(bt_oui_px+20, bt_oui_py+50, (uint8_t *)"OUI", LEFT_MODE);
                BSP_LCD_DisplayStringAt(bt_nn_px+20, bt_nn_py+50, (uint8_t *)"NON", LEFT_MODE);
                BSP_LCD_SetBackColor(LCD_COLOR_WHITE); //modification de la couleur de fond de l'ecriture
                BSP_LCD_DisplayStringAt(bt_retour_px+10, bt_retour_py+20, (uint8_t *)"Retour", LEFT_MODE);
                break;
                
            case ecran_alarme:
                BSP_LCD_Clear(LCD_COLOR_ORANGE);
                
                BSP_LCD_DisplayStringAt(0, LINE(0), (uint8_t *)"ALARME !", CENTER_MODE);
                BSP_LCD_SetFont(&Font16); //modification de la taille d'écriture
                BSP_LCD_DisplayStringAt(0, LINE(5), (uint8_t *)"Appuie sur l'ecran pour acquitter l'alarme", CENTER_MODE);
                buzzer = 1.0;
                break;
        }
    return ecran;
}
 