#define MAX_NUMBERS 10 // največje število števil v seznamu
#define BUFFER_SIZE 64 // velikost začasnega pomnilnika za branje iz serijskega porta
#include <LiquidCrystal_I2C.h>

#define I2C_ADDR    0x27
#define LCD_COLUMNS 20
#define LCD_LINES   2

LiquidCrystal_I2C lcd(I2C_ADDR, LCD_COLUMNS, LCD_LINES);
long numbers[MAX_NUMBERS]; // seznam za shranjevanje števil
int count = 0; // število trenutno shranjenih števil

void setup() {
  Serial.begin(9600);
  Serial.println("Vpiši število.");
  lcd.init();
  lcd.backlight();
}

void loop() {
  if (Serial.available() > 0) {
    char buffer[BUFFER_SIZE];
    memset(buffer, 0, sizeof(buffer)); // počisti vsebino seznama
    Serial.readBytesUntil('\n', buffer, BUFFER_SIZE); // preberi niz do znaka za novo vrstico
    
    Serial.println(buffer);
    // razdeli niz na števila in jih shranite v seznam
    char *token = strtok(buffer, ",");
    count = 0; // ponastavi števec števil
    while (token != NULL && count < MAX_NUMBERS) {
      numbers[count++] = atol(token); // pretvori niz v število in shrani v seznam
      //s funkcijo strtok() pridobimo naslednji podniz iz niza buffer. 
      //Kot prvi argument nastavimo na NULL, kar pomeni, da strtok() nadaljuje z razdeljevanjem istega niza,
      // kot je bil podan pri prvem klicu, vendar tokrat nadaljuje od prejšnjega mesta,
      // kjer je bila najdena vejica.
      token = strtok(NULL, ",");

    }


    for (int i = 0; i<count; i++){
      if(numbers[i]>=5000){
        numbers[i]=0;
      }
    }
    // izpiši vsebino seznama
    Serial.println("Seznam shranjenih števil:");
 
    
    
    for (int i = 0; i < count; i++) {
      Serial.print(numbers[i]);
      lcd.setCursor(1, 0);
      lcd.print("Seznam Stevil:");
      lcd.setCursor(2,3);
      
      lcd.print(numbers[i]);
      delay(800);
      lcd.clear();

      if (i < count - 1) {
        Serial.print(", ");
      }
    }
    Serial.println();
  }
}
/* Vrstica memset(buffer, 0, sizeof(buffer)); 
Tukaj je razlaga:
    memset je funkcija, ki se uporablja za postavitev bloka pomnilnika na določeno vrednost.
    buffer je ime spremenljivke ali kazalca na začetek bloka pomnilnika, ki ga želite izbrisati.
    0 je vrednost, ki jo želite nastaviti v celotnem bloku pomnilnika.
    sizeof(buffer) vrne velikost bloka pomnilnika, na katerega kaže buffer. To je koristno, ker se velikost bloka pomnilnika lahko spreminja, in ta izraz se prilagodi tem spremembam.

Skupaj ta vrstica postavi vrednost 0 v vseh bajtih bloka pomnilnika, na katerega kaže buffer. 

Vrstica Serial.readBytesUntil('\n', seznam, SEZNAM_SIZE); 
se uporablja za branje podatkov iz serijskega porta do določenega znaka 
(v tem primeru znak \n, kar je znak za novo vrstico ali "Enter" v ASCII kodiranju) 
ali do dosežene največje dolžine

Vrstica char *token = strtok(seznam, ","); 
uporablja funkcijo strtok() za razdelitev niza znakov na "tokene" glede na določen ločevalni znak 
(v tem primeru vejica, ,).

Tu je razlaga:

    strtok() je funkcija v jeziku C/C++, ki se uporablja za razdeljevanje nizov na podnize 
    ali "tokene" glede na določen ločevalni znak.
    seznam je niz znakov, iz katerega želimo izvleči "tokene".
    "," je niz znakov, ki določa, kako bomo razdelili seznam. V tem primeru uporabljamo vejico kot ločilo.
    token je kazalec na prvi podniz (token), ki ga vrne funkcija strtok().

Funkcija strtok() vrača naslednji podniz (token) iz niza seznam, ki je deljen glede na določen ločevalni znak. 
Ob vsakem klicu funkcije strtok() vrne naslednji token, dokler ne pride do konca niza ali dokler niso izčrpani vsi tokeni.

Pomembno je vedeti, da funkcija strtok() spreminja vhodni niz seznam.
Poleg tega, ko je strtok() prvič klican, se kot prvi argument poda niz, ki ga želite razdeliti. 
Za vsak naslednji klic strtok() kot prvi argument podate NULL, kar pomeni, da nadaljujete z delom na istem nizu.
*/