// https://forum.arduino.cc/t/problemi-con-la-condizione/1130482
// Dalla descrizione sembra si tratti di un montacarichi
// teorico, quindi niente parti mobili.
#include <Wire.h>
#include <SSD1306Ascii.h>
//#include <SSD1306AsciiAvrI2c.h>
#include <SSD1306AsciiWire.h>
#include "mtbutton.h"
#include <LedControl.h>
#include "dbgtime.h"
//#define US_BUFF_SIZE  100
//DBG_INIT();
//DBG_INCLUDE()

//#define TEST_ASSERT_STATE
//#define TEST_IS_PRESSED_TIME
//#define TEST_PULLUP_PULLDOWN
//#define TEST_BUTTON_PDWN
#ifdef TEST_BUTTON_PDWN

//Button btnPdwn(9, 25, false, false);
MtButton btnPdwn(9, InputMode::EXPDWN);
MtButton btnPup(6);  // default InputMode::IPUP

void setup() {
    Serial.begin(115200);
    //delay(2000);
    // test bloccante
    /*while(!btnPdwn.wasPressed()) {
        btnPdwn.read();
        //if (btnPdwn.wasPressed())
        //    break;
    }*/

    //btnPdwn.begin();
    //btnPup.begin();
    uint32_t m_timeRepeat = 300;
    byte gcnt = 0;
    while(true) {
        if (m_timeRepeat > 10) {
            //m_timeRepeat -= log(m_timeRepeat * m_timeRepeat);
            //m_timeRepeat -= log(m_timeRepeat);
            m_timeRepeat -= log(m_timeRepeat)*pow(m_timeRepeat, 0.25);
            
            Serial.println(m_timeRepeat);
            gcnt++;
        } else {
            Serial.println(gcnt);
            break;
        }
    }
    Serial.println("setup");

}

void loop() {
#ifdef TEST_IS_PRESSED_TIME
    /*if (saveUs())
      usPrint();*/

    btnPdwn.read();
    btnPup.read();
    if (btnPdwn.isPressed(255)) {
        /*restartSaveUs();*/
        Serial.print(".");
    } else if (btnPup.isPressed(100)) {
        /*restartSaveUs();*/
        Serial.print("-");
    }
    //delay(25);
  
#endif
#ifdef TEST_PULLUP_PULLDOWN
    btnPdwn.read();
    btnPup.read();
    if (btnPdwn.wasPressed()) {
        Serial.println("redleft");
    } else if (btnPup.wasPressed()) {
        Serial.println("redRight");
    }
#endif
#ifdef TEST_ASSERT_STATE
    btnPdwn.read();
    btnPup.read();
    if (btnPdwn.pressedFor(10)) {
        Serial.println("redleft");
    } else if (btnPup.pressedFor(10)) {
        Serial.println("redRight");
    }
#endif
}
#endif

#if(1)

#define CS_PIN  10
#define CLK_PIN 13
#define DIN_PIN 11
// font System5x7 
// 0X3C+SA0 - 0x3C or 0x3D
#define I2C_ADDRESS 0x3C
//SSD1306AsciiAvrI2c oled;
SSD1306AsciiWire oled;


#define MAX_SEG 3
byte grow = 7;
byte gcol = 1;

#define PIN_LEFT_BTN    2
#define PIN_RIGTH_BTN   3
#define PIN_UP_BTN      4
#define PIN_DWN_BTN     5
#define PIN_SET_BTN     6

MtButton leftBtn(PIN_LEFT_BTN);
MtButton rightBtn(PIN_RIGTH_BTN);
MtButton upBtn(PIN_UP_BTN);
MtButton downBtn(PIN_DWN_BTN);
MtButton setBtn(PIN_SET_BTN);

// Define os pinos da matriz de LEDs
LedControl mat = LedControl(DIN_PIN, CLK_PIN, CS_PIN, MAX_SEG);

enum Spostamento {
    salire = 1,
    scendere = -1
};

