// importing the Libraries: Download "Adafruit SD1306" and the "Adafruit GFX Library"
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define SCREEN_WIDTH 128  // OLED display width, in pixels
#define SCREEN_HEIGHT 64  // OLED display height, in pixels

#define SCREEN_ADDRESS 0x3C  // Oled Display's Address

Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);

// Change The Setting Acording To your Setup. If you Followed the Instructions, No need to Change Anythi
#define unitChangePin 5
#define PotPin1 2
#define PotPin2 6
#define corner_resetPin 4

const int pulsePerRound = 21;
const float circumference = 15;
const float corner = (circumference / 3.1415);
int cornerTimeGoal = 1500;

// Some variables use in Program
int pulseCounter;
float cm;
int unit = 0;
int cornercount;
unsigned long premilli;
bool buttonPresedBefore = false;

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);  // Start Serial Com

  if (!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) {
    Serial.println(F("SSD1306 allocation failed"));
    for (;;)
      ;
  }

  display.clearDisplay();  // Clear Display
  display.display();


  display.setTextColor(WHITE);
  display.setRotation(3);  // Rotate the screen: 0 = 0° ,1 = 90° , 2 = 180° ,3 = 270°

  attachInterrupt(digitalPinToInterrupt(PotPin1), rotaryPot, RISING);//Attaching Interupt 
  pinMode(corner_resetPin, INPUT_PULLUP);
}

void loop() {
  // put your main code here, to run repeatedly:
  cm = abs(pulseCounter) * (circumference / pulsePerRound) + (cornercount * corner);  // Convert Pulses 

  if (!digitalRead(unitChangePin)) { //if Unit Changing Button Clicked
    unit++;
    if (unit == 2) {
      unit = 0;
    }
    Serial.print("Unit Changed! ");
    Serial.println(unit);
    delay(300); //De-bounce delay
  }



  if (!digitalRead(corner_resetPin)) {//We are Checking if the Button is Being Held or Clicked

    if (!buttonPresedBefore) {
      buttonPresedBefore = true;
      delay(100);
      premilli = millis();
    }

  } else {
    if (buttonPresedBefore) {
      if (millis() - premilli > cornerTimeGoal) {
        Serial.println(millis() - premilli);
        buttonPresedBefore = false;

        cornercount++;
        Serial.print("Corner Counter is Set to:");// How many Times are we Going to Multiply the corner 
        Serial.println(cornercount);

      } else {
        buttonPresedBefore = false;

        pulseCounter = 0;
        cornercount = 0;
        Serial.println("Reseting Data...");
      }
    }
  }






  // This is the Part where We are Displaying Stuff

  display.clearDisplay();// Clearing Display For New Data
  display.drawRect(0, 0, 64, 128, 1);// Make the UI look better



  if (unit == 0) {// Making the Correct Measurements and Setting and Display them
    display.setTextSize(3);
    display.setCursor(18, 20);
    if (cm < 10) {
      display.print("0" + String(cm));
    } else if (cm < 100) {
      display.print(String(cm, 2));
    } else {
      display.print(String(99.99, 2));
    }
    display.setCursor(15, 80);
    display.print("CM");

  } else if (unit == 1) {

    display.setTextSize(3);
    display.setCursor(15, 15);

    display.print(String(int(cm / 100)) + ".");

    display.setCursor(15, 40);
    char buffer[10];
    if ((int(cm) - (int(cm / 100) * 100)) < 10) {
      sprintf(buffer, "0%i", (int(cm) - (int(cm / 100) * 100)));
      display.print(buffer);

    } else if ((int(cm) - (int(cm / 100) * 100)) >= 10) {
      display.print(int(cm) - (int(cm / 100) * 100));
    }
    display.setCursor(22, 75);
    display.setTextSize(4);
    display.print("M");
  }


  if (buttonPresedBefore) {// 3 Dots Animation

    if (cornerTimeGoal / 3 < millis() - premilli) {
      display.drawPixel(22, 110, 1);
    }
    if (cornerTimeGoal * 2 / 3 < millis() - premilli) {
      display.drawPixel(32, 110, 1);
    }
    if (cornerTimeGoal < millis() - premilli) {
      display.drawPixel(42, 110, 1);
    }
  }

  display.display(); // Display EVERYTHING!
}


void rotaryPot() {// Function to Get the Pulses From the Rotary Pot by Interrupt

  if (digitalRead(PotPin2) == HIGH) {
    pulseCounter++;
    delay(10);
  }
  if (digitalRead(PotPin2) == LOW) {
    pulseCounter--;
    delay(10);
  }
}