
//2DO:
// obsługa przycisków zmieniających menu i LED

//160x128

#define Version "0.0.0"
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_ST7735.h>
#include "AS726X.h"
#define TFT_DC         8
#define TFT_CS         9
#define TFT_RST        10

#define Btn1 21             //on board: A1   menu
#define Btn2 20             //on board: A2   gain
#define Btn3 19             //on board: A3   ???

#define WHITE 0xFFFF
#define BLACK 0x0000
#define GRAY 0x8410
#define RED 0xF800
#define ORANGE 0xFA60
#define YELLOW 0xFFE0
#define LIME 0x07FF
#define GREEN 0x07E0
#define CYAN 0x07FF
#define AQUA 0x04FF
#define BLUE 0x001F
#define MAGENTA 0xF81F
#define PINK 0xF8FF
//#define ST7735 NEW 0xD500FF




AS726X sensor;
Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_RST);

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 = 128;
int GrapWidth = 25;
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() {
  tft.initR(INITR_BLACKTAB);
  tft.fillScreen(BLACK);
  tft.setRotation(1);
  tft.setTextSize(1);
  tft.setTextColor(WHITE);
  tft.setCursor(0, 0);
  tft.println("Version:");
  tft.setCursor(0, 10);
  tft.println(Version);

  delay(1000);
  Wire.begin();
  Serial.begin(115200);
  sensor.begin();
  pinMode(Btn1, INPUT);
  pinMode(Btn2, INPUT);
}
void drawControls() {
  tft.fillScreen(BLACK);

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

}
void loop() {
  tft.fillScreen(ST77XX_BLACK);
  tft.setTextSize(1);
  tft.setTextColor(WHITE);

//  //TESTY
//  tft.setCursor(0, 0);
//  tft.setTextColor(WHITE);
//  tft.setTextWrap(true);
//  tft.print("test");
//  delay(500);
//  tft.fillRect(0, 64 , 25, 64, RED);
//  tft.fillRect(25, 64 , 25, 64, ORANGE);
//  tft.fillRect(50, 64 , 25, 64, YELLOW);
//  tft.fillRect(75, 64 , 25, 64, GREEN);
//  tft.fillRect(100, 64 , 25, 64, BLUE);
//  tft.fillRect(125, 64 , 25, 64, MAGENTA);
//  delay(1000);




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




  if (menu_number == 0 ) {//show menu
    drawControls();
    tft.setCursor(0, 0);
    tft.println("GAIN");
    tft.setCursor(32, 0);
    tft.println(gainValue, 1);
    tft.setCursor(64, 0);
    tft.println("LED: 5-8");
    tft.setCursor(0, 8);
    tft.println("0:Menu 1:Calculated");
    tft.setCursor(0, 16);
    tft.println("2:Raw 3:Reltive Graph");
    tft.setCursor(0, 24);
    tft.println("4:Calculated Graph");
    delay(0);  
  }

  //
  if (menu_number == 1 || menu_number == 5  ) {//show calculated values
    drawControls();
    //tft.setRotation(0);
    tft.setCursor(0, 25);
    tft.println("R:");
    tft.setCursor((GrapWidth), 25);
    tft.println("O:");
    tft.setCursor((GrapWidth) * 2, 25);
    tft.println("Y:");
    tft.setCursor((GrapWidth) * 3, 25);
    tft.println("G:");
    tft.setCursor((GrapWidth) * 4, 25);
    tft.println("B:");
    tft.setCursor((GrapWidth) * 5, 25);
    tft.println("V:");
    ////tft.setRotation(3);
    tft.setCursor(0, 4);
    dtostrf(CalcRed, 10, 1, FloatInChar);
    tft.println(FloatInChar);
    tft.setCursor(0, (GrapWidth * 1) + 5);
    dtostrf(CalcOrange, 10, 1, FloatInChar);
    tft.println(FloatInChar);
    tft.setCursor(0, (GrapWidth * 2) + 5);
    dtostrf(CalcYellow, 10, 1, FloatInChar);
    tft.println(FloatInChar);
    tft.setCursor(0, (GrapWidth * 3) + 5);
    dtostrf(CalcGreen, 10, 1, FloatInChar);
    tft.println(FloatInChar);
    tft.setCursor(0, (GrapWidth * 4) + 5);
    dtostrf(CalcBlue, 10, 1, FloatInChar);
    tft.println(FloatInChar);
    tft.setCursor(0, (GrapWidth * 5) + 5);
    dtostrf(CalcViolet, 10, 1, FloatInChar);
    tft.println(FloatInChar);
  }

  //  ////tft.setRotation(0);
  //show raw values
  if (menu_number == 2 || menu_number == 6) {
    drawControls();
    ////tft.setRotation(0);
    tft.setCursor(0, 25);
    tft.println("R");
    tft.setCursor((GrapWidth), 25);
    tft.println("O");
    tft.setCursor((GrapWidth) * 2, 25);
    tft.println("Y");
    tft.setCursor((GrapWidth) * 3, 25);
    tft.println("G");
    tft.setCursor((GrapWidth) * 4, 25);
    tft.println("B");
    tft.setCursor((GrapWidth) * 5, 25);
    tft.println("V");
    ////tft.setRotation(3);

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


      ////tft.setRotation(0);

  //show relative calculated values graph
   if (menu_number == 3 || menu_number == 7 ){
      maxValue = 0;
      drawControls();
      ////tft.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);


      tft.setCursor(1 * GrapWidth -10, 10);
      if (HeightRed >25){
          tft.setTextColor(BLACK);
      }

      tft.fillRect(0 * GrapWidth,     GraphHeight - HeightRed,    GrapWidth, HeightRed,     RED);
      tft.fillRect(1 * GrapWidth + 1, GraphHeight - HeightOrange, GrapWidth, HeightOrange,  ORANGE);
      tft.fillRect(2 * GrapWidth + 2, GraphHeight - HeightYellow, GrapWidth, HeightYellow,  YELLOW);
      tft.fillRect(3 * GrapWidth + 3, GraphHeight - HeightGreen,  GrapWidth, HeightGreen,   GREEN);
      tft.fillRect(4 * GrapWidth + 4, GraphHeight - HeightBlue,   GrapWidth, HeightBlue,    BLUE);
      tft.fillRect(5 * GrapWidth + 5, GraphHeight - HeightViolet, GrapWidth, HeightViolet,  MAGENTA);
      tft.setCursor(1 * GrapWidth -10, 0);
      if (HeightRed > 28){
          tft.setTextColor(BLACK);
      }else {
          tft.setTextColor(WHITE);
      }
      tft.println("R:");
      tft.setCursor(2 * GrapWidth -10, 0);
      if (HeightOrange > 28){
          tft.setTextColor(BLACK);
      }else {
          tft.setTextColor(WHITE);
      }
      tft.println("O:");
      tft.setCursor(3 * GrapWidth -10, 0);
      if (HeightYellow > 28){
          tft.setTextColor(BLACK);
      }else {
          tft.setTextColor(WHITE);
      }
      tft.println("Y:");
      tft.setCursor(4 * GrapWidth -10, 0);
      if (HeightGreen > 28){
          tft.setTextColor(BLACK);
      }else {
          tft.setTextColor(WHITE);
      }
      tft.println("G:");
      tft.setCursor(5 * GrapWidth -10, 0);
      if (HeightBlue > 28){
          tft.setTextColor(BLACK);
      }else {
          tft.setTextColor(WHITE);
      }
      tft.println("B:");
      tft.setCursor(6 * GrapWidth -10, 0);
      if (HeightViolet > 28){
          tft.setTextColor(BLACK);
      }else {
          tft.setTextColor(WHITE);
      }
      tft.println("V:");

      maxValue = 0.0;
    }



    //show relative raw data  graph
    if (menu_number == 4 || menu_number == 8 ){
      maxValue = 0;
      drawControls();
      ////tft.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);


      tft.setCursor(1 * GrapWidth -10, 10);
      if (HeightRed >25){
          tft.setTextColor(BLACK);
      }

      tft.fillRect(0 * GrapWidth,     GraphHeight - HeightRed,    GrapWidth, HeightRed,     RED);
      tft.fillRect(1 * GrapWidth + 1, GraphHeight - HeightOrange, GrapWidth, HeightOrange,  ORANGE);
      tft.fillRect(2 * GrapWidth + 2, GraphHeight - HeightYellow, GrapWidth, HeightYellow,  YELLOW);
      tft.fillRect(3 * GrapWidth + 3, GraphHeight - HeightGreen,  GrapWidth, HeightGreen,   GREEN);
      tft.fillRect(4 * GrapWidth + 4, GraphHeight - HeightBlue,   GrapWidth, HeightBlue,    BLUE);
      tft.fillRect(5 * GrapWidth + 5, GraphHeight - HeightViolet, GrapWidth, HeightViolet,  MAGENTA);
      tft.setCursor(1 * GrapWidth -10, 0);
      if (HeightRed > 28){
          tft.setTextColor(BLACK);
      }else {
          tft.setTextColor(WHITE);
      }
      tft.println("R");
      tft.setCursor(2 * GrapWidth -10, 0);
      if (HeightOrange > 28){
          tft.setTextColor(BLACK);
      }else {
          tft.setTextColor(WHITE);
      }
      tft.println("O");
      tft.setCursor(3 * GrapWidth -10, 0);
      if (HeightYellow > 28){
          tft.setTextColor(BLACK);
      }else {
          tft.setTextColor(WHITE);
      }
      tft.println("Y");
      tft.setCursor(4 * GrapWidth -10, 0);
      if (HeightGreen > 28){
          tft.setTextColor(BLACK);
      }else {
          tft.setTextColor(WHITE);
      }
      tft.println("G");
      tft.setCursor(5 * GrapWidth -10, 0);
      if (HeightBlue > 28){
          tft.setTextColor(BLACK);
      }else {
          tft.setTextColor(WHITE);
      }
      tft.println("B");
      
      tft.setCursor(6 * GrapWidth -10, 0);
      if (HeightViolet > 28){
          tft.setTextColor(BLACK);
      }else {
          tft.setTextColor(WHITE);
      }
      tft.println("V");

      maxValue = 0.0;
    }
  delay(1000);
  
  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) == HIGH) {
    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;
}