byte c[] = {3, 6, 9};
byte b[] = {2, 5, 8};
byte a[] = {1, 4, 7};

byte row = 0;
byte col = 0;

byte lastMatrix;


byte *matrix[] = { a, b, c };

byte select(byte row, byte col) {
    if (row > 2 || col > 2) 
        return 255;
    return matrix[row][col];
}

byte lastPin;
byte oldPin = 255;


void cambiaPiano(Spostamento sc) {
    for (byte row = 0; row < 3; row++) {
        for (byte col = 0; col < 3; col++) {
            if (sc == salire)
                matrix[row][col] = matrix[row][col] + 9;
            else if (sc == scendere) {
                matrix[row][col] = matrix[row][col] - 9;      
            }
        }
    }
}

byte piano;
byte oldPiano;
bool shiftKey;
uint32_t shiftTimer;
byte oldRow = 4;
byte oldCol = 4;

#define US_BUFF_SIZE    100
#include "dbgtime.h"
DBG_INIT();
DBG_INCLUDE()

void setLight(byte matrix, byte row, byte col) {
    if (row != oldRow || col != oldCol || piano != oldPiano) {
        mat.clearDisplay(lastMatrix);
        lastMatrix = matrix;
        byte lrow = (grow - 1) - (row*2);
        byte lcol = gcol + (col * 2);
        mat.setRow(matrix, lrow - 1, _BV(lcol) | _BV(lcol+1));
        mat.setRow(matrix, lrow, _BV(lcol) | _BV(lcol+1));
        oldRow = row;
        oldCol = col;
        oldPiano = piano;
    }

}

void selectPiano(byte p) {
    if (piano == oldPiano)
        return;
    cambiaPiano((int8_t)piano - oldPiano);
    //Serial.println((int)piano - oldPiano);
   
    oldPiano = piano = p;
}

void digitalPrint(byte pin) {
    if (oldPin != pin) {
        
        if (oldPin != 255) {

            Serial.print("spegne ");
            Serial.print(oldPin);
            byte megaPin = oldPin + 21;
            Serial.print(" su pin ");
            Serial.println(megaPin);
        }
        oldPin = lastPin;

        Serial.print("accende ");
        Serial.print(lastPin);
        byte megaPin = lastPin + 21;
        Serial.print(" su pin ");
        Serial.println(megaPin);
        //setLight(piano, row, col);
    }
}

uint16_t g_counter;

void setup()
{
    Serial.begin(115200);

    /*leftBtn.begin();
    rightBtn.begin();
    upBtn.begin();
    downBtn.begin();
    setBtn.begin();*/

    mat.shutdown(0, false);

    mat.setIntensity(0, 7);

    
    mat.clearDisplay(0);
    Wire.setClock(400000);
    oled.begin(&Adafruit128x64, I2C_ADDRESS);
    // prima di scrivere si oled seleziona un font
    oled.clear();
    oled.setFont(System5x7);
    /*byte s = select(3, 3);
    Serial.println(s);
    s = select(2, 2);
    Serial.println(s);
    s = select(1, 1);
    Serial.println(s);*/
    lastPin = select(row, col);
    digitalPrint(lastPin);
    setLight(piano, 0, 0);
    uint16_t r = 300;
    r -= log10(r);
    Serial.println(r);
    r -= log10(r);
    Serial.println(r);
    r -= log10(r);
    Serial.println(r);
  
    //selectPiano(1);
}

void oledShift() {
    oled.setCursor(85, 6);
    if (!shiftKey)
        oled.print("     ");
    else    
        oled.print("shift");
}

void lcdPrint(uint16_t c) {
    char buff[6] = {0};
    buff[5] = 0;
    oled.setCursor(85, 6);
    sprintf(buff, "%#5u", c);
    saveUs();
    oled.print(buff);
    saveUs();
}

