#include <avr/pgmspace.h>
#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_ADXL345_U.h>
#include "meuh.h"
#include "digitalWriteFast.h"

//Pin connected to ST_CP of 74HC595
#define latchPin  8
//Pin connected to SH_CP of 74HC595
#define clockPin 12
////Pin connected to DS of 74HC595
#define dataPin  11

#define size_meuh 11692
#define min_mouv 7
int interval = 125;
/* Assign a unique ID to this sensor at the same time */
Adafruit_ADXL345_Unified accel = Adafruit_ADXL345_Unified(12345);

//struct audio
typedef struct
{
  unsigned char b0 : 1;
  unsigned char b1 : 1;
  unsigned char b2 : 1;
  unsigned char b3 : 1;
  unsigned char b4 : 1;
  unsigned char b5 : 1;
  unsigned char b6 : 1;
  unsigned char b7 : 1;
} bit_field;

typedef union
{
  bit_field bits;
  unsigned char a_word;
} audio_word;

void play_word(audio_word tmp)
{
  digitalWriteFast(latchPin, 0);
  //clear everything out just in case to
  //prepare shift register for bit shifting
  digitalWriteFast(dataPin, 0);
  digitalWriteFast(clockPin, 0);
  digitalWriteFast(dataPin, tmp.bits.b7);
  digitalWriteFast(clockPin, 1);
  digitalWriteFast(dataPin, 0);
  
  digitalWriteFast(clockPin, 0);
  digitalWriteFast(dataPin, tmp.bits.b6);
  digitalWriteFast(clockPin, 1);
  digitalWriteFast(dataPin, 0);

  digitalWriteFast(clockPin, 0);
  digitalWriteFast(dataPin, tmp.bits.b5);
  digitalWriteFast(clockPin, 1);
  digitalWriteFast(dataPin, 0);

  digitalWriteFast(clockPin, 0);
  digitalWriteFast(dataPin, tmp.bits.b4);
  digitalWriteFast(clockPin, 1);
  digitalWriteFast(dataPin, 0);

  digitalWriteFast(clockPin, 0);
  digitalWriteFast(dataPin, tmp.bits.b3);
  digitalWriteFast(clockPin, 1);
  digitalWriteFast(dataPin, 0);

  digitalWriteFast(clockPin, 0);
  digitalWriteFast(dataPin, tmp.bits.b2);
  digitalWriteFast(clockPin, 1);
  digitalWriteFast(dataPin, 0);

  digitalWriteFast(clockPin, 0);
  digitalWriteFast(dataPin, tmp.bits.b1);
  digitalWriteFast(clockPin, 1);
  digitalWriteFast(dataPin, 0);

  digitalWriteFast(clockPin, 0);
  digitalWriteFast(dataPin, tmp.bits.b0);
  digitalWriteFast(clockPin, 1);
  digitalWriteFast(dataPin, 0);

  digitalWriteFast(clockPin, 0);
  digitalWriteFast(latchPin, 1);

}

void play_music(void)
{
  int m = 0;
  unsigned long previousMicros = 0;
  unsigned long currentMicros = micros();
  audio_word tmp;
   
  while (m < size_meuh)
  {
    currentMicros = micros();

    if (currentMicros - previousMicros >= interval) {
      previousMicros = currentMicros;
      tmp.a_word = (int) pgm_read_byte_near(meuh + m);
      play_word(tmp);
      m++;
    }
  }
  tmp.a_word = 0x00;
  play_word(tmp);
}

void setup(void)
{
  Serial.begin(9600);
  Serial.println("Boite a meuh"); Serial.println("");

  pinModeFast(clockPin, OUTPUT);
  pinModeFast(dataPin, OUTPUT);
  pinModeFast(latchPin, OUTPUT);

  digitalWriteFast(latchPin, 0);

  /* Initialise the sensor */
  if (!accel.begin())
  {
    /* There was a problem detecting the ADXL345 ... check your connections */
    Serial.println("Ooops, no ADXL345 detected ... Check your wiring!");
    while (1);
  }

  /* Set the range to whatever is appropriate for your project */
  accel.setRange(ADXL345_RANGE_16_G);

}

void loop(void)
{
  /* Get a new sensor event */
  sensors_event_t event;
  accel.getEvent(&event);

  if ( (abs(event.acceleration.x) > min_mouv) || (abs(event.acceleration.y) > min_mouv) )
  {
    Serial.println("Maintenant :)");
    play_music();
  }

  //play_music();
  //while(1);

  delay(500);
}
