#include <FastLED.h>
#include "gameClasses.h"

                                //Objekte erstellen
Poti poti1(A0);                 //poti an pin A0 erzeugen
Bloecke bloecke;                //"Listen" Objekt bloecke erzeugen
Ball ball(3, &bloecke);         //ball mit 3 Leben und einem Zeiger auf bloecke erzeugen
Platform platform1(0);          //platform an x-position 0 erzeugen


unsigned long timeNow;              //Variable für Zeitstempel erzeugen
unsigned long intervall = 250;      //Intervall in Millisekunden nach dem die Position des Balls aktualisiert wird

void setup() {
  Serial.begin(9600);                      //für Seriellen Monitor

  for (int i = 0; i < 32; i++) {          //"Karte" für die Information welche Pixel belegt sind mit False initialisieren
    for (int j = 0; j < 16; j++) {
      occupied[i][j] = 0;
    }
  }

  for (int i = 0; i < 6; i ++) {                        //Block Objekte dynamisch erstellen und in die Liste bloecke einfügen, hier könnte man für verschiedene Schwierigkeitsgrade ansetzen
    for(int j = (1+i);j<((matrixWidth)-(1+i));j+=2){
      bloecke.addRight(j,i,3);                          //Block elemente am Ende der Liste anfügen
    }
  }

  FastLED.addLeds<CHIPSET, LED_PIN, COLOR_ORDER>(leds, NUM_LEDS).setCorrection(UncorrectedColor);   //leds[] mit der fastLED.show() verknüpfen und diese initialisieren 
  FastLED.setBrightness(BRIGHTNESS);                                                                //Helligkeit setzen

  timeNow = millis();               //zeitstempel auf jetzt
  FastLED.show();                   //leds[] auf Matrix ausgeben
  Serial.println("Willkommen zu Block Shooter!\nDu hast 3 Leben.");
  for(int i=5;i>=0;i--){
    Serial.println(i);
    delay(1000);
  }
  Serial.println("Los geht's!");
}

void loop() {
  poti1.refreshValue();                           //potiwert aktualisieren
  platform1.refreshPosition(poti1.getValue());    //Platformposition mit dem neuen Potiwert aktualisieren
  flushLeds();                                    //leds[] leeren
  bloecke.colorBlocks();                          //Farben der Blöcke nach leds[] übertragen
    
  if (((unsigned long) millis() - timeNow) >= intervall) {    //bei erreichen des Intervalls
    platform1.refreshPlatformOccupation();                    //aktuelle Platformposition in "belegt" array schreiben
    ball.move();                                              //Ball einen Schritt bewegen
    timeNow = millis();                                       //Zeitstempel auf jetzt
  }

  leds[(ball.getYPos()*matrixWidth) + ball.getXPos()] = CRGB::Red;    //Ballposition rot einfärben

  for (int i = platform1.getXPos(); i < (platform1.getXPos() + platform1.getWidth()); i++) {  //Plattformposition blau einfärben
    leds[(platform1.getYPos()*matrixWidth) + i] = CRGB::Blue;
  }

  FastLED.show();   //leds[] ausgeben
}

void flushLeds() {                        //funktion um leds[] zu leeren (=mit Weiß überschreiben)
  for (int i = 0; i < NUM_LEDS; i++) {
    leds[i] = CRGB::White;
  }
}

void flushMonitor(){                      //"leert" den Serial Monitor
  for(int i=0;i<10;i++){
    Serial.println();
  }
}