#ifndef __screen
#define __screen

#include <Adafruit_ST7789.h>
#include "include/config.h"
#include "include/screenids.h"


class ScreenManager;


enum class Button
{
  Top,
  Middle,
  Bottom
};


class BaseScreen
{
  public:
    BaseScreen(ScreenManager* screenManager, Adafruit_GFX* display)
    {
      this->screenManager = screenManager;
      this->display = display;
    }

    virtual ~BaseScreen() {}

    virtual void onShow() = 0;
    virtual void onButton(Button button) = 0;
    virtual void onTick() = 0;

    virtual ScreenId screenId() = 0;

  protected:
    uint16_t printCentered(const char* text, int16_t y);

    void drawLargeTextLineCentered(const char* text, int16_t y, uint16_t textColor, uint16_t backgroundColor);

    void drawArrowLeft(int16_t x, int16_t y, uint16_t color);
    void drawArrowRight(int16_t x, int16_t y, uint16_t color);
    void drawArrowUp(int16_t x, int16_t y, uint16_t color);
    void drawArrowDown(int16_t x, int16_t y, uint16_t color);

    ScreenManager* screenManager;
    Adafruit_GFX* display;
};



class ScreenManager
{
  public:
    ScreenManager(Adafruit_ST7789* display)
    {
      this->display = display;
    }

    void init();

    inline void button(Button button) { this->getCurrentScreen()->onButton(button); }
    inline void tick() { this->getCurrentScreen()->onTick(); }

    inline BaseScreen* getCurrentScreen() { return this->currentScreen; }


    template<class T> void show()
    {
      if (this->currentScreen != nullptr)
      {
        //currentScreen->onHide();
        delete this->currentScreen;
      }

      this->currentScreen = new T(this, this->display);
      this->currentScreen->onShow();
    }

    template<class T> void show(ScreenId onlyIfNotOn)
    {
      if (this->currentScreen == nullptr || this->currentScreen->screenId() != onlyIfNotOn)
        this->show<T>();
    }


    void displayOff();
    void displayOn();

  private:
    Adafruit_ST7789* display;
    BaseScreen* currentScreen = nullptr;
};

#endif
