/*
  ---AVAILABLE FUNCTIONS---
  AS726X(TwoWire &wirePort = Wire, byte gain = 3, byte measurementMode = 3);
  void printMeasurements();
  byte getTemperature();
  float getTemperatureF();
  void setMeasurementMode(byte mode);
  boolean dataAvailable();
  void enableIndicator();
  void disableIndicator();
  void setIndicatorCurrent(byte current);
  void setBulbCurrent(byte current);
  void softReset();
  void setGain(byte gain);
  void setIntegrationTime(byte integrationValue);
  void enableInterrupt();
  void disableInterrupt();
*/
//2DO:
// obsługa przycisków zmieniających menu i LED
// obsługa przycisków zmieniających gain
//obsługa włączania/wyłączania LED

#define Version "1.1.0"
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include "AS726X.h"
#define Btn2 8             //on board: 8   menu
#define Btn1 9             //on board: 9   gain

AS726X sensor;
Adafruit_SSD1306 display(4);

int RawRed = 0;
int RawOrange = 0;
int RawYellow = 0;
int RawGreen = 0;
int RawBlue = 0;
int RawViolet = 0;
float CalcRed  = 0.0;
float CalcOrange = 0.0;
float CalcYellow = 0.0;
float CalcGreen = 0.0;
float CalcBlue = 0.0;
float CalcViolet = 0.0;
int HeightRed = 0;
int HeightOrange = 0;
int HeightYellow = 0;
int HeightGreen = 0;
int HeightBlue = 0;
int HeightViolet = 0;

byte gain = 3; //  values: 0,1,2,3
float gainValue = 64;
int menu_number = 0; //  values:0 menu 1,2,3 bez led, 4,5,6 z LED
int LedPower = 0;
int GraphHeight = 32;
int GrapWidth = 20;
float ReadValues[6] = {0, 0, 0, 0, 0, 0};
float maxValue = 0.0;
float minValue = 0.0;
float test_vle = 1.0;
char FloatInChar[20];
char ChValue[20];


void setup() {
  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
  display.clearDisplay();
  display.setTextSize(1);
  display.setTextColor(WHITE);
  display.setCursor(0, 0);
  display.println("Version:");
  display.setCursor(0, 10);
  display.println(Version);
  display.display();
  delay(1000);
  Wire.begin();
  Serial.begin(115200);
  display.clearDisplay();
  sensor.begin();
  pinMode(Btn1, INPUT_PULLUP);
  pinMode(Btn2, INPUT_PULLUP);
}

