#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <Adafruit_AM2320.h>
#include <RTClib.h>

/*
  Multifuntional display powered by UNO and various 
  peripherals
  OLED Temperature and Humidity Meter
  oled-temp-humid-meter.ino
  Displays results on 128 x 64 OLED display
  Uses AM2320 I2C Temperature and Humidity sensor
  Uses Adafruit SSD1306 OLED Library
  Uses Adafruit AM2320 Library
  Uses Adafruit GFX Graphics Library
*/

// Reset pin not used but needed for library
#define OLED_RESET 5
Adafruit_SSD1306 display(OLED_RESET);
RTC_DS1307 rtc;
//Rotary encoder pins
#define ENCODER_CLK 2
#define ENCODER_DT  4
#define ENCODER_BTN 3

//NTC "beta" parameter
const float BETA = 3950; 

// Define object am2320
//Adafruit_AM2320 am2320 = Adafruit_AM2320();
DateTime now = rtc.now();
int menuItem = 0;

void setup() {

  // Start Serial
  //Serial.begin(9600);

  //Set encoder pins as inputs
  pinMode(ENCODER_CLK, INPUT);
  pinMode(ENCODER_DT, INPUT);
  pinMode(ENCODER_BTN, INPUT_PULLUP);

  //Attaching interupt on encoder event 
  attachInterrupt(digitalPinToInterrupt(ENCODER_CLK), readEncoderRot, FALLING);
  attachInterrupt(digitalPinToInterrupt(ENCODER_BTN), readEncoderBut, CHANGE);

  // Start Wire library for I2C
  Wire.begin();

  
  // initialize OLED with I2C addr 0x3C
  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
  
  // Initialize Temp & Humid Sensor
  //am2320.begin();
}

// Get the menuItem value, disabling interrupts.
// This make sure readEncoderRot() doesn't change the value
// while we're reading it.
int getCounter() {
  int result;
  noInterrupts();
  result = menuItem;
  interrupts();
  return result;
}

void displayDate () {

  char daysOfTheWeek[7][12] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};


  Serial.print("Current Date: ");
  Serial.print(daysOfTheWeek[now.dayOfTheWeek()]);
  Serial.print(" ");
  Serial.print(now.day(), DEC);
  Serial.print('/');
  Serial.print(now.month(), DEC);
  Serial.print('/');
  Serial.print(now.year(), DEC);

  Serial.println();
  delay(500);
}

void displayTime () {
  
  String title = "------TIME------";
  int h, m, s = 0;

  //if (now.hour() < 10) 
  //  Serial.print(0);
  h = (now.hour(), DEC);
  //Serial.print(':');
  //if (now.minute() < 10) 
  //  Serial.print(0);
  m = (now.minute(), DEC);
  //Serial.print(':');
  //  if (now.second() < 10) 
  //  Serial.print(0);
  //Serial.print(now.second(), DEC);
  //Serial.println();


  displayItem(title,h,s,"H","M");
  //delay(500);
}

void readEncoderRot() {
  int dtValue = digitalRead(ENCODER_DT);
  if (dtValue == HIGH) {
    //Next Menu Item "Rotated clockwise "
    menuItem++ ;
  }
  if (dtValue == LOW) {
    //Previous Menu Item "Rotated counterclockwise"
    menuItem-- ;
  }
}

void readEncoderBut() {
  if (digitalRead(ENCODER_BTN) == LOW) { //press event
  digitalWrite(LED_BUILTIN, HIGH); //press action
  } 
  else {
  digitalWrite(LED_BUILTIN, LOW);
  }
}

void displayTempHumidIn(){
  // Title
  String title = "----IN----";

  // Read temperature as Celsius
  int analogValue = analogRead(A0);
  float t = 1 / (log(1 / (1023. / analogValue - 1)) / BETA + 1.0 / 298.15) - 273.15;

  //delay(50);
  // Read Humidity
  float h = 47.0;

  displayItem(title,t,h,"°C","%");

}

void displayTempHumidOut(){
  // Title
  String title = "----OUT----";

  // Read temperature as Celsius
  int analogValue = analogRead(A0);
  float t = 1 / (log(1 / (1023. / analogValue - 1)) / BETA + 1.0 / 298.15) - 273.15;

  delay(50);
  // Read Humidity
  float h = 15.02;

  displayItem(title,t,h,"°C","%");
}

void displayItem(String title, float item1, float item2, String units1, String units2){
  // Clear the display
  display.clearDisplay();
  //Set the color - always use white despite actual display color
  display.setTextColor(WHITE);
  //Set the font size
  display.setTextSize(1);
  //Set the cursor coordinates
  display.setCursor(0,0);
  display.print(title);
  display.print(menuItem);
  display.setCursor(0,10); 
  display.print("H: "); 
  display.print(item1);
  display.print(units1);
  display.print(" T: "); 
  display.print(item2);
  display.print(units2);
  display.setCursor(0,20);
  //display.print("<- IN");
  //display.print("  ");
  //display.print("IN ->");
}

int displayMenuItem(int menuItem) {
  switch (menuItem) {
  case 0:
    displayTempHumidOut();
    break;
  case 1:
    displayTempHumidIn();
    break;
  case 2:
    displayTime();
    break;
  default:
    return menuItem = 0;
    break;
}
}

void loop() {
  displayMenuItem(getCounter());
  display.display();
}
GND5VSDASCLSQWRTCDS1307+