#include "U8glib.h";

U8GLIB_SSD1306_128X64 u8g(U8G_I2C_OPT_DEV_0 | U8G_I2C_OPT_NO_ACK | U8G_I2C_OPT_FAST); // Fast I2C / TWI
// U8GLIB_SSD1306_128X64 u8g(13, 11, 8, 9, 10); // SPI connection
// for SPI connection, use this wiring:
// GND > GND
// VCC > 5V
// SCL > 13
// SDA > 11
// RES > 10
// DC > 9
// CS > 8

// ' icon_bowl', 16x16px
const unsigned char bitmap_icon_bowl [] PROGMEM = {
	0x00, 0x24, 0x00, 0x80, 0x00, 0x14, 0x01, 0x40, 0x00, 0x10, 0x02, 0x40, 0x00, 0x00, 0x0f, 0xf0, 
	0x18, 0x18, 0x10, 0x08, 0x3c, 0x3c, 0x3f, 0xfc, 0x7f, 0xfe, 0x7f, 0xfe, 0x1f, 0xf8, 0x00, 0x00
};
// ' icon_clock', 16x16px
const unsigned char bitmap_icon_clock [] PROGMEM = {
	0x1c, 0x38, 0x32, 0x4c, 0x62, 0x46, 0x47, 0xe2, 0x48, 0x12, 0x70, 0x8e, 0x20, 0x84, 0x24, 0x84, 
	0x42, 0x82, 0x41, 0x82, 0x40, 0x04, 0x20, 0x04, 0x20, 0x08, 0x18, 0x10, 0x0f, 0xf0, 0x1c, 0x38
};
// ' icon_settings', 16x16px
const unsigned char bitmap_icon_settings [] PROGMEM = {
	0x00, 0x00, 0x03, 0xc0, 0x1b, 0xd8, 0x3f, 0xfc, 0x3f, 0xfc, 0x1c, 0x38, 0x78, 0x1e, 0x78, 0x1e, 
	0x78, 0x1e, 0x78, 0x1e, 0x1c, 0x38, 0x3f, 0xfc, 0x3f, 0xfc, 0x1b, 0xd8, 0x03, 0xc0, 0x00, 0x00
};

// Array of all bitmaps for convenience. (Total bytes used to store images in PROGMEM = 144)
const int icons_array_LENGTH = 3;
const unsigned char* icons_array[3] = {
	bitmap_icon_bowl,
	bitmap_icon_clock,
	bitmap_icon_settings
};


