#include <Adafruit_QDTech.h>
#include <SPI.h>

//Display
#define CS_PIN  10
#define DC_PIN  9
#define RST_PIN 8
Adafruit_QDTech tft = Adafruit_QDTech(CS_PIN, DC_PIN, RST_PIN);

//Zählervariablen
int two_Euro_count = 0;
int one_Euro_count = 0;
int fifty_cents_count = 0;
int twenty_cents_count = 0;
int ten_cents_count = 0;

int Sensor1 = A4; //10 Cent
int Sensor2 = A3; //20 Cent
int Sensor3 = A2; //1 Euro
int Sensor4 = A1; //50 Cent
int Sensor5 = A0; //2 Euro

//Startzeit an der die Münze erkannt wird
unsigned long Sensor1_time = 0;
unsigned long Sensor2_time = 0;
unsigned long Sensor3_time = 0;
unsigned long Sensor4_time = 0;
unsigned long Sensor5_time = 0;

//Analogwerte beim Start
int Sensor1_Start;
int Sensor2_Start;
int Sensor3_Start;
int Sensor4_Start;
int Sensor5_Start;

//Motor H-Brücke
int GSM1 = 3;
int in1 = 4;
int in2 = 2;

//Button
int buttonPin = 12;
int buttonState = 0;//Button Status
unsigned long buttonTime = 0;

//Parameter Einstellungen
int Sensor_puffer = 40; //Analogwret Abweichung wann Münze erkannt wird
int Sensor_delay_time = 100;//Wie lange wird Sensor nach erkennen einer Münze deaktiviert

void setup() {
  Serial.begin(9600);
  tft.init();
  TFT_start();

  Sensor1_Start = analogRead(Sensor1);
  Sensor2_Start = analogRead(Sensor2);
  Sensor3_Start = analogRead(Sensor3);
  Sensor4_Start = analogRead(Sensor4);
  Sensor5_Start = analogRead(Sensor5);

  Serial.println(Sensor1_Start);
  Serial.println(Sensor2_Start);
  Serial.println(Sensor3_Start);
  Serial.println(Sensor4_Start);
  Serial.println(Sensor5_Start);
    
  pinMode(buttonPin, INPUT_PULLUP);
}

void loop() {
  //Betriebsmodus einstellen / Button entprellen
  if(digitalRead(buttonPin) == LOW && millis() >= buttonTime + 500){
    if(buttonState == 0){
      buttonState = 1;
      analogWrite(GSM1, 180);//Motor Starten 0-255 
      digitalWrite(in1, LOW); 
      digitalWrite(in2, HIGH);
      TFT_running();
    }
    else if(buttonState == 1){//Auswerten
      buttonState = 2;
      analogWrite(GSM1, 0);//Motor bleibt stehen
      //digitalWrite(in1, LOW); 
      //digitalWrite(in2, LOW);
      TFT_evaluation();
    }
    else if(buttonState == 2){//Reset
      buttonState = 0;
      TFT_start();
      
      two_Euro_count = 0;
      one_Euro_count = 0;
      fifty_cents_count = 0;
      twenty_cents_count = 0;
      ten_cents_count = 0;
    }
    buttonTime = millis();
  }


  if(buttonState == 1){
    if(analogRead(Sensor1) >= Sensor1_Start + Sensor_puffer && millis() >= Sensor1_time + Sensor_delay_time){
        Sensor1_time = millis();
        ten_cents_count = ten_cents_count + 1;
        //Serial.print("10 Cent: ");
        //Serial.println(ten_cents_count);
        //Serial.println(millis());
        //Serial.println(analogRead(Sensor1));
      }

      if(analogRead(Sensor2) >= Sensor2_Start + Sensor_puffer && millis() >= Sensor2_time + Sensor_delay_time){
        Sensor2_time = millis();
        twenty_cents_count = twenty_cents_count + 1;
        //Serial.print("20 Cent: ");
        //Serial.println(twenty_cents_count);
        //Serial.println(millis());
        //Serial.println(analogRead(Sensor1));
      }

      if(analogRead(Sensor3) >= Sensor3_Start + Sensor_puffer && millis() >= Sensor3_time + Sensor_delay_time){
        Sensor3_time = millis();
        one_Euro_count = one_Euro_count + 1;
        //Serial.print("1 Euro: ");
        //Serial.println(one_Euro_count);
        //Serial.println(millis());
        //Serial.println(analogRead(Sensor3));
      }

      if(analogRead(Sensor4) >= Sensor4_Start + Sensor_puffer && millis() >= Sensor4_time + Sensor_delay_time){
        Sensor4_time = millis();
        fifty_cents_count = fifty_cents_count + 1;
        //Serial.print("50 Cent: ");
        //Serial.println(fifty_cents_count);
        //Serial.println(millis());
        //Serial.println(analogRead(Sensor4));
      }

      if(analogRead(Sensor5) >= Sensor5_Start + Sensor_puffer && millis() >= Sensor5_time + Sensor_delay_time){
        Sensor5_time = millis();
        two_Euro_count = two_Euro_count + 1;
        //Serial.print("2 Euro: ");
        //Serial.println(two_Euro_count);
        //Serial.println(millis());
        //Serial.println(analogRead(Sensor5));
      }
  }

  
//Serial.print(analogRead(Sensor1));
//Serial.print("  ");
//Serial.print(analogRead(Sensor2));
//Serial.print("  ");
//Serial.print(analogRead(Sensor3));
//Serial.print("  ");
//Serial.print(analogRead(Sensor4));
//Serial.print("  ");
//Serial.println(analogRead(Sensor5));




}


