// BASICS
///////////////////////////////////////////////////////
#define BUTTON_A  9
#define BUTTON_B  6
#define BUTTON_C  5
#define LED_REC  19
#define BUTTON_SEND   17
#define BUTTON_READ   18

// SCREEN
///////////////////////////////////////////////////////
#include "doomsDayBitMap.h"
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SH110X.h>
Adafruit_SH1107 display = Adafruit_SH1107(64, 128, &Wire);

// KEY BOARD
///////////////////////////////////////////////////////
#define CARDKB_ADDR 0x5F

// LORA
///////////////////////////////////////////////////////
#include <LoRa.h>
#define RFM95_CS  8
#define RFM95_RST 4
#define RFM95_INT 3
byte msgCount = 0;
// byte localAddress = 0b10111; // for radio 1 -- uncomment here
// byte destination = 0b10010;  // for radio 1 -- uncomment here
byte localAddress = 0b10010;   // for radio 2 -- uncomment here
byte destination = 0b10111;   // for radio 2 -- uncomment here
String outgoingMsg = "";
String incomingMsg = "";

class IncomingMsgr {
  public:
    int receivedIdx=0;int viewdIdx=0;int unseenIdx=0;
    int H = 3;
    String msgs[3] = {};
    void newPacket( String msg ) {
      msgs[2] = msgs[1];msgs[1] = msgs[0];msgs[0] = msg;
      viewdIdx = 0;unseenIdx += 1;
      if (unseenIdx > 3){unseenIdx=4;}
    }  
    void updateFromShowed()
    {
      viewdIdx += 1;
      viewdIdx = viewdIdx%H;
    }
    String getNewMsgs()
    {
      if (unseenIdx == 4){unseenIdx=2;return "3+";}
      String val = String(unseenIdx);
      if (unseenIdx > 0){unseenIdx-=1;}
      return val;
    }
};

IncomingMsgr im;


class OnButtonUp {
  public:
    int buttonNum;
    OnButtonUp( int button ) {
      buttonNum = button;
    }
    int buttonState;
    int wasClickActive=1;
    bool listenForPress()
    {
      buttonState = digitalRead(buttonNum);
      if (buttonState == HIGH) 
      {
        if (!wasClickActive) 
        {
          wasClickActive = 1;
          return true;
        }
      } 
      else 
      {
        if (wasClickActive) 
        {
          wasClickActive = 0;
        }
      }   
      return false;
    }
};

OnButtonUp button_a(BUTTON_A);
OnButtonUp button_b(BUTTON_B);
OnButtonUp button_c(BUTTON_C);
OnButtonUp button_send(BUTTON_SEND);
OnButtonUp button_read(BUTTON_READ);

void receivedPacket( )
{
  int packetSize = LoRa.parsePacket();
  if (packetSize) 
  {
    int recipient = LoRa.read();          // recipient address
    byte sender = LoRa.read();            // sender address
    // if (recipient != localAddress && recipient != 0b10111) {return;} // for radio 1 -- uncomment here
    if (recipient != localAddress && recipient != 0b10010) {return;} // for radio 2 -- uncomment here
    incomingMsg = LoRa.readString();
    if (incomingMsg.substring(0, 6) == "pingMO")
    {
      delay(200);
      LoRa.beginPacket();      
      LoRa.write(destination);     
      LoRa.write(localAddress);      
      // LoRa.print("hello from radioClinc1");  // for radio 1 -- uncomment here      
      LoRa.print("hello from radioClinc2");  // for radio 2 -- uncomment here        
      LoRa.write(msgCount);       
      LoRa.endPacket();                
      msgCount++;      
      return;
    }
    digitalWrite(LED_REC, HIGH);
    incomingMsg = incomingMsg.substring(0, incomingMsg.length() - 1);
    im.newPacket(incomingMsg);
  }
}