bool autoRepet;
bool reload = true;
uint32_t saveMillis;
uint8_t timeRepeat = 500;
void loop() {
    rightBtn.read();
    leftBtn.read();
    /*upBtn.read();
    downBtn.read();
    setBtn.read();*/
    

    if (leftBtn.isPressed(200)) {
        //Serial.print('.');
        g_counter++;
        lcdPrint(g_counter);
        restartSaveUs();
    }

    if (rightBtn.isPressed(200)) {
        g_counter--;
        //saveUs();
        lcdPrint(g_counter);
        //saveUs();
    }
    if (isBufferFull()) {
        usPrint();    
    }
    /*setLight(piano, row, col);
    //digitalPrint(lastPin);
    if (rightBtn.wasPressed()) {
        
        col++;
        if (col > 2) {
            col = 2;
        }
        //Serial.println(col);
        //lastPin = select(row, col);
    }
    if (leftBtn.wasPressed()) {
        if (col > 0) {
            col--;
            //lastPin = select(row, col);
        } 
    }
    if (upBtn.wasPressed()) {
        if (!shiftKey) {
            if (row < 2) {
                row++;
                //lastPin = select(row, col);
            }
        } else {
            // sali di piano
            if (piano < 2) {
                piano++;
                //selectPiano(piano);
                //lastPin = select(row, col);
            }
        }
    }

    if (downBtn.wasPressed()) {
        if (!shiftKey) {
            if (row > 0) {
                row--;
                //lastPin = select(row, col);
            }
        } else {
            if (piano > 0) {
                piano--;
                //selectPiano(piano);
                //lastPin = select(row, col);
            }
        }
    }
    if (setBtn.wasPressed()) {
        shiftKey = !shiftKey;
        oledShift();
        shiftTimer = millis();

        //Serial.println("sk true");
    }
    if (shiftKey) {
        if (millis() - shiftTimer > 2000) {
            shiftKey = false;
            oledShift();
        }
    }*/
    
}
#endif
#if(0)
// Kukident Siggillo 
// oki
// di mamma
// ONAKA bustine 800mg
// IMMUBRON compresse 50mg
// domani è carini

#include <Arduino.h>
#include <Wire.h>

#define S_RED 0
#define S_GREEN 1
#define S_BLUE 2
int Stato = -1;
unsigned long tmrSwitch;

#define PIN_LED_RED 5
#define PIN_LED_GREEN 6
#define PIN_LED_BLUE 7
uint32_t coh;
void setup()
{
  pinMode(PIN_LED_RED, OUTPUT);
  pinMode(PIN_LED_GREEN, OUTPUT);
  pinMode(PIN_LED_BLUE, OUTPUT);
  Serial.begin(115200);
  tmrSwitch = 0;
  Stato = S_RED;
  //coh = micros();
  saveUs();
  Aggiorna();
  saveUs();  
  //Serial.println(micros() - coh);
 
}

#define US_BUFF_SIZE    20
#include "dbgtime.h"
DBG_INIT();
DBG_INCLUDE();

void loop() {
  
    unsigned long int m = millis();
    if (m - tmrSwitch > 100) {
        if (++Stato > S_BLUE) 
            Stato = S_RED;

        tmrSwitch = m;
        saveUs();
        Aggiorna();
        saveUs(); 
        
    }
    if (isBufferFull()) {
        usPrint();    
    }
}

void Aggiorna() {
  switch (Stato) {
    case S_RED:    
      colora(255, 0, 0);
      Serial.println("RED");
      //delayMicroseconds(14);
      break;
    case S_GREEN:    
      colora(0, 255, 0);
      Serial.println("GREEN");
      break;
    case S_BLUE:
      colora(0, 0, 255);
      Serial.println("BLUE");
      //delayMicroseconds(8);
      break;
  }
}

void colora(int R, int G, int B)
{
   analogWrite(PIN_LED_RED, R);
   analogWrite(PIN_LED_GREEN, G);
   analogWrite(PIN_LED_BLUE, B);
}
#endif