//---------------------------------------
//TFT Start
void TFT_start(){
  tft.setRotation(1);
  tft.fillScreen(QDTech_BLACK);

  for (int radius = 0; radius <= max(tft.width()/2, tft.height()/2); radius += 5) {
      tft.drawCircle(tft.width()/2, tft.height()/2, radius, QDTech_WHITE); //Kreis zeichnen
      delay(100); //Kurze Verzögerung, damit der Effekt sichtbar ist
  }
  tft.fillRect(0, 0, 200, 30, QDTech_BLACK);
  tft.setTextSize(2);
  tft.setTextColor(QDTech_GREEN);
  tft.setCursor(15, 10);
  tft.println("Coin Sorter");
  tft.setTextSize(1);
  tft.fillRect(0, 56, 200, 15, QDTech_BLACK);
  tft.setCursor(30, 60);
  tft.println("Push the button");
  tft.setTextSize(1);
  tft.fillRect(0, 113, 200, 12, QDTech_BLACK);
  tft.setCursor(5, 115);
  tft.println("made by FraensEngineering");
}
//---------------------------------------
//TFT Running
void TFT_running(){
  tft.setRotation(1);
  tft.fillScreen(QDTech_BLACK);
  tft.fillRect(0, 50, 200, 30, QDTech_WHITE);
  tft.setTextSize(1);
  tft.setTextColor(QDTech_BLACK);
  tft.setCursor(25, 60);
  tft.println("Machine is sorting");
}

