//Pour module d'horloge RTC
#include <Wire.h>
#include <DS3231.h>

//Pour shield mp3 et carte sd
#include <SPI.h>           // SPI library
#include <SdFat.h>         // SDFat Library
#include <SFEMP3Shield.h>  // Mp3 Shield Library

// Création de l'objet carte sd permettant de gérer la carte sd
SdFat sd;
// Création de l'objet MP3
SFEMP3Shield MP3player; 
// Création de l'objet clock
DS3231 clock;
// Création de l'objet RTCDateTime pour stocker valeurs de l'horloge
RTCDateTime dt;

//CES DEUX VARIABLES SONT A GARDER COMME CA SANS LES MODIFIER
const uint8_t volume = 0; // MP3 Player volume 0=max, 255=lowest (off)
const uint16_t monoMode = 1;  // Mono setting 0=off, 3=max

int stopPin = A3;

void setup() {
//Ouverture de la liaison série pour communication avec l'ordinateur (affichage dans le moniteur série)
  Serial.begin(9600);
//Initialisation de l'horloge
  clock.begin();
//A conserver seulement si on veut remettre l'heure de l'ordinateur dans l'horloge (dans le cas où la 
//pile est morte pas exemple)
  //clock.setDateTime(__DATE__, __TIME__);

// Déclaration du bouton d'arrêt de son comme entrée (pas besoin de résistance car utilisation de "INPUT_PULLUP"
  pinMode(stopPin, INPUT_PULLUP);

//INITIALISATION de shield MP3 et de la carte sd

  initSD();  // Initialisation de la carte sd (cf fonction d'initalisation en bas du code)
  initMP3Player(); // Initialisation du shield MP3 (cd fonction d'initalisation en bas du code)
}

void loop() {

  // Stocke les données de date et d'heure de l'horloge dans la variable nommé dt
  dt = clock.getDateTime();

  //teste si on est en heure d'été
  if (DST(dt.year,dt.month,dt.day,dt.hour)) {
    add1hour(&dt);
  }

  //Affiche dans le moniteur série l'heure et les minutes
  Serial.print(dt.hour);
  Serial.print(":");
  Serial.print(dt.minute);
  Serial.print(":");
  Serial.println(dt.second);

  // A 09h30, la musique se lance : arrivée
  if ((dt.hour == 9) && (dt.minute==30)){
     MP3player.playMP3("piste001.mp3");
  }

  // Une minute plus tard (09h31), on arrête la musique.
  if ((dt.hour == 9) && (dt.minute==31)){
      MP3player.stopTrack(); // Arrête la musique
  }

  delay(1000); //attend une seconde avant de recommencer la boucle

  // A 10H50, la musique se lance
  if ((dt.hour == 10) && (dt.minute==50)){
     MP3player.playMP3("piste001.mp3");
  }

  // Une minute plus tard (10h51), on arrête la musique.
  if ((dt.hour == 10) && (dt.minute==51)){
      MP3player.stopTrack(); // Arrête la musique
  }

  delay(1000); //attend une seconde avant de recommencer la boucle

  // A 11H30, la musique se lance
  if ((dt.hour == 11) && (dt.minute==30)){
     MP3player.playMP3("piste001.mp3");
  }

  // Une minute plus tard (11h31), on arrête la musique.
  if ((dt.hour == 11) && (dt.minute==31)){
      MP3player.stopTrack(); // Arrête la musique
  }

  delay(1000); //attend une seconde avant de recommencer la boucle

  // A 13H, la musique se lance
  if ((dt.hour == 13) && (dt.minute==0)){
     MP3player.playMP3("piste001.mp3");
  }

  // Une minute plus tard (13h01), on arrête la musique.
  if ((dt.hour == 13) && (dt.minute==1)){
      MP3player.stopTrack(); // Arrête la musique
  }

  delay(1000); //attend une seconde avant de recommencer la boucle

  // A 14h30, la musique se lance
  if ((dt.hour == 14) && (dt.minute==30)){
     MP3player.playMP3("piste001.mp3");
  }

  // Une minute plus tard (14h31), on arrête la musique.
  if ((dt.hour == 14) && (dt.minute==31)){
      MP3player.stopTrack(); // Arrête la musique
  }

  delay(1000); //attend une seconde avant de recommencer la boucle

  // A 15h15, la musique se lance
  if ((dt.hour == 15) && (dt.minute==15)){
     MP3player.playMP3("piste001.mp3");
  }

  // Une minute plus tard (15h16), on arrête la musique.
  if ((dt.hour == 15) && (dt.minute==16)){
      MP3player.stopTrack(); // Arrête la musique
  }

  delay(1000); //attend une seconde avant de recommencer la boucle
}




/* LES FONCTIONS D'INITIALISATION de la carte sd et du shield MP3
 *  A GARDER COMME ELLES SONT SANS LES MODIFIER.
 */
 
//Fonction d'initialisation de la carte sd appelée dans le setup

void initSD()
{
  //Initialize the SdCard.
  if(!sd.begin(SD_SEL, SPI_HALF_SPEED)) 
    sd.initErrorHalt();
  if(!sd.chdir("/")) 
    sd.errorHalt("sd.chdir");
}

//Fonction d'initialisation de la carte sd appelée dans le setup

void initMP3Player()
{
  uint8_t result = MP3player.begin(); // init the mp3 player shield
  if(result != 0) // check result, see readme for error codes.
  {
    // Error checking can go here!
  }
  MP3player.setVolume(volume, volume);
  MP3player.setMonoMode(monoMode);
}


//Fonction de gestion du changement d'heure

uint8_t month_lastday(uint8_t year, uint8_t month)
{
  return (month==4 || month==6 || month==9 || month==11) ? 30 : (month==2 ? ((year&3) ? 28 : 29) : 31);
}

void add1hour(RTCDateTime *dt)
{
   if (dt->hour < 23)
  {
    dt->hour = dt->hour +1;
  }
  else
  {
    dt->hour = 0;
    if (dt->day < month_lastday(dt->year, dt->month))
    {
      dt->day = dt->day +1;
    }
    else
    {
      dt->day = 1;
      dt->month =  dt->month +1;
    }
  }
}

bool DST(uint8_t year, uint8_t month, uint8_t day, uint8_t hour) {
// daylight saving time return True if date is between march last sunday, 2 am and october last sunday 2am)

  const uint8_t MARS = 3;
  const uint8_t OCTOBRE = 10;
  if (month == MARS)
  {
    uint8_t dernierDimancheMars = 31 - ((4 + year + (year >> 2)) % 7); //Pas évidente à trouver celle-là
  return day > dernierDimancheMars || (day == dernierDimancheMars && hour > 1);
  }
  if (month == OCTOBRE)
  {
    uint8_t dernierDimancheOctobre = 31 - ((1 + year + (year >> 2)) % 7);
  return day < dernierDimancheOctobre || (day == dernierDimancheOctobre && hour < 3);
  }
  return MARS < month && month < OCTOBRE;
}
