/*You will need to install the Adafruit Neopixel library which can be found in the library manager.
 * RTClib.h used which can be downloaded from the library manager
 * IRremote library used to integerate with the IR remote and sensor this library is also available in the library manager
 * 
*/

#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
#endif
#include <IRremote.h>
#include "RTClib.h"
//Object of DS1307
RTC_DS1307 rtc;
// Create a variable to hold the time data 
#define PIN_RECEIVER 2   // Signal Pin of IR receiver
//Different Variables Defined of DateTime 
DateTime zeroTime;
DateTime Alpha=DateTime(2017,7,16,0,59,59);
DateTime Beta=DateTime(2017,7,16,0,0,0);
  DateTime Now = rtc.now();
//Receiver Object Defined
IRrecv receiver(PIN_RECEIVER);

// Which pin on the Arduino is connected to the NeoPixels?
#define LEDCLOCK_PIN    6

// How many NeoPixels are attached to the Arduino?
#define LEDCLOCK_COUNT 116

//(red * 65536) + (green * 256) + blue ->for 32-bit merged colour value so 16777215 equals white
// or 3 hex byte 00 -> ff for RGB eg 0x123456 for red=12(hex) green=34(hex), and green=56(hex) 
// this hex method is the same as html colour codes just with "0x" instead of "#" in front
uint32_t clockMinuteColour = 0x800000; // pure red 
uint32_t clockhourColour = 0x008000;   // pure green

// Declare our NeoPixel objects:
Adafruit_NeoPixel stripClock(LEDCLOCK_COUNT, LEDCLOCK_PIN, NEO_GRB + NEO_KHZ800);
// Argument 1 = Number of pixels in NeoPixel strip
// Argument 2 = Arduino pin number (most are valid)
// Argument 3 = Pixel type flags, add together as needed:
//   NEO_KHZ800  800 KHz bitstream (most NeoPixel products w/WS2812 LEDs)
//   NEO_KHZ400  400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers)
//   NEO_GRB     Pixels are wired for GRB bitstream (most NeoPixel products)
//   NEO_RGB     Pixels are wired for RGB bitstream (v1 FLORA pixels, not v2)
//   NEO_RGBW    Pixels are wired for RGBW bitstream (NeoPixel RGBW products)


void setup() {

 receiver.enableIRIn(); // Start the receiver
 Serial.begin(115200);
    if (! rtc.begin()) {
    Serial.println("Couldn't find RTC");
    Serial.flush();
    abort();
    }
    rtc.adjust(zeroTime);
  stripClock.begin();           // INITIALIZE NeoPixel stripClock object (REQUIRED)
  stripClock.show();            // Turn OFF all pixels ASAP
  stripClock.setBrightness(50); // Set inital BRIGHTNESS (max = 255)
}
void loop() {
DateTime Now = rtc.now(); 
int minute=Alpha.minute()-Now.minute();
int second=Alpha.second()-Now.second();
abs(minute);
abs(second);
Beta=DateTime(2017,7,16,0,minute,second);
  if (receiver.decode()) {
    if(receiver.decodedIRData.command==48)
{

 Beta=decrement(Beta,1);
 int min2=Now.minute();
 min2=min2+1;                                    //One minute is decremented
 int sc=Now.second();
   rtc.adjust(DateTime(2017, 7, 16, 0, min2, sc));
}
if(receiver.decodedIRData.command==24)
{
 Beta=decrement(Beta,5);
 int min2=Now.minute();                                     
 min2=min2+5;                                   //Five minutes penalized if button 2 is pressed
 int sc=Now.second();
   rtc.adjust(DateTime(2017, 7, 16, 0, min2, sc));
}
if(receiver.decodedIRData.command==122)
{
Beta=increment(Beta);
int min2=Now.minute();
if(min2>=5)
{                                               //Five Bonus Minutes if button 3 is pressed
min2=min2-5;

}
if(Beta.minute()==59)
{
  min2=0;
}
if(Beta.minute()==58)
{
  min2=1;
}
if(Beta.minute()==57)
{
  min2=2;
}
if(Beta.minute()==56)
{
  min2=3;
}
if(Beta.minute()==55)
{
  min2=4;
}
int sc=Now.second();
rtc.adjust(DateTime(2017, 7, 16, 0, min2, sc));
}
if(receiver.decodedIRData.command==16)
{
 int min2=Now.minute();   //24
 int min3=min2+1;         //25
 while(min3-min2>=1)
 {
  DateTime now = rtc.now();
  min2=Now.minute(); 
  displayTheTime(Beta,1);
  stripClock.show();
  delay(200);

 }
}
  receiver.resume();  // Receive the next value
  }
  //display the time on the LEDs
  displayTheTime(Beta,0);
  stripClock.show();
  //(red * 65536) + (green * 256) + blue ->for 32-bit merged colour value so 16777215 equals white
  delay(500);   //this 5 second delay to slow things down during testing
}
//Functions to increment and decrement when the buttons are pressed
DateTime increment(DateTime z)
{
int minut=z.minute();

minut=minut+5;

int hour=0;
if(minut>=59)
{
minut=59;
}
int second=z.second();
z=DateTime(2017,7,16,hour,minut,second);

return z;
}
DateTime decrement(DateTime z,int decrement)
{
int minut=z.minute();
minut=minut-decrement;
int second;
if(minut<0)
{
second=0;
minut=0;
}
if(minut>0)
{
second=z.second();
}
z=DateTime(2017,7,16,0,minut,second);
return z;
}

void displayTheTime(DateTime r,int mode){                                     //Mode checking if random numbers are to be displayed if 4 is pressed
 if(mode==0)
 { stripClock.clear(); //clear the clock face 
  int firstMinuteDigit = r.minute()%10; //work out the value of the first digit and then display it
  displayNumber(firstMinuteDigit, 0, clockMinuteColour);
  int secondMinuteDigit = floor(r.minute() / 10); //work out the value for the second digit and then display it
  displayNumber(secondMinuteDigit, 63, clockMinuteColour);  
  int firsthourDigit = 0; //work out the value for the third digit and then display it
  displayNumber(firsthourDigit, 126, clockhourColour);
 }
if(mode==1)
{
stripClock.clear(); //clear the clock face 
  int digit=random(0, 59);
  int firstMinuteDigit = digit%10;
  displayNumber(firstMinuteDigit, 0, clockMinuteColour);
  int secondMinuteDigit = floor(digit / 10); //work out the value for the second digit and then display it
  displayNumber(secondMinuteDigit, 63, clockMinuteColour);  
  int firsthourDigit = 0; //work out the value for the third digit and then display it
  displayNumber(firsthourDigit, 126, clockhourColour);
}
}
   
void displayNumber(int digitToDisplay, int offsetBy, uint32_t colourToUse){
    switch (digitToDisplay){
    case 0:
    digitZero(offsetBy,colourToUse);
      break;
    case 1:
      digitOne(offsetBy,colourToUse);
      break;
    case 2:
    digitTwo(offsetBy,colourToUse);
      break;
    case 3:
    digitThree(offsetBy,colourToUse);
      break;
    case 4:
    digitFour(offsetBy,colourToUse);
      break;
    case 5:
    digitFive(offsetBy,colourToUse);
      break;
    case 6:
    digitSix(offsetBy,colourToUse);
      break;
    case 7:
    digitSeven(offsetBy,colourToUse);
      break;
    case 8:
    digitEight(offsetBy,colourToUse);
      break;
    case 9:
    digitNine(offsetBy,colourToUse);
      break;
    default:
     break;
  }
}
GND5VSDASCLSQWRTCDS1307+