#include <Wire.h>
#include <SPI.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 OLED_RESET     4 // Reset pin # (or -1 if sharing Arduino reset pin)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

const int ANALOG_INPUT_PIN = A0;
const int MIN_ANALOG_INPUT = 0;
const int MAX_ANALOG_INPUT = 100;
const int DELAY_LOOP_MS = 5;            // change to slow down how often to read and graph value

int _circularBuffer[SCREEN_WIDTH];      //fast way to store values 
int _curWriteIndex = 0;                 // tracks where we are in the circular buffer

unsigned long _frameCount = 0;

int _graphHeight = SCREEN_HEIGHT;

void setup() {
  display.begin(SSD1306_SWITCHCAPVCC, 0x3C); 
  
  display.clearDisplay();
  display.setTextSize(1);                      //1, 2, 3, 4, 5
  display.setTextColor(WHITE);                 //WHITE or BLACK, WHITE
  display.setCursor(30 ,20);                   // Text start position x, y pixel
  display.println("Display Test"); 
  display.display();
  delay(2000);
}

void loop() {
  display.clearDisplay();

  int analogVal = analogRead(ANALOG_INPUT_PIN);  // Read and store the analog data into a circular buffer
  Serial.println(analogVal);
  _circularBuffer[_curWriteIndex++] = analogVal;

  if(_curWriteIndex >= display.width()){  // Set the circular buffer index back to zero when it reaches the right of the screen
    _curWriteIndex = 0;
  }
  
  int xPos = 0; 
  for (int i = _curWriteIndex; i < display.width(); i++){  // Draw the line graph based on data in _circularBuffer
    int analogVal = _circularBuffer[i];
    drawLine(xPos, analogVal);
    xPos++;
  }
  
  for(int i = 0; i < _curWriteIndex; i++){
    int analogVal = _circularBuffer[i];
    drawLine(xPos, analogVal);
    xPos++;;
  }
  
  display.display();
  delay(DELAY_LOOP_MS);
}

void drawLine(int xPos, int analogVal){             //Draw the line at the given x position and analog value
  int lineHeight = map(analogVal, MIN_ANALOG_INPUT, MAX_ANALOG_INPUT, 0, _graphHeight);
  int yPos = display.height() - lineHeight;
  display.drawFastVLine(xPos, yPos, lineHeight, SSD1306_WHITE);
}