void loop() {
  display.clearDisplay();
  display.setTextSize(1);
  display.setTextColor(WHITE);
  display.setRotation(0);
  //rotation 0 default, pod wyswitlanie grafów
  //roration 1 -tego nie, wyswietlacz pionowy w zla strone
  //roation 2 -tego nie  do gory nogami
  //rotation 3 pod wyswietlanie listy wartosci

  
  //menu change
 if (digitalRead(Btn2) == 0) {
    if (menu_number < 8) {
      menu_number = menu_number + 1;
    } else {
      menu_number = 0;
    }
  }


  if (menu_number > 4 ) {
    LedPower = 1;
  } else {
    LedPower = 0;
  }

  if (LedPower == 1) {
    sensor.enableBulb();
    sensor.takeMeasurementsWithBulb();
  } else {
    sensor.disableBulb();
    sensor.takeMeasurements();
  }
  //gain change
  if (digitalRead(Btn1) == 0) {
    if (gain < 3) {
      gain = gain + 1;
      sensor.setGain(gain);

    } else {
      gain = 0;
      sensor.setGain(gain);
    }
  }

  if (gain == 0 ) {
    gainValue = 1;
  } else if (gain == 1) {
    gainValue = 3.7;
  } else if (gain == 2) {
    gainValue = 16;
  } else {
    gainValue = 64;
  }


  //data haverest
  RawRed    = sensor.getRed();
  RawOrange = sensor.getOrange();
  RawYellow = sensor.getYellow();
  RawGreen  = sensor.getGreen();
  RawBlue   = sensor.getBlue();
  RawViolet = sensor.getViolet();

  CalcRed    = sensor.getCalibratedRed();
  CalcOrange = sensor.getCalibratedOrange();
  CalcYellow = sensor.getCalibratedYellow();
  CalcGreen  = sensor.getCalibratedGreen();
  CalcBlue   = sensor.getCalibratedBlue();
  CalcViolet = sensor.getCalibratedViolet();

  ReadValues[0] = CalcRed;
  ReadValues[1] = CalcOrange;
  ReadValues[2] = CalcYellow;
  ReadValues[3] = CalcGreen;
  ReadValues[4] = CalcBlue;
  ReadValues[5] = CalcViolet;


  if (menu_number == 0 ) {//show menu
    drawControls();
    display.setCursor(0, 0);
    display.println("GAIN");
    display.setCursor(32, 0);
    display.println(gainValue, 1);
    display.setCursor(64, 0);
    display.println("LED: 5-8");
    display.setCursor(0, 8);
    display.println("0:Menu 1:Calculated");
    display.setCursor(0, 16);
    display.println("2:Raw 3:Reltive Graph");
    display.setCursor(0, 24);
    display.println("4:Calculated Graph");
  }
  //
  if (menu_number == 1 || menu_number == 5  ) {//show calculated values
    drawControls();
    display.setRotation(0);
      display.setCursor(0, 25);
      display.println("R:");
      display.setCursor((GrapWidth), 25);
      display.println("O:");
      display.setCursor((GrapWidth) * 2, 25);
      display.println("Y:");
      display.setCursor((GrapWidth) * 3, 25);
      display.println("G:");
      display.setCursor((GrapWidth) * 4, 25);
      display.println("B:");
      display.setCursor((GrapWidth) * 5, 25);
      display.println("V:");
    display.setRotation(3);
    display.setCursor(0, 4);
    dtostrf(CalcRed, 10, 1, FloatInChar);
    display.println(FloatInChar);
      display.setCursor(0, (GrapWidth * 1) + 5);
    dtostrf(CalcOrange, 10, 1, FloatInChar);
    display.println(FloatInChar);
      display.setCursor(0, (GrapWidth * 2) + 5);
    dtostrf(CalcYellow, 10, 1, FloatInChar);
    display.println(FloatInChar);
      display.setCursor(0, (GrapWidth * 3) + 5);
    dtostrf(CalcGreen, 10, 1, FloatInChar);
    display.println(FloatInChar);
      display.setCursor(0, (GrapWidth * 4) + 5);
    dtostrf(CalcBlue, 10, 1, FloatInChar);
    display.println(FloatInChar);
      display.setCursor(0, (GrapWidth * 5) + 5);
    dtostrf(CalcViolet, 10, 1, FloatInChar);
    display.println(FloatInChar);
  }
  display.setRotation(0);
    //show raw values
    if (menu_number == 2 || menu_number == 6) { 
      drawControls();
      display.setRotation(0);
      display.setCursor(0, 25);
      display.println("R");
      display.setCursor((GrapWidth), 25);
      display.println("O");
      display.setCursor((GrapWidth) * 2, 25);
      display.println("Y");
      display.setCursor((GrapWidth) * 3, 25);
      display.println("G");
      display.setCursor((GrapWidth) * 4, 25);
      display.println("B");
      display.setCursor((GrapWidth) * 5, 25);
      display.println("V");
      display.setRotation(3);

      display.setCursor(0, 4);
      dtostrf(RawRed, 10, 0, FloatInChar);
      display.println(FloatInChar);
      display.setCursor(0, (GrapWidth * 1) + 5);
      dtostrf(RawOrange, 10, 0, FloatInChar);
      display.println(FloatInChar);
      display.setCursor(0, (GrapWidth * 2) + 5);
      dtostrf(RawYellow, 10, 0, FloatInChar);
      display.println(FloatInChar);
      display.setCursor(0, (GrapWidth * 3) + 5);
      dtostrf(RawGreen, 10, 0, FloatInChar);
      display.println(FloatInChar);
      display.setCursor(0, (GrapWidth * 4) + 5);
      dtostrf(RawBlue, 10, 0, FloatInChar);
      display.println(FloatInChar);
      display.setCursor(0, (GrapWidth * 5) + 5);
      dtostrf(RawViolet, 10, 0, FloatInChar);
      display.println(FloatInChar);


    }
      display.setRotation(0);

  //show relative calculated values graph
   if (menu_number == 3 || menu_number == 7 ){
      maxValue = 0;
      drawControls();
      display.setRotation(0);
  
      for (int i = 0; i < 5; i++) {
          maxValue = max(maxValue, ReadValues[i]);
      }
      HeightRed     = int((CalcRed     / maxValue) * GraphHeight);
      HeightOrange  = int((CalcOrange  / maxValue) * GraphHeight);
      HeightYellow  = int((CalcYellow  / maxValue) * GraphHeight);
      HeightGreen   = int((CalcGreen   / maxValue) * GraphHeight);
      HeightBlue    = int((CalcBlue    / maxValue) * GraphHeight);
      HeightViolet  = int((CalcViolet  / maxValue) * GraphHeight);
  
  
      display.setCursor(1 * GrapWidth -10, 10);
      if (HeightRed >25){
          display.setTextColor(BLACK);
      }
  
      display.fillRect(0 * GrapWidth,     GraphHeight - HeightRed,    GrapWidth, HeightRed,     SSD1306_WHITE);
      display.fillRect(1 * GrapWidth + 1, GraphHeight - HeightOrange, GrapWidth, HeightOrange,  SSD1306_WHITE);
      display.fillRect(2 * GrapWidth + 2, GraphHeight - HeightYellow, GrapWidth, HeightYellow,  SSD1306_WHITE);
      display.fillRect(3 * GrapWidth + 3, GraphHeight - HeightGreen,  GrapWidth, HeightGreen,   SSD1306_WHITE);
      display.fillRect(4 * GrapWidth + 4, GraphHeight - HeightBlue,   GrapWidth, HeightBlue,    SSD1306_WHITE);
      display.fillRect(5 * GrapWidth + 5, GraphHeight - HeightViolet, GrapWidth, HeightViolet,  SSD1306_WHITE);
      display.setCursor(1 * GrapWidth -10, 0);
      if (HeightRed > 28){
          display.setTextColor(BLACK);
      }else {
          display.setTextColor(WHITE);
      }
      display.println("R:");
      display.setCursor(2 * GrapWidth -10, 0);
      if (HeightOrange > 28){
          display.setTextColor(BLACK);
      }else {
          display.setTextColor(WHITE);
      }
      display.println("O:");
      display.setCursor(3 * GrapWidth -10, 0);
      if (HeightYellow > 28){
          display.setTextColor(BLACK);
      }else {
          display.setTextColor(WHITE);
      }
      display.println("Y:");
      display.setCursor(4 * GrapWidth -10, 0);
      if (HeightGreen > 28){
          display.setTextColor(BLACK);
      }else {
          display.setTextColor(WHITE);
      }
      display.println("G:");
      display.setCursor(5 * GrapWidth -10, 0);
      if (HeightBlue > 28){
          display.setTextColor(BLACK);
      }else {
          display.setTextColor(WHITE);
      }
      display.println("B:");
      display.setCursor(6 * GrapWidth -10, 0);
      if (HeightViolet > 28){
          display.setTextColor(BLACK);
      }else {
          display.setTextColor(WHITE);
      }
      display.println("V:");
  
      maxValue = 0.0;
    }

      
    //show relative raw data  graph
    if (menu_number == 4 || menu_number == 8 ){
      maxValue = 0;
      drawControls();
      display.setRotation(0);
  
      for (int i = 0; i < 5; i++) {
          maxValue = max(maxValue, ReadValues[i]);
      }
      for (int i = 0; i < 5; i++) {
          minValue = min(minValue, ReadValues[i]);
      }
      HeightRed     = int(((RawRed + abs(minValue))     / (maxValue + abs(minValue)) * GraphHeight);
      HeightOrange  = int(((RawOrange + abs(minValue))  / (maxValue + abs(minValue)) * GraphHeight);
      HeightYellow  = int(((RawYellow + abs(minValue))  / (maxValue + abs(minValue)) * GraphHeight);
      HeightGreen   = int(((RawGreen + abs(minValue))   / (maxValue + abs(minValue)) * GraphHeight);
      HeightBlue    = int(((RawBlue + abs(minValue))    / (maxValue + abs(minValue)) * GraphHeight);
      HeightViolet  = int(((RawViolet + abs(minValue))  / (maxValue + abs(minValue)) * GraphHeight);
  
  
      display.setCursor(1 * GrapWidth -10, 10);
      if (HeightRed >25){
          display.setTextColor(BLACK);
      }
  
      display.fillRect(0 * GrapWidth,     GraphHeight - HeightRed,    GrapWidth, HeightRed,     SSD1306_WHITE);
      display.fillRect(1 * GrapWidth + 1, GraphHeight - HeightOrange, GrapWidth, HeightOrange,  SSD1306_WHITE);
      display.fillRect(2 * GrapWidth + 2, GraphHeight - HeightYellow, GrapWidth, HeightYellow,  SSD1306_WHITE);
      display.fillRect(3 * GrapWidth + 3, GraphHeight - HeightGreen,  GrapWidth, HeightGreen,   SSD1306_WHITE);
      display.fillRect(4 * GrapWidth + 4, GraphHeight - HeightBlue,   GrapWidth, HeightBlue,    SSD1306_WHITE);
      display.fillRect(5 * GrapWidth + 5, GraphHeight - HeightViolet, GrapWidth, HeightViolet,  SSD1306_WHITE);
      display.setCursor(1 * GrapWidth -10, 0);
      if (HeightRed > 28){
          display.setTextColor(BLACK);
      }else {
          display.setTextColor(WHITE);
      }
      display.println("R");
      display.setCursor(2 * GrapWidth -10, 0);
      if (HeightOrange > 28){
          display.setTextColor(BLACK);
      }else {
          display.setTextColor(WHITE);
      }
      display.println("O");
      display.setCursor(3 * GrapWidth -10, 0);
      if (HeightYellow > 28){
          display.setTextColor(BLACK);
      }else {
          display.setTextColor(WHITE);
      }
      display.println("Y");
      display.setCursor(4 * GrapWidth -10, 0);
      if (HeightGreen > 28){
          display.setTextColor(BLACK);
      }else {
          display.setTextColor(WHITE);
      }
      display.println("G");
      display.setCursor(5 * GrapWidth -10, 0);
      if (HeightBlue > 28){
          display.setTextColor(BLACK);
      }else {
          display.setTextColor(WHITE);
      }
      display.println("B");
      display.setCursor(6 * GrapWidth -10, 0);
      if (HeightViolet > 28){
          display.setTextColor(BLACK);
      }else {
          display.setTextColor(WHITE);
      }
      display.println("V");
  
      maxValue = 0.0;
    }
    

    
  
  display.display();
  delay(500);

}


void drawControls() {
  display.clearDisplay();
  display.setRotation(0);
  //    linia pozycyjna LED
  display.drawPixel(127, 24, SSD1306_WHITE);
  if (LedPower == 1) {
    display.drawLine(127, 26, 127, 31, SSD1306_WHITE);
  }
  //gain:
  display.drawPixel(127, 0, SSD1306_WHITE);
  if (gain >= 1) {
    display.drawPixel(127, 2, SSD1306_WHITE);
  }
  if (gain >= 2) {
    display.drawPixel(127, 4, SSD1306_WHITE);
  }
  if (gain >= 3) {
    display.drawPixel(127, 6, SSD1306_WHITE);
  }
  // menu
  if (menu_number >= 1  ) {
  display.drawPixel(127, 10, SSD1306_WHITE);
  }
  if ((menu_number >= 2 && menu_number <5 )|| menu_number >= 6 ) {
    display.drawPixel(127, 12, SSD1306_WHITE);
  }
  if ((menu_number >= 3 && menu_number <5)  || menu_number >= 7 ) {
    display.drawPixel(127, 14, SSD1306_WHITE);
  }
  if ((menu_number >= 4 && menu_number <5 ) || menu_number >= 8 ) {
    display.drawPixel(127, 16, SSD1306_WHITE);
  }
  
}
