// this example will play a Track 002 in folder 007 
// when light is on the LDR
// it expects the sd card to contain some mp3 files
// LDR is connected with Resistor 10K in series
// Free LDR leg is connected to 5V
//    other end of R10K is connected to GND
//    joined LDR leg and R10k is connected to pin A0
// LED is connected to pin D2,3,4,5
// Servo connected to pin 9

#include <SoftwareSerial.h>
#include <DFMiniMp3.h>
#include <Servo.h>

#define DEBUG 0
// implement a notification class,
// its member methods will get called 
//
class Mp3Notify
{
public:
  static void OnError(uint16_t errorCode)
  {
    // see DfMp3_Error for code meaning
    Serial.println();
    Serial.print("Com Error ");
    Serial.println(errorCode);
  }
  static void OnPlayFinished(uint16_t track)
  {
    Serial.print("Play finished for #");
    Serial.println(track);  
  }
  static void OnCardOnline(uint16_t code)
  {
    Serial.println("Card online ");
  }
  static void OnCardInserted(uint16_t code)
  {
    Serial.println("Card inserted ");
  }
  static void OnCardRemoved(uint16_t code)
  {
    Serial.println("Card removed ");
  }
};

// instance a DFMiniMp3 object, 
// defined with the above notification class and the hardware serial class
//
//DFMiniMp3<HardwareSerial, Mp3Notify> mp3(Serial1);

// Some arduino boards only have one hardware serial port, so a software serial port is needed instead.
// comment out the above definition and uncomment these lines
SoftwareSerial secondarySerial(10, 11); // RX, TX
DFMiniMp3<SoftwareSerial, Mp3Notify> mp3(secondarySerial);

Servo myservo;  // create servo object to control a servo
int pos = 0;    // variable to store servo position

const int LDRpin = A0;       // LDR connected to pin A0
const int EyeCommon = 6;    // low = off
const int Eyepin = 2;      // Eye LED pin D23
const int Chest1 = 3;
const int Chest2 = 4;
const int Chest3 = 5;
int Song=2;                 //sd:/07/002.mp3
int ldrStatus;
boolean onStatus = true;
boolean takeLowTime; 
//the timer to reset song
long unsigned int timeoutTimer = 0, resetCount = 0;  
//the amount of milliseconds the sensor has to be low 
//before we assume all motion has stopped
long unsigned int pause = 2000; 

void setup() 
{
  
  Serial.begin(115200);
  if (DEBUG) Serial.println("initializing...");
  pinMode(LDRpin, INPUT);     // setup LDR
  pinMode(EyeCommon, OUTPUT);
  pinMode(Eyepin, OUTPUT);
  pinMode(Chest1, OUTPUT);
  pinMode(Chest2, OUTPUT);
  pinMode(Chest3, OUTPUT);

  mp3.begin();
  mp3.reset(); 
  
  // show some properties and set the volume
  uint16_t volume = mp3.getVolume();
  Serial.print("volume ");
  Serial.println(volume);
  mp3.setVolume(20);
  
  uint16_t count = mp3.getTotalTrackCount();
  Serial.print("files ");
  Serial.println(count);

  uint16_t mode = mp3.getPlaybackMode();
  Serial.print("playback mode ");
  Serial.println(mode);
  
  if (DEBUG) Serial.println("starting...");
  mp3.playFolderTrack(7, Song);
  myservo.attach(9);  // attaches the servo on pin 9 to the servo object

}

void loop() 
{
    for (pos = 0; pos <= 90; pos += 1) { // goes from 0 degrees to 90 degrees
      // in steps of 1 degree
      myservo.write(pos);              // tell servo to go to position in variable 'pos'
      delay(15);                       // waits 15ms for the servo to reach the position
    }
    for (pos = 90; pos >= 0; pos -= 1) { // goes from 90 degrees to 0 degrees
      myservo.write(pos);              // tell servo to go to position in variable 'pos'
      delay(15);                       // waits 15ms for the servo to reach the position
    }
  ldrStatus = analogRead(LDRpin);
  //Serial.println(ldrStatus);
  if (ldrStatus > 200){       //light up when open
    //digitalWrite(LED_BUILTIN, LOW);
    digitalWrite(EyeCommon, LOW); // eye LED had different polarity so that
    digitalWrite(Eyepin, HIGH);   // only one eyes can be on at one time
    delay(100);
    digitalWrite(EyeCommon, HIGH);
    digitalWrite(Eyepin, LOW);
    timeoutTimer ++;
    //Serial.print("LED Light");
    if (DEBUG) Serial.println(timeoutTimer);
    mp3.start();
    digitalWrite(Chest1, LOW);  // chest LED had common cable connected
    digitalWrite(Chest2, HIGH); // my common cable is connected to Anode
    digitalWrite(Chest3, HIGH); // so EyeCommon needs to be HIGH
    delay(100);
    digitalWrite(Chest1, HIGH);
    digitalWrite(Chest2, LOW);
    digitalWrite(Chest3, HIGH);
    delay(100);
    digitalWrite(Chest1, HIGH);
    digitalWrite(Chest2, HIGH);
    digitalWrite(Chest3, LOW);
    delay(100);
    digitalWrite(Chest1, HIGH);
    digitalWrite(Chest2, LOW);
    digitalWrite(Chest3, HIGH);
    delay(100);

    onStatus = true;
    if (timeoutTimer > 200) {
      if (DEBUG) Serial.println(timeoutTimer);
      timeoutTimer = 0;
      resetCount = 0;
    } 
  } else {
    digitalWrite(EyeCommon, LOW);
    digitalWrite(Eyepin, HIGH);
    digitalWrite(Chest1, HIGH);
    digitalWrite(Chest2, HIGH);
    digitalWrite(Chest3, HIGH);    mp3.pause();
    timeoutTimer ++;
    /*if (timeoutTimer <= 200 && timeoutTimer > 50){
      resetCount ++;
      timeoutTimer = 0;
      Serial.println(resetCount);
      if (resetCount = 3){
        resetCount =  0;
        mp3.playFolderTrack(6, Song);
      }
    } else{
      timeoutTimer = 0;
    }*/
  }
  // calling mp3.loop() periodically allows for notifications 
  // to be handled without interrupts
  mp3.loop();
}
