#include <Adafruit_SSD1306.h> //In this header file we have to comment "#define SSD1306_128_32", and uncoment "#define SSD1306_128_64"
#include <Adafruit_GFX.h>
#include <Wire.h>
#include "WeatherIcons.h"
////////CONSTANTS////////
//In this section, all constants resulting from the prototype board design are set
#define KEY_RIGHT 7
#define KEY_LEFT 4
#define KEY_UP 6
#define KEY_DOWN 5
#define KEY_CENTER 8
#define THERMOMETER A2
#define LED_SERIAL 12
#define LED_COUNT 5

////////MODIFIERS////////
//In this section there are constants whose modification will affect the operation of our plate
#define DELAY_BETWEEN_FRAMES 0.2
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define RESET_BTN 4

////////DECLARATIONS////////
//This section prepares variables that are responsible for the individual components on the board
Adafruit_SSD1306 display(SCREEN_WIDTH,SCREEN_HEIGHT, &Wire, RESET_BTN);

boolean frame = true;
unsigned long time = 0;
int temp;

enum Animation{
  CLOUD,
  RAIN,
  STORM,
  SUN
} animation;

// ================================== By BocmenDen
#define FRAME_OFFSET_X 63
#define FRAME_SIZE_X 32
#define FRAME_SIZE_Y 64

byte _currentDay = 0;
struct WeatherDay{
  float Temperature;
  Animation State;
} _weatherDay;

WeatherDay _weather[] = {
  {20, Animation::CLOUD},
  {22, Animation::RAIN},
  {23, Animation::STORM},
  {24, Animation::SUN},
  {25, Animation::RAIN},
  {25.5f, Animation::STORM},
  {26, Animation::SUN}
};
// ================================== End

void setup(){
  display.begin(0x2, 0x3C, false);
  display.clearDisplay();

  pinMode(THERMOMETER, INPUT);

  pinMode(KEY_RIGHT , INPUT);
  pinMode(KEY_LEFT , INPUT);
  ApplayWatherDay(); // Add by BocmenDen
}

void loop(){ // Full Refactor by BocmenDen
  ReadKeys();
  if(millis() > time){
    printNextFrame(getTemperature());
    time = millis() + (1000 * DELAY_BETWEEN_FRAMES);
  }
}

void printNextFrame(float temp){ // Full Refactor by BocmenDen
  display.clearDisplay();
  if(frame)
    display.drawBitmap(FRAME_OFFSET_X, 0, icons[_weatherDay.State * 2], FRAME_SIZE_Y, FRAME_SIZE_X + FRAME_OFFSET_X, 1);
  else
    display.drawBitmap(FRAME_OFFSET_X, 0, icons[_weatherDay.State * 2 + 1], FRAME_SIZE_Y, FRAME_SIZE_X + FRAME_OFFSET_X, 1);

  display.setTextSize(1);
  display.setCursor(0, 0);
  display.setTextColor(SSD1306_WHITE);

  display.println(F("Current"));
  display.println(F("temp:"));
  display.print(temp); display.println(F(" C"));

  display.println();

  display.print(F("Day: "));
  display.println(_currentDay + 1);

  display.println();

  display.println(F("Temp:"));
  display.print(_weatherDay.Temperature); display.println(F(" C"));

  frame = !frame;  
  display.display();
}

float getTemperature(){ // Refactor By BocmenDen
  return analogRead(THERMOMETER) * 0.125 - 22.0; // Из документации стр. 25
}

void ReadKeys(){ // Add by BocmenDen
  if(digitalRead(KEY_RIGHT)){
    _currentDay++;
  }else if(digitalRead(KEY_LEFT)){
    _currentDay--;
  }else{
    return;
  }
  ApplayWatherDay();
  delay(250);
}

inline void ApplayWatherDay(){ // Add by BocmenDen
  time = 0;
  _currentDay = _currentDay % (sizeof(_weather) / sizeof(WeatherDay));
  _weatherDay = _weather[_currentDay];
}