//---------------------------------------
//TFT Evaluation (Auswertung am Ende der Zählung
void TFT_evaluation(){
  const int NUM_ROWS = 6;
  const int NUM_COLS = 3;
  const int CELL_WIDTH = 50;
  const int CELL_HEIGHT = 16;
  const int ROW_START = 18;
  const int COL_START = 10;
  const int TEXT_SIZE = 1;  // change font size to 1
  
  tft.setRotation(1);
  tft.fillScreen(QDTech_BLACK);

  // create header with name "Coinsorter"
  int headerX = 0;  // x position of header
  int headerY = 0;  // y position of header
  int headerWidth = 160;  // width of header
  int headerHeight = 15;  // height of header
  tft.fillRect(headerX, headerY, headerWidth, headerHeight, tft.Color565 (127, 255, 0));  // draw red rectangle
  tft.setCursor(headerX + 18, headerY + 4);  // set cursor position
  tft.setTextColor(QDTech_BLACK);
  tft.setTextSize(1);  // set font size
  tft.print("C o i n s o r t e r");  // print header text
  
  // draw filled rectangle for column header
  int colHeaderX = 0;
  int colHeaderY = ROW_START - 3;
  int colHeaderWidth = CELL_WIDTH * 4;
  int colHeaderHeight = CELL_HEIGHT;
  tft.fillRect(colHeaderX, colHeaderY, colHeaderWidth, colHeaderHeight, tft.Color565(255, 0, 0)); 

    // draw filled rectangle for Summe
  tft.fillRect(0, 109, 160, 128, tft.Color565(255, 0, 0)); 

  // draw vertical lines
  for (int i = 0; i < NUM_COLS - 1; i++) {
    int x = COL_START + ((i + 1) * CELL_WIDTH);
    tft.drawFastVLine(x, ROW_START, (NUM_ROWS+1) * CELL_HEIGHT, QDTech_YELLOW);
  }
  
  // write column headers
  tft.setCursor(COL_START + 3, ROW_START);
  tft.setTextColor(QDTech_YELLOW);
  tft.setTextSize(TEXT_SIZE);
  tft.print("Coin");
  
  tft.setCursor(COL_START + CELL_WIDTH + 8, ROW_START);
  tft.setTextColor(QDTech_YELLOW);
  tft.setTextSize(TEXT_SIZE);
  tft.print("Number");
  
  tft.setCursor(COL_START + (CELL_WIDTH * 2)+ 8, ROW_START);
  tft.setTextColor(QDTech_YELLOW);
  tft.setTextSize(TEXT_SIZE);
  tft.print("Total");
  tft.drawFastHLine(0, ROW_START + 13, 160, QDTech_YELLOW);

  // Beispiel-Daten schreiben
  tft.setCursor(COL_START, ROW_START + CELL_HEIGHT);
  tft.setTextColor(QDTech_WHITE);
  tft.setTextSize(TEXT_SIZE);
  tft.print("2 Euro");    // geändert auf 2 Euro

  tft.setCursor(COL_START, ROW_START + (2 * CELL_HEIGHT));
  tft.setTextColor(QDTech_WHITE);
  tft.setTextSize(TEXT_SIZE);
  tft.print("1 Euro");
  tft.drawFastHLine(0, 2 * CELL_HEIGHT + 13, 160, QDTech_YELLOW);
  
  tft.setCursor(COL_START, ROW_START + (3 * CELL_HEIGHT));
  tft.setTextColor(QDTech_WHITE);
  tft.setTextSize(TEXT_SIZE);
  tft.print("50 Cent");
  tft.drawFastHLine(0, 3 * CELL_HEIGHT + 13, 160, QDTech_YELLOW);
  
  tft.setCursor(COL_START, ROW_START + (4 * CELL_HEIGHT));
  tft.setTextColor(QDTech_WHITE);
  tft.setTextSize(TEXT_SIZE);
  tft.print("20 Cent");
  tft.drawFastHLine(0, 4 * CELL_HEIGHT + 13, 160, QDTech_YELLOW);
  
  tft.setCursor(COL_START, ROW_START + (5 * CELL_HEIGHT));
  tft.setTextColor(QDTech_WHITE);
  tft.setTextSize(TEXT_SIZE);
  tft.print("10 Cent");
  tft.drawFastHLine(0, 5 * CELL_HEIGHT + 13, 160, QDTech_YELLOW);

  tft.setCursor(COL_START, ROW_START + (6 * CELL_HEIGHT)+2);
  tft.setTextColor(QDTech_GREEN);
  tft.setTextSize(TEXT_SIZE);
  tft.print("Sum tot.:");
  tft.drawFastHLine(0, 6 * CELL_HEIGHT + 13, 160, QDTech_YELLOW);

const int x = 82;
const int xx = 120;
  //TFT mit Zahlen befüllen
  tft.setCursor(x, 34);
  tft.setTextColor(QDTech_WHITE);
  tft.setTextSize(1);
  tft.print(two_Euro_count);
  tft.setCursor(xx, 34);
  tft.print(two_Euro_count*2);

  tft.setCursor(x, 50);
  tft.setTextColor(QDTech_WHITE);
  tft.setTextSize(1);
  tft.print(one_Euro_count);
  tft.setCursor(xx, 50);
  tft.print(one_Euro_count*1);

  tft.setCursor(x, 65);
  tft.setTextColor(QDTech_WHITE);
  tft.setTextSize(1);
  tft.print(fifty_cents_count);
  tft.setCursor(xx, 65);
  tft.print(fifty_cents_count*0.5);

  tft.setCursor(x, 81);
  tft.setTextColor(QDTech_WHITE);
  tft.setTextSize(1);
  tft.print(twenty_cents_count);
  tft.setCursor(xx, 81);
  tft.print(twenty_cents_count*0.2);

  tft.setCursor(x, 97);
  tft.setTextColor(QDTech_WHITE);
  tft.setTextSize(1);
  tft.print(ten_cents_count);
  tft.setCursor(xx, 97);
  tft.print(ten_cents_count*0.1);

  int sum_count = two_Euro_count + one_Euro_count + fifty_cents_count + twenty_cents_count + ten_cents_count; 
  float sum_total = two_Euro_count*2 + one_Euro_count*1 + fifty_cents_count*0.5 + twenty_cents_count*0.2 + ten_cents_count*0.1;
  tft.setCursor(x, 116);
  tft.setTextColor(QDTech_GREEN);
  tft.setTextSize(1);
  tft.print(sum_count);
  tft.setCursor(xx, 116);
  tft.print(sum_total);
}