#include <LiquidCrystal.h> //LCD Lybrary 


// Pins
  const int ledRPin = 8;       // Red LED pin
  const int ledGPin = 9;       // Green LED pin
  const int ledBPin = 10;       // Blue LED pin
  const int SoundSensor_OUT_PIN = 11;
  const int valve = 12;       // Valve
  const int airpump = 13;      // Airpump

  const int enA = A1;
  const int enB = A4;

  const int in1 = A5;
  const int in2 = A0;
  const int in3 = A2;
  const int in4 = A3;



// constants

  const unsigned long datePeriod = 300000; // duration date 
  const unsigned long afterDatePeriod = 305000; // after date date period
  const int SAMPLE_TIME = 2000;
  const int balloonExplosion = 30000;
  const int rs = 2, en = 3, d4 = 4, d5 = 5, d6 = 6, d7 = 7;
  LiquidCrystal lcd(rs, en, d4, d5, d6, d7);

// make some custom characters:
  byte Heart[8] = {
  0b00000,
  0b01010,
  0b11111,
  0b11111,
  0b01110,
  0b00100,
  0b00000,
  0b00000
  };

  byte Sound[8] = {
  0b00001,
  0b00011,
  0b00101,
  0b01001,
  0b01001,
  0b01011,
  0b11011,
  0b11000
  };

  byte Alien[8] = {
  0b11111,
  0b10101,
  0b11111,
  0b11111,
  0b01110,
  0b01010,
  0b11011,
  0b00000
  };

  byte Skull[8] = {
  0b00000,
  0b01110,
  0b10101,
  0b11011,
  0b01110,
  0b01110,
  0b00000,
  0b00000
  };

  byte Smiley[8] = {
  0b00000,
  0b00000,
  0b01010,
  0b00000,
  0b00000,
  0b10001,
  0b01110,
  0b00000
  };


// Variables will change:


  unsigned long sampleBufferValue = 0;

  unsigned long millisCurrent;
  unsigned long millisLast = 0;
  unsigned long millisElapsed = 0;
  unsigned long startDateTime = 0;
  unsigned long previousDateTime = 0;
  unsigned long LcdTime = 0;





void setup() {
  
  Serial.begin(9600);



  lcd.begin(16, 2);

  // create a new character
  lcd.createChar(0, Heart);
  lcd.createChar(1, Sound);
  lcd.createChar(2, Alien);
  lcd.createChar(3, Skull);
  lcd.createChar(4, Smiley);

  pinMode(airpump, OUTPUT);
  pinMode(valve, OUTPUT);
  
  pinMode(ledRPin, OUTPUT);
  pinMode(ledGPin, OUTPUT);
  pinMode(ledBPin, OUTPUT);

  pinMode(enA, OUTPUT);
  pinMode(enB, OUTPUT);

  pinMode(in1, OUTPUT);
  pinMode(in2, OUTPUT);
  pinMode(in3, OUTPUT);
  pinMode(in4, OUTPUT);

  // Turn off motors - Initial state
  digitalWrite(in1, LOW);
	digitalWrite(in2, LOW);
	digitalWrite(in3, LOW);
	digitalWrite(in4, LOW);

  //LCD Display
  lcd.setCursor(1, 0);
  lcd.print("Welcome Date!");
  lcd.setCursor(0, 1);
  lcd.write(byte(4));    //smiley
  lcd.setCursor(2, 1);
  lcd.print("Try me!");  
  lcd.setCursor(15, 1);
  lcd.write(byte(4));    //smiley

  delay(3000);

  lcd.clear();
}

