#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <DHT.h>
#include <RTClib.h>
#include <AsyncDelay.h>

#define ver 0.04

#define I2C_SDA 3
#define I2C_SCL 2 

#define displayAddress 0x3C
#define DHT_Type DHT22

#define refreshSpeed 333        //(ms) Time before screen scrolls
#define utcOffset -6 * 3600     //(hr) Coordinated Universal Time (UTC) offset
#define utcDST 0 * 1000         //(hr) Daylight Savings 
#define timeUpdate 24 * 360000  //(hr) Updating from server interval

#define DHT_Pin 18
#define buttonPin 4
#define ledPin 5
#define conFan 0
#define ledFan 1
#define peltierHot 6
#define peltireCold 7

RTC_DS1307 rtc;

TwoWire I2C(0);
DHT dht(DHT_Pin, DHT_Type);
Adafruit_SSD1306 display(128, 64, &I2C, -1);

AsyncDelay refreshDelay;
AsyncDelay timeFetch;
AsyncDelay wifiTimeOut;

int Yscrl = 10;           //Screen Scroll offset
char sign = 'C';
float temp = 00.00f;
bool isF = true;
float humid = 00.00f;
bool buttonState = false;
bool buttonNew = true;

/*Analog values for PWM control*/
int conFanSpeed = 255;    //Range from 0 to 255
int ledFanSpeed = 255;    //Range from 0 to 255
int led = 255;            //Range from 0 to 255
int peltier = 0;          //Range from -255 to 255


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

  pinMode(buttonPin, INPUT);
  pinMode(ledPin, OUTPUT);

  I2C.begin(I2C_SDA, I2C_SCL, 400000);
  rtc.begin(&I2C);
  dht.begin();

  display.begin(SSD1306_SWITCHCAPVCC, displayAddress);
  display.cp437(true); //all printable ASCII
  display.setTextSize(1);
  display.setTextColor(WHITE);
  display.setCursor(0,0);
  display.dim(true);
  display.clearDisplay();


  refreshDelay.start(refreshSpeed, AsyncDelay::MILLIS);
  timeFetch.start(timeUpdate, AsyncDelay::MILLIS);

  /*just pretend that these are the values from the PID controller that cleary exists in this file */
  conFanSpeed = 186;
  ledFanSpeed = 175;
}

void loop() {
  buttonState = digitalRead(buttonPin);
  if (buttonState == LOW) {
    buttonNew = true;
    digitalWrite(ledPin, LOW);
  } else if (buttonState == HIGH && buttonNew) {
    isF = !isF;
    buttonNew = false;
    digitalWrite(ledPin, HIGH);
    displayInfo();
  }

  if (refreshDelay.isExpired()) {
    humid = dht.readHumidity();
    temp = dht.readTemperature(isF); 

    displayInfo();

    Yscrl = (Yscrl + 1) % 64; //Moves screen down by 1 pixel

   
    refreshDelay.repeat();
  }
}

void scroll(String text, int X, int Y) {
  int pos = (Yscrl + Y) % 64;

  if (pos < 8 || pos > 56) {
    display.setCursor(X, pos - 7);
    display.println(text);
    display.setCursor(X, pos + 57);
    display.println(text);
  } else {
    display.setCursor(X, pos - 7);
    display.println(text);
  }
}

void displayInfo() {
  char time[] = "hh:mm:ssap";
  char date[] = "MM-DD-YY";

  display.clearDisplay();
  scroll("Planter Box     v" + String(ver), 1, 0);
  display.drawFastHLine(0, (Yscrl) % 64 + 1, 128, WHITE);
  scroll(rtc.now().toString(time), 1, 16); 
  scroll(rtc.now().toString(date), 78, 16);         
  scroll("T:" + String(temp) + char(248) + (isF ? 'F' : 'C'), 1, 32);
  scroll("Fan:" + String(String(double (conFanSpeed) / 255)), 80, 32);
  scroll("H:" + String(humid) + "%", 1, 48);
  scroll("LED:" + String(double (ledFanSpeed) / 255), 80, 48);  
  display.display();
}

GND5VSDASCLSQWRTCDS1307+