// ' scrollbar', 8x64px
const unsigned char bitmap_scrollbar [] PROGMEM = {
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x02, 0x02, 0x02, 
	0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
// ' selector', 128x20px
const unsigned char bitmap_selector [] PROGMEM = {
	0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 
	0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x00, 
	0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x80, 
	0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 
	0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 
	0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 
	0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 
	0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 
	0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 
	0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 
	0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 
	0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 
	0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 
	0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 
	0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 
	0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 
	0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 
	0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xe0, 
	0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 
	0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00
};

const int NUM_ITEMS = 3; // number of items in the list
const int MAX_ITEM_LENGTH = 20; // maximum characters for the item name

char menu_items [NUM_ITEMS] [MAX_ITEM_LENGTH] = {  // array with item names
  { "Feed now!" }, 
  { "Feed later" }, 
  { "Settings" }
 };

#define BUTTON_UP_PIN 12 // pin for UP button 
#define BUTTON_SELECT_PIN 8 // pin for SELECT button
#define BUTTON_DOWN_PIN 4 // pin for DOWN button

#define FONT_HEIGHT u8g.getFontAscent()-u8g.getFontDescent()
#define FONT_WIDTH u8g.getStrWidth("a")

#define MENU_SCREEN 0
#define FEED_NOW_SCREEN 1
#define FEED_LATER_SCREEN 2
#define SETTINGS_SCREEN 3
#define EDITOR_SCREEN 10
int current_screen = MENU_SCREEN;

int button_up_clicked = 0; // only perform action when button is clicked, and wait until another press
int button_select_clicked = 0; // same as above
int button_down_clicked = 0; // same as above

int MAIN_MENU_SCREEN_items_idx = 0; // which item in the menu is selected
bool edit_mode_on = false;

int item_sel_previous; // previous item - used in the menu screen to draw the item before the selected one
int item_sel_next; // next item - used in the menu screen to draw next item after the selected one

struct feedingTime{
  uint32_t id;
  char type; // 'W' - weekly on, 'O' - one time on, 'w' - weekly off, 'o' - one time off
  char day; // 00000001 - Monday, 01000010 - Sunday and Tuesday
  int year;
  int month;
  int date;
  int hour;
  int minute;
  int rations;

  String toString() //"( )  O  2  2023:9:14 07:50"
  {
    String s = "";
    // is active?
    if (type == 'W' || type == 'O') 
      s += "(x)  ";
    else 
      s += "( )  ";
    // type
    if (type == 'W' || type == 'w')
      s += "W  ";
    else if (type == 'O' || type == 'o')
      s += "O  ";
    // rations
    s += rations;
    s += "  ";
    // date
    if (month != 0){
      s += year; 
      s += ".";
      if (month / 10 == 0) s += "0";
      s += month; 
      s += ".";
      if (date / 10 == 0) s += "0";
      s += date;
      s += ".";
    } // or days
    else{
      s += day & 0b00000001 ? "M" : "_";
      s += day & 0b00000010 ? "T" : "_";
      s += day & 0b00000100 ? "W" : "_";
      s += day & 0b00001000 ? "T" : "_";
      s += day & 0b00010000 ? "F" : "_";
      s += day & 0b00100000 ? "S" : "_";
      s += day & 0b01000000 ? "S" : "_";
    }
    s += " ";
    // time
    if (hour / 10 == 0) s += "0";
    s += hour;
    s += ":";
    if (minute / 10 == 0) s += "0";
    s += minute;

    return s;
  }
};
int feedingTimes_count = 9;
feedingTime feedingTimes[] = {
  {1, 'w', 0b00000001, 0, 0, 0, 10, 45, 3},
  {2, 'o', 0b01111111, 2023, 6, 30, 13, 45, 2},
  {3, 'W', 0b01010101, 0, 0, 0, 23, 1, 3},
  {4, 'O', 0, 2023, 10, 15, 10, 30, 4},
  {5, 'w', 0b01111111, 0, 0, 0, 3, 0, 5},
  {6, 'w', 0b00000001, 0, 0, 0, 13, 45, 6},
  {7, 'W', 0b01010101, 0, 0, 0, 23, 1, 7},
  {8, 'o', 0, 2024, 5, 1, 20, 59, 8},
  {9, 'O', 0, 2023, 10, 15, 10, 30, 9}
};
feedingTime* selectedFeedingTime;

struct selectableItem
{
  void (*action)();
  int x;
  int y;
  String text;
  int* value;

  String toString()
  {
    if (text.length() == 0)
    {
      return text + *value;
    }

    return text;
  }
};
selectableItem* selectedItem;

// EDITOR CONTEXT:
struct editorContext
{
  uint32_t id;
  bool isActive;
  bool isWeekly;
  int year;
  int month;
  int date;
  int hour;
  int minute;
  int rations;
  bool weekDays[7];
};
editorContext context = {0, true, true, 2023, 10, 30, 12, 30, 1, {true, true, true, true, true, true, true}};

void openEditor(bool editing)
{
  if (editing)
  {
    if (selectedFeedingTime->type == 'W' || selectedFeedingTime->type == 'O')
      context.isActive = true;
    else
      context.isActive = false;
    if (selectedFeedingTime->type == 'W' || selectedFeedingTime->type == 'w')
    {
      context.isWeekly = true;
      context.weekDays[0] = 0b00000001 & selectedFeedingTime->day;
      context.weekDays[1] = 0b00000010 & selectedFeedingTime->day;
      context.weekDays[2] = 0b00000100 & selectedFeedingTime->day;
      context.weekDays[3] = 0b00001000 & selectedFeedingTime->day;
      context.weekDays[4] = 0b00010000 & selectedFeedingTime->day;
      context.weekDays[5] = 0b00100000 & selectedFeedingTime->day;
      context.weekDays[6] = 0b01000000 & selectedFeedingTime->day;
    }
    else
    {
      context.isWeekly = false;
      context.year = selectedFeedingTime->year;
      context.month = selectedFeedingTime->month;
      context.date = selectedFeedingTime->date;
    }
    context.rations = selectedFeedingTime->rations;
  }
  else
  {
    context = {0, true, true, 2023, 10, 30, 12, 30, 1, {true, true, true, true, true, true, true}};
  }

}

void drawSelection(selectableItem si)
{
  if (edit_mode_on)
  {
    u8g.drawStr(si.x - FONT_WIDTH, si.y, "<");
    u8g.drawStr(si.x + si.toString().length() * FONT_WIDTH, si.y, ">");
  }
  else
  {
    int width = si.toString().length() * FONT_WIDTH + FONT_WIDTH;
    u8g.drawRFrame(
      si.x - 4, 
      si.y-1, 
      width < 120 ? width : 120, 
      FONT_HEIGHT + 2, 
      3);
  }
}

int rations = 1;
int FEED_NOW_SCREEN_items_idx = 0;
int FEED_NOW_SCREEN_items_count = 3;
selectableItem FEED_NOW_SCREEN_items[] = {
  { 
    .action = []{ edit_mode_on = !edit_mode_on; },
    .x = 98, 
    .y = 10, 
    .text = "", 
    .value = &rations 
  },
  {
    .action = []{
      //run motor
    },
    .x = 20, 
    .y = 40,
    .text = "OK"
  },
  {
    .action = []{
      current_screen = MENU_SCREEN;
    },
    .x = 60, 
    .y = 40,
    .text = "Go back!"
  }
};


int FEED_LATER_SCREEN_items_idx = 0;
int FEED_LATER_SCREEN_items_count = 7;
int FEED_LATER_SCREEN_feedingTime_idx = 0;
selectableItem FEED_LATER_SCREEN_items[] = {
  {
    .action = []{
      current_screen = MENU_SCREEN;
    },
    .x = 5, 
    .y = 4,
    .text = "Go back!"
  },
  {
    .action = []{
      current_screen = EDITOR_SCREEN;
      openEditor(false);
    },
    .x = 70, 
    .y = 4,
    .text = "Create new!"
  },
  {
    .action = []{
      current_screen = EDITOR_SCREEN;
      openEditor(true);
    },
    .x = 10,
    .y = 15,
    .text = feedingTimes[0].toString()
  },
  {
    .action = []{
      current_screen = EDITOR_SCREEN;
      openEditor(true);
    },
    .x = 10,
    .y = 25,
    .text = feedingTimes[1].toString()
  },
  {
    .action = []{
      current_screen = EDITOR_SCREEN;
      openEditor(true);
    },
    .x = 10,
    .y = 35,
    .text = feedingTimes[2].toString()
  },
  {
    .action = []{
      current_screen = EDITOR_SCREEN;
      openEditor(true);
    },
    .x = 10,
    .y = 45,
    .text = feedingTimes[3].toString()
  },
  {
    .action = []{
      current_screen = EDITOR_SCREEN;
      openEditor(true);
    },
    .x = 10,
    .y = 55,
    .text = feedingTimes[4].toString()
  }
};


int EDITOR_SCREEN_items_idx = 0;
int EDITOR_SCREEN_items_count = 17;
selectableItem EDITOR_SCREEN_items[] = {
  { //0: go back
    .action = []{
      current_screen = FEED_LATER_SCREEN;
    },
    .x = 5, 
    .y = 4,
    .text = "Go back!"
  },
  { //1: save
    .action = []{
      if (context.id == 0)
      {
        //feedingTimes.push_back(editorContext);
      }
      else
      {
        //selectedFeedingTime->type = (char)context.type;
        //selectedFeedingTime->day = (char)context.day;
        selectedFeedingTime->year = context.year;
        selectedFeedingTime->month = context.month;
        selectedFeedingTime->date = context.date;
        selectedFeedingTime->hour = context.hour;
        selectedFeedingTime->minute = context.minute;
        selectedFeedingTime->rations = context.rations;
      }
      current_screen = FEED_LATER_SCREEN;
    },
    .x = 85, 
    .y = 4,
    .text = "Save!"
  },
  { //2: isActive
    .action = []{
      context.isActive = !context.isActive;
      if (context.isActive)
        EDITOR_SCREEN_items[2].text = "Yes";
      else
        EDITOR_SCREEN_items[2].text = "No";
    },
    .x = 45, 
    .y = 15,
    .text = "Yes"
  },
  { //3: type
    .action = []{ 
      context.isWeekly = !context.isWeekly; 
      if (context.isWeekly)
        EDITOR_SCREEN_items[3].text = "Weekly";
      else
        EDITOR_SCREEN_items[3].text = "Once";
    },
    .x = 94, 
    .y = 15, 
    .text = "Weekly"
  },
  { //4. rations
    .action = []{ edit_mode_on = !edit_mode_on; },
    .x = 50, 
    .y = 25, 
    .text = "",
    .value = &context.rations
  },
  { //5: hour
    .action = []{ edit_mode_on = !edit_mode_on; },
    .x = 40, 
    .y = 35, 
    .text = "",
    .value = &context.hour
  },
  { //6: minute
    .action = []{ edit_mode_on = !edit_mode_on; },
    .x = 60, 
    .y = 35, 
    .text = "",
    .value = &context.minute
  },
  { //7: monday
    .action = []{ 
      context.weekDays[0] = !context.weekDays[0];
      EDITOR_SCREEN_items[7].text = context.weekDays[0] ? "M" : "_";
    },
    .x = 40, 
    .y = 45, 
    .text = "M"
  },
  { //8: tuesday
    .action = []{ 
      context.weekDays[1] = !context.weekDays[1];
      EDITOR_SCREEN_items[8].text = context.weekDays[1] ? "T" : "_";
    },
    .x = 51, 
    .y = 45, 
    .text = "T"
  },
  { //9: wednesday
    .action = []{ 
      context.weekDays[2] = !context.weekDays[2];
      EDITOR_SCREEN_items[9].text = context.weekDays[2] ? "W" : "_";
    },
    .x = 62, 
    .y = 45, 
    .text = "W"
  },
  { //10: thursday
    .action = []{ 
      context.weekDays[3] = !context.weekDays[3];
      EDITOR_SCREEN_items[10].text = context.weekDays[3] ? "T" : "_";
    },
    .x = 73, 
    .y = 45, 
    .text = "T"
  },
  { //11: friday
    .action = []{ 
      context.weekDays[4] = !context.weekDays[4];
      EDITOR_SCREEN_items[11].text = context.weekDays[4] ? "F" : "_";
    },
    .x = 84, 
    .y = 45, 
    .text = "F"
  },
  { //12: saturday
    .action = []{ 
      context.weekDays[5] = !context.weekDays[5];
      EDITOR_SCREEN_items[12].text = context.weekDays[5] ? "S" : "_";
    },
    .x = 95, 
    .y = 45, 
    .text = "S"
  },
  { //13: sunday
    .action = []{ 
      context.weekDays[6] = !context.weekDays[6];
      EDITOR_SCREEN_items[13].text = context.weekDays[6] ? "S" : "_";
    },
    .x = 106, 
    .y = 45, 
    .text = "S"
  },
  { //14: year
    .action = []{ edit_mode_on = !edit_mode_on; },
    .x = 40, 
    .y = 55, 
    .text = "",
    .value = &context.year
  },
  { //15: month
    .action = []{ edit_mode_on = !edit_mode_on; },
    .x = 70, 
    .y = 55, 
    .text = "",
    .value = &context.month
  },
  { //16: date
    .action = []{ edit_mode_on = !edit_mode_on; },
    .x = 88, 
    .y = 55, 
    .text = "",
    .value = &context.date
  }
};

int SETTINGS_SCREEN_items_idx = 0;
int SETTINGS_SCREEN_items_count = 8;
selectableItem SETTINGS_SCREEN_items[] = {
  { //0: go back
    .action = []{
      current_screen = MENU_SCREEN;
    },
    .x = 5, 
    .y = 4,
    .text = "Go back!"
  },
  { //1: save
    .action = []{
      current_screen = MENU_SCREEN;
      // set clock
    },
    .x = 85,
    .y = 4,
    .text = "Save!"
  },
  { //2: hour
    .action = []{ edit_mode_on = !edit_mode_on; },
    .x = 40, 
    .y = 15, 
    .text = "",
    .value = &context.hour
  },
  { //3: minute
    .action = []{ edit_mode_on = !edit_mode_on; },
    .x = 60, 
    .y = 15, 
    .text = "",
    .value = &context.minute
  },
  { //4: dayOfWeek
    .action = []{ edit_mode_on = !edit_mode_on; },
    .x = 40, 
    .y = 25, 
    .text = "1"
  },
  { //5: year
    .action = []{ edit_mode_on = !edit_mode_on; },
    .x = 40, 
    .y = 35, 
    .text = "",
    .value = &context.year
  },
  { //6: month
    .action = []{ edit_mode_on = !edit_mode_on; },
    .x = 70, 
    .y = 35, 
    .text = "",
    .value = &context.month
  },
  { //7: date
    .action = []{ edit_mode_on = !edit_mode_on; },
    .x = 88, 
    .y = 35, 
    .text = "",
    .value = &context.date
  }
};

void setup() {
  u8g.setColorIndex(1);  // set the color to white
  u8g.setFontPosTop();

  // define pins for buttons
  // INPUT_PULLUP means the button is HIGH when not pressed, and LOW when pressed
  // since it´s connected between some pin and GND
  pinMode(BUTTON_UP_PIN, INPUT_PULLUP); // up button
  pinMode(BUTTON_SELECT_PIN, INPUT_PULLUP); // select button
  pinMode(BUTTON_DOWN_PIN, INPUT_PULLUP); // down button
}

void loop() 
{
  if (current_screen == MENU_SCREEN) 
  {
    if ((digitalRead(BUTTON_UP_PIN) == LOW) && (button_up_clicked == 0)) 
    { // up button clicked - jump to previous menu item
      button_up_clicked = 1; // set button to clicked to only perform the action once

      MAIN_MENU_SCREEN_items_idx = MAIN_MENU_SCREEN_items_idx - 1; // select previous item
      if (MAIN_MENU_SCREEN_items_idx < 0) 
      { // if first item was selected, jump to last item
        MAIN_MENU_SCREEN_items_idx = NUM_ITEMS-1;
      }
    }
    if ((digitalRead(BUTTON_UP_PIN) == HIGH) && (button_up_clicked == 1)) button_up_clicked = 0; // unclick 
    
    if ((digitalRead(BUTTON_DOWN_PIN) == LOW) && (button_down_clicked == 0)) 
    { // down button clicked - jump to next menu item
      button_down_clicked = 1; // set button to clicked to only perform the action once

      MAIN_MENU_SCREEN_items_idx = MAIN_MENU_SCREEN_items_idx + 1; // select next item
      if (MAIN_MENU_SCREEN_items_idx >= NUM_ITEMS) 
      { // last item was selected, jump to first menu item
        MAIN_MENU_SCREEN_items_idx = 0;
      }
    }
    if ((digitalRead(BUTTON_DOWN_PIN) == HIGH) && (button_down_clicked == 1)) button_down_clicked = 0; // unclick

    if ((digitalRead(BUTTON_SELECT_PIN) == LOW) && (button_select_clicked == 0)) 
    { // unclick 
      button_select_clicked = 1;
      current_screen = MAIN_MENU_SCREEN_items_idx+1;
    }
    if ((digitalRead(BUTTON_SELECT_PIN) == HIGH) && (button_select_clicked == 1)) button_select_clicked = 0; // unclick
  }

  if (current_screen == FEED_NOW_SCREEN) 
  {
    selectedItem = &FEED_NOW_SCREEN_items[FEED_NOW_SCREEN_items_idx];

    if ((digitalRead(BUTTON_UP_PIN) == LOW) && (button_up_clicked == 0)) 
    { // up button clicked - jump to previous menu item
      button_up_clicked = 1;

      if (edit_mode_on)
      {
        (*(selectedItem->value))--;
      }
      else if (FEED_NOW_SCREEN_items_idx != 0)
      {
        FEED_NOW_SCREEN_items_idx--; // select previous item
      }
    }
    if ((digitalRead(BUTTON_UP_PIN) == HIGH) && (button_up_clicked == 1)) button_up_clicked = 0; // unclick 
    
    if ((digitalRead(BUTTON_DOWN_PIN) == LOW) && (button_down_clicked == 0)) 
    { // down button clicked - jump to next menu item
      button_down_clicked = 1;

      if (edit_mode_on)
      {
        (*(selectedItem->value))++;
      }
      else if (FEED_NOW_SCREEN_items_idx < FEED_NOW_SCREEN_items_count - 1)
      {
        FEED_NOW_SCREEN_items_idx++; // select previous item
      }
    }
    if ((digitalRead(BUTTON_DOWN_PIN) == HIGH) && (button_down_clicked == 1)) button_down_clicked = 0; // unclick

    if ((digitalRead(BUTTON_SELECT_PIN) == LOW) && (button_select_clicked == 0)) 
    { // select button clicked
      button_select_clicked = 1; // set button to clicked to only perform the action once
      selectedItem->action();
    }
    if ((digitalRead(BUTTON_SELECT_PIN) == HIGH) && (button_select_clicked == 1)) button_select_clicked = 0; // unclick
  }

  if (current_screen == FEED_LATER_SCREEN)
  {
    selectedItem = &FEED_LATER_SCREEN_items[FEED_LATER_SCREEN_items_idx];

    if ((digitalRead(BUTTON_UP_PIN) == LOW) && (button_up_clicked == 0)) 
    { // up button clicked - jump to previous menu item
      button_up_clicked = 1;

      if ((FEED_LATER_SCREEN_feedingTime_idx != 0 && FEED_LATER_SCREEN_items_idx == 2) || FEED_LATER_SCREEN_items_idx == 0) ; //do nothing
      else FEED_LATER_SCREEN_items_idx--;

      if (FEED_LATER_SCREEN_items_idx >= 2)
      {
        // Select previous feeding time if there is one
        if (FEED_LATER_SCREEN_feedingTime_idx - 1 >= 0)
        {
          FEED_LATER_SCREEN_feedingTime_idx--;
          selectedFeedingTime = &feedingTimes[FEED_LATER_SCREEN_feedingTime_idx];

          // Is redrawing needed?
          if (FEED_LATER_SCREEN_items_idx == 2)
          {
            int print_idx = FEED_LATER_SCREEN_feedingTime_idx;
            for (int i = 2; i <= 6; i++)
            {
              FEED_LATER_SCREEN_items[i].text = feedingTimes[print_idx].toString();
              print_idx++;
            }
          }
        }
      }

      // Move selection
      //if (FEED_LATER_SCREEN_feedingTime_idx == 0 || FEED_LATER_SCREEN_items_idx != 0)
      //  FEED_LATER_SCREEN_items_idx = FEED_LATER_SCREEN_items_idx - 1;
    }
    if ((digitalRead(BUTTON_UP_PIN) == HIGH) && (button_up_clicked == 1)) button_up_clicked = 0; // unclick 
    
    if ((digitalRead(BUTTON_DOWN_PIN) == LOW) && (button_down_clicked == 0)) 
    { // down button clicked - jump to next menu item
      button_down_clicked = 1;

      if (FEED_LATER_SCREEN_items_idx >= 2) // First 2 item is not feedingTime
      {
        // Select next feeding time if there is one
        if (FEED_LATER_SCREEN_feedingTime_idx < feedingTimes_count-1)
        {
          FEED_LATER_SCREEN_feedingTime_idx++;
          selectedFeedingTime = &feedingTimes[FEED_LATER_SCREEN_feedingTime_idx];

          // Is redrawing needed?
          if (FEED_LATER_SCREEN_items_idx == 6)
          {
            int print_idx = FEED_LATER_SCREEN_feedingTime_idx-4;
            for (int i = 2; i <= 6; i++)
            {
              FEED_LATER_SCREEN_items[i].text = feedingTimes[print_idx].toString();
              print_idx++;
            }
          }
        }
      }

      // Move selection unless last item
      if (FEED_LATER_SCREEN_items_idx < FEED_LATER_SCREEN_items_count - 1)
        FEED_LATER_SCREEN_items_idx++;

    }
    if ((digitalRead(BUTTON_DOWN_PIN) == HIGH) && (button_down_clicked == 1)) button_down_clicked = 0; // unclick

    if ((digitalRead(BUTTON_SELECT_PIN) == LOW) && (button_select_clicked == 0)) 
    { // select button clicked
      button_select_clicked = 1; // set button to clicked to only perform the action once
      selectedItem->action();
    }
    if ((digitalRead(BUTTON_SELECT_PIN) == HIGH) && (button_select_clicked == 1)) button_select_clicked = 0; // unclick
  }


  if (current_screen == SETTINGS_SCREEN)
  {
    selectedItem = &SETTINGS_SCREEN_items[SETTINGS_SCREEN_items_idx];

    if ((digitalRead(BUTTON_UP_PIN) == LOW) && (button_up_clicked == 0)) 
    { // up button clicked - jump to previous menu item
      button_up_clicked = 1;

      if (edit_mode_on)
      {
        (*(selectedItem->value))--;
      }
      else if (SETTINGS_SCREEN_items_idx != 0)
      {
        SETTINGS_SCREEN_items_idx--; // select previous item
      }
    }
    if ((digitalRead(BUTTON_UP_PIN) == HIGH) && (button_up_clicked == 1)) button_up_clicked = 0; // unclick 
    
    if ((digitalRead(BUTTON_DOWN_PIN) == LOW) && (button_down_clicked == 0)) 
    { // down button clicked - jump to next menu item
      button_down_clicked = 1;

      if (edit_mode_on)
      {
        (*(selectedItem->value))++;
      }
      else if (SETTINGS_SCREEN_items_idx < SETTINGS_SCREEN_items_count - 1)
      {
        SETTINGS_SCREEN_items_idx++; // select previous item
      }
    }
    if ((digitalRead(BUTTON_DOWN_PIN) == HIGH) && (button_down_clicked == 1)) button_down_clicked = 0; // unclick

    if ((digitalRead(BUTTON_SELECT_PIN) == LOW) && (button_select_clicked == 0)) 
    { // select button clicked
      button_select_clicked = 1; // set button to clicked to only perform the action once
      selectedItem->action();
    }
    if ((digitalRead(BUTTON_SELECT_PIN) == HIGH) && (button_select_clicked == 1)) button_select_clicked = 0; // unclick
  }

  if (current_screen == EDITOR_SCREEN)
  {
    selectedItem = &EDITOR_SCREEN_items[EDITOR_SCREEN_items_idx];

    if ((digitalRead(BUTTON_UP_PIN) == LOW) && (button_up_clicked == 0)) 
    { // up button clicked - jump to previous menu item
      button_up_clicked = 1;

      if (edit_mode_on)
      {
        (*(selectedItem->value))--;
      }
      else if (EDITOR_SCREEN_items_idx != 0)
      {
        EDITOR_SCREEN_items_idx--; // select previous item
      }
    }
    if ((digitalRead(BUTTON_UP_PIN) == HIGH) && (button_up_clicked == 1)) button_up_clicked = 0; // unclick 
    
    if ((digitalRead(BUTTON_DOWN_PIN) == LOW) && (button_down_clicked == 0)) 
    { // down button clicked - jump to next menu item
      button_down_clicked = 1;

      if (edit_mode_on)
      {
        (*(selectedItem->value))++;
      }
      else if (EDITOR_SCREEN_items_idx < EDITOR_SCREEN_items_count - 1)
      {
        EDITOR_SCREEN_items_idx++; // select previous item
      }
    }
    if ((digitalRead(BUTTON_DOWN_PIN) == HIGH) && (button_down_clicked == 1)) button_down_clicked = 0; // unclick

    if ((digitalRead(BUTTON_SELECT_PIN) == LOW) && (button_select_clicked == 0)) 
    { // select button clicked
      button_select_clicked = 1; // set button to clicked to only perform the action once
      selectedItem->action();
    }
    if ((digitalRead(BUTTON_SELECT_PIN) == HIGH) && (button_select_clicked == 1)) button_select_clicked = 0; // unclick
  }


  // set correct values for the previous and next items
  item_sel_previous = MAIN_MENU_SCREEN_items_idx - 1;
  if (item_sel_previous < 0) {item_sel_previous = NUM_ITEMS - 1;} // previous item would be below first = make it the last
  item_sel_next = MAIN_MENU_SCREEN_items_idx + 1;  
  if (item_sel_next >= NUM_ITEMS) {item_sel_next = 0;} // next item would be after last = make it the first


  u8g.firstPage(); // required for page drawing mode for u8g library
  do {
    if (current_screen == MENU_SCREEN) {
      // selected item background
      u8g.drawBitmapP(0, 22, 128/8, 20, bitmap_selector);

      // draw previous item as icon + label
      u8g.setFont(u8g_font_7x14);
      u8g.drawStr(25, 15, menu_items[item_sel_previous]); 
      u8g.drawBitmapP( 4, 2, 16/8, 16, icons_array[item_sel_previous]);          

      // draw selected item as icon + label in bold font
      u8g.setFont(u8g_font_7x14B);    
      u8g.drawStr(25, 15+20+2, menu_items[MAIN_MENU_SCREEN_items_idx]);   
      u8g.drawBitmapP( 4, 24, 16/8, 16, icons_array[MAIN_MENU_SCREEN_items_idx]);     

      // draw next item as icon + label
      u8g.setFont(u8g_font_7x14);     
      u8g.drawStr(25, 15+20+20+2+2, menu_items[item_sel_next]);   
      u8g.drawBitmapP( 4, 46, 16/8, 16, icons_array[item_sel_next]);  

      // draw scrollbar handle
      u8g.drawBox(126, 64/NUM_ITEMS * MAIN_MENU_SCREEN_items_idx, 1, 64/NUM_ITEMS);             
    } 
    else if (current_screen == FEED_NOW_SCREEN) {
      u8g.setFontPosTop();
      u8g.setColorIndex(1);
      u8g.setFont(u8g_font_7x14);
      u8g.drawStr(26, 10, "Rations: ");

      for (auto item : FEED_NOW_SCREEN_items)
      {
        u8g.drawStr(item.x, item.y, item.toString().c_str());
      }

      drawSelection(*selectedItem);
    } 
    else if (current_screen == FEED_LATER_SCREEN)
    {
      u8g.setFontPosTop();
      u8g.setColorIndex(1);
      u8g.setFont(u8g_font_04b_03r);

      //u8g.drawStr(55, 5, String(FEED_LATER_SCREEN_feedingTime_idx).c_str()); 
      //u8g.drawStr(48, 5, String(FEED_LATER_SCREEN_items_idx).c_str()); 
      
      for (auto item : FEED_LATER_SCREEN_items)
      {
        u8g.drawStr(item.x, item.y, item.toString().c_str());
      }

      drawSelection(*selectedItem);
    }
    else if (current_screen == SETTINGS_SCREEN)
    {
      u8g.setFontPosTop();
      u8g.setColorIndex(1);
      u8g.setFont(u8g_font_04b_03r);
      u8g.drawStr(8, 15, "Time:");
      u8g.drawStr(8, 25, "Day:");
      u8g.drawStr(8, 35, "Date:");

      for (auto item : SETTINGS_SCREEN_items)
      {
        u8g.drawStr(item.x, item.y, item.toString().c_str());
      }

      drawSelection(*selectedItem);
    }
    else if (current_screen == EDITOR_SCREEN)
    {
      u8g.setFontPosTop();
      u8g.setColorIndex(1);
      u8g.setFont(u8g_font_04b_03r);
      u8g.drawStr(8, 15, "Enabled:");
      u8g.drawStr(66, 15, "Type:");
      u8g.drawStr(8, 25, "Rations:");
      u8g.drawStr(8, 35, "Time:");
      u8g.drawStr(8, 45, "Days:");
      u8g.drawStr(8, 55, "Date:");
      

      for (auto item : EDITOR_SCREEN_items)
      {
        u8g.drawStr(item.x, item.y, item.toString().c_str());
      }

      drawSelection(*selectedItem);
    }

  } while ( u8g.nextPage() ); // required for page drawing mode with u8g library


}