void loop() {

 //start date time
  startDateTime = millis();

  if ((startDateTime - previousDateTime) <= datePeriod) {

    //LCD Display
    lcd.setCursor(1, 0);
    lcd.print("Date or Die!");
    lcd.setCursor(0, 1);
    lcd.write(byte(2));    //alien
    lcd.setCursor(5, 1);

    LcdTime = (datePeriod - (startDateTime - previousDateTime)) / 1000;
    if (LcdTime >= 100){
        lcd.setCursor(7, 1);
        lcd.print(LcdTime);
      }
      else if (LcdTime<100&& LcdTime>=10){
        lcd.setCursor(7, 1);
        lcd.print(" ");
        lcd.setCursor(8, 1);
        lcd.print(LcdTime);
      }
      else{
        lcd.setCursor(8, 1);
        lcd.print(" ");
        lcd.setCursor(9, 1);
        lcd.print(LcdTime);
      }
    lcd.setCursor(15, 1);
    lcd.write(byte(1));    //sound

    Serial.println(digitalRead(airpump));

    millisCurrent = millis();
    millisElapsed = millisCurrent - millisLast;

    if (digitalRead(SoundSensor_OUT_PIN) == LOW) {    //Reads the sound sensor 
      sampleBufferValue++;                            //Increases buffer value
    }

    if (millisElapsed > SAMPLE_TIME) {
      Serial.println(sampleBufferValue);


        //loud - if the value is more than 0
        if (sampleBufferValue > 0) {
      

        // valve off
        digitalWrite(valve, LOW);

        //air pump on
        digitalWrite(enA, HIGH);
        digitalWrite(enB, HIGH);
        	// Turn on motor A & B
	      digitalWrite(in1, HIGH);
        digitalWrite(in2, LOW);
        digitalWrite(in3, HIGH);
        digitalWrite(in4, LOW);

        //LED on green
        digitalWrite(ledRPin, LOW);
        digitalWrite(ledGPin, HIGH);
        digitalWrite(ledBPin, LOW);

        //super loud - balloon exploded
          if (sampleBufferValue > balloonExplosion) {

            //clear lcd
            lcd.clear();

            //LCD Display
            lcd.setCursor(1, 0);
            lcd.print("KISS!!");
            lcd.setCursor(0, 1);
            lcd.write(byte(0));    //heart
            lcd.setCursor(5, 1);
            lcd.print("KISS!!"); 
            lcd.setCursor(15, 1);
            lcd.write(byte(0));    //heart

            //wait for 10 sec
            delay(1000);

            //reset time
            previousDateTime = startDateTime;
            
          }
        }
        else {

        // Red
        digitalWrite(ledRPin, HIGH);
        digitalWrite(ledGPin, LOW);
        digitalWrite(ledBPin, LOW);

        // valve open
        digitalWrite(valve, HIGH);
        //air pump off
        digitalWrite(enA, LOW);
        digitalWrite(enB, LOW);
        // Turn off motors
        digitalWrite(in1, LOW);
        digitalWrite(in2, LOW);
        digitalWrite(in3, LOW);
        digitalWrite(in4, LOW);

        }    

      sampleBufferValue = 0;
      millisLast = millisCurrent;
    }
  }
  else {

    //clear lcd
    lcd.clear();

    if ((startDateTime - previousDateTime) <= afterDatePeriod) {

      //deflate balloon
      // valve open
      digitalWrite(valve, HIGH);
      //air pump off
      digitalWrite(enA, LOW);
      digitalWrite(enB, LOW);
      // Turn off motors
      digitalWrite(in1, LOW);
      digitalWrite(in2, LOW);
      digitalWrite(in3, LOW);
      digitalWrite(in4, LOW);      

      //LCD Display
      lcd.setCursor(1, 0);
      lcd.print("KISS!!  or");
      lcd.setCursor(0, 1);
      lcd.write(byte(0));    //heart
      lcd.setCursor(5, 1);
      lcd.print("RUN!!"); 
      lcd.setCursor(15, 1);
      lcd.write(byte(3));    //skull
    }
  else  {

    //reset time
      previousDateTime = startDateTime;

    //clear lcd
    lcd.clear();
    }
  }
}
  