# include <Adafruit_MPU6050.h>
# include <Adafruit_Sensor.h>
# include <Wire.h>

const int ignitionPin = 2;
const int outputPin = 13;
const float accTriggerLevel = 13.0;

// const unsigned long delayTime = 1000UL * 60 * 20;   // twenty minutes
const unsigned long delayTime = 1000UL * 5;   // five seconds

unsigned long startTime;

enum { CAR_OFF, CAR_IDLE, CAR_MOVING, CAR_STOPPED, CAR_DELAY_OFF };
int state;

Adafruit_MPU6050 mpu;

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

  // Try to initialize!
  if (!mpu.begin()) {
    Serial.println("Failed to find MPU6050 chip");
    while (1) {
      delay(10);
    }
  }
  Serial.println("MPU6050 Found!");

  // set accelerometer range to +-8G
  mpu.setAccelerometerRange(MPU6050_RANGE_8_G);

  // set gyro range to +- 500 deg/s
  mpu.setGyroRange(MPU6050_RANGE_500_DEG);

  // set filter bandwidth to 21 Hz
  mpu.setFilterBandwidth(MPU6050_BAND_21_HZ);

  delay(100);

  pinMode(outputPin, OUTPUT);
  pinMode(ignitionPin, INPUT_PULLUP);

}

void loop() {
  /* Get new sensor events with the readings */
  sensors_event_t a, g, temp;
  mpu.getEvent(&a, &g, &temp);

  static unsigned long lastReportTime;

  // only report every second
  if ( millis() - lastReportTime >= 5000 ) {
    lastReportTime = millis();
    
     
    Serial.print("Acceleration X: ");
    Serial.print(a.acceleration.x);
    Serial.print(", Y: ");
    Serial.print(a.acceleration.y);
    Serial.print(", Z: ");
    Serial.print(a.acceleration.z);
    Serial.println(" m/s^2");
  
    Serial.print("Rotation X: ");
    Serial.print(g.gyro.x);
    Serial.print(", Y: ");
    Serial.print(g.gyro.y);
    Serial.print(", Z: ");
    Serial.print(g.gyro.z);
    Serial.println(" rad/s");
  
    Serial.print("Temperature: ");
    Serial.print(temp.temperature);
    Serial.println(" degC");
  
    Serial.println("");
    
  }
  
  float totalAcc = abs(a.acceleration.x) + abs(a.acceleration.y) + abs(a.acceleration.z);
  int ignitionState = digitalRead(ignitionPin);

  switch ( state ) {
  case CAR_OFF:
  // car is off, check to see if it is on and react

    if ( ignitionState == HIGH ) {
    // car is on
      digitalWrite(outputPin, HIGH);
      state = CAR_IDLE;
    }
    else digitalWrite(outputPin, LOW);

  break;
    case CAR_IDLE:
      // car is ON but not moving
      if (totalAcc > accTriggerLevel) {
        state = CAR_MOVING;
      }
      if (ignitionState == LOW ) {
        // car turned off
        state = CAR_DELAY_OFF;
        startTime = millis();
      }
      break;

    case CAR_MOVING:
      digitalWrite(outputPin, LOW);
      if (totalAcc <= accTriggerLevel) {
        // car has stopped
        state = CAR_STOPPED;
      }
      break;

    case CAR_STOPPED:
      if (totalAcc > accTriggerLevel) {
        state = CAR_MOVING;
        Serial.println("car moving again");
      }
      if (ignitionState == LOW ) {
        // car turned off
        state = CAR_DELAY_OFF;
        startTime = millis();
        digitalWrite(outputPin, HIGH);
      }
      else digitalWrite(outputPin, HIGH);

      break;

    case CAR_DELAY_OFF:
      // check timer and, if expired, we are OFF
      if ( millis() - startTime >= delayTime ) {
        state = CAR_OFF;
      }
      if (ignitionState == HIGH) {
        // car turned back on so reset
        state = CAR_OFF;
      }
      break;
  }
}