void setup() {

  // BASICS
  // Serial.begin(115200);
  Wire.begin(); 
  pinMode(LED_REC, OUTPUT);
  pinMode(BUTTON_SEND, INPUT_PULLUP);
  pinMode(BUTTON_READ, INPUT_PULLUP);

  // SCREEN
  delay(250);
  display.begin(0x3C, true);
  display.clearDisplay();
  // display.display();
  display.setRotation(1);
  display.drawBitmap(0, 0, doomsdayLogo1, 128, 51, SH110X_WHITE);
  display.setTextSize(1); // chars are 8 pixels tall and 6 pixels wide
  display.setTextColor(SH110X_WHITE);
  display.drawLine(0, 51, 129, 51, SH110X_WHITE);
  display.setCursor(0,54);
  display.print("clinc");  
  display.display();
  delay(1000);
  display.invertDisplay(true);delay(400);
  display.invertDisplay(false);delay(400);
  display.invertDisplay(true);delay(400);
  display.invertDisplay(false);delay(400);
  display.invertDisplay(true);delay(400);
  display.invertDisplay(false);delay(1000);
  display.clearDisplay();
  display.display();
  pinMode(BUTTON_A, INPUT_PULLUP);
  pinMode(BUTTON_B, INPUT_PULLUP);
  pinMode(BUTTON_C, INPUT_PULLUP);


  // LoRa
  // while (!Serial);
  LoRa.setPins(RFM95_CS, RFM95_RST, RFM95_INT);
  if (!LoRa.begin(915E6)){
    // Serial.println("Starting LoRa failed!");
    while (1);
  }
  else{
    pinMode(LED_BUILTIN, OUTPUT);
    digitalWrite(LED_BUILTIN, HIGH);
    // Serial.println("LoRa Started");
  };
}

void loop() {

  Wire.requestFrom(CARDKB_ADDR, 1); // Request 1 byte from the slave device.
  while (Wire.available()) 
  {
    char c = Wire.read();
    if (c != 0)
    {
      outgoingMsg += c;
      display.setCursor(0,0);
      display.clearDisplay();
      display.print(outgoingMsg);
      display.drawLine(0, 51, 129, 51, SH110X_WHITE);
      display.setCursor(0,54);
      display.print("clinc");      
      display.display();
    }
  }

  receivedPacket();

  if (button_a.listenForPress())
  {
    display.clearDisplay();
    display.drawBitmap(0, 0, doomsdayLogo1, 128, 51, SH110X_WHITE);
    display.setTextColor(SH110X_WHITE);
    display.drawLine(0, 51, 129, 51, SH110X_WHITE);
    display.setCursor(0,54);
    display.print("clinc");  
    display.display();
    delay(1500);
    display.clearDisplay();
    display.setCursor(0,0);
    display.display();
    outgoingMsg = "";
  }
  
  if (button_send.listenForPress())
  {
    LoRa.beginPacket();                // start packet
    LoRa.write(destination);           // add destination address
    LoRa.write(localAddress);          // add sender address
    LoRa.print(outgoingMsg);           // add payload
    LoRa.write(msgCount);              // add message ID
    LoRa.endPacket();                  // finish packet and send it
    msgCount++;

    display.setCursor(0,0);
    display.clearDisplay();
    display.print("sent msg");
    display.drawLine(0, 51, 129, 51, SH110X_WHITE);
    display.setCursor(0,54);
    display.print("clinc"); 
    display.display();
    outgoingMsg = "";
  }
  if (button_read.listenForPress())
  {
    digitalWrite(LED_REC, LOW);
    display.setCursor(0,0);
    display.clearDisplay();   
    display.print(im.msgs[im.viewdIdx]); 
    im.updateFromShowed();
    display.drawLine(0, 51, 129, 51, SH110X_WHITE);
    display.setCursor(0,54);
    display.print("RSSI:");
    display.print(LoRa.packetRssi());
    display.setCursor(116,54);
    display.print(im.getNewMsgs());
    display.display();
  }

  if (button_b.listenForPress())
  {
    LoRa.beginPacket();                // start packet
    LoRa.write(destination);           // add destination address
    LoRa.write(localAddress);          // add sender address
    LoRa.print("pingMO xyz");          // add payload
    LoRa.write(msgCount);              // add message ID
    LoRa.endPacket();                  // finish packet and send it
    msgCount++; 
  }

  delay(10);
}
