//
// Created by robtor on 26.01.23.
//

#include "Menu.h"

namespace floatpump::menu {

    auto MenuEntryCheckable::toString() -> std::string {
        return buildString({(*m_storage) ? "ON " : "OFF"});
    }

    auto MenuEntryCheckable::u_press() -> void {
        *m_storage = !(*m_storage);
    }

    auto MenuEntryExecute::u_press() -> void {
        *m_storage = true;
    }

    auto MenuEntryExecute::toString() -> std::string {
        return buildString({(*m_storage) ? "[-]" : "[X]"});
    }

    auto MenuEntryNumeric::u_press() -> void {
        m_entered = !m_entered;
    }

    auto MenuEntryNumeric::u_increase(uint16_t steps) -> void {
        (*m_storage)++;
    }

    auto MenuEntryNumeric::u_decrease(uint16_t steps) -> void {
        (*m_storage)--;
    }

    auto MenuEntryNumeric::is_entered() -> bool {
        return m_entered;
    }

    auto MenuEntryNumeric::toString() -> std::string {
        if (m_entered) {
            return buildString({"> " + std::to_string(*m_storage)});
        } else {
            return buildString({"  " + std::to_string(*m_storage)});
        }
    }

    auto MenuEntryPercent::u_press() -> void {
        m_entered = !m_entered;
    }

    auto MenuEntryPercent::u_increase(uint16_t steps) -> void {
        if (*m_storage < 100)
            (*m_storage)++;
    }

    auto MenuEntryPercent::u_decrease(uint16_t steps) -> void {
        if (*m_storage > 0) {
            (*m_storage)--;
        }
    }

    auto MenuEntryPercent::is_entered() -> bool {
        return m_entered;
    }

    auto MenuEntryPercent::toString() -> std::string {
        if (m_entered) {
            return buildString({"> %" + std::to_string(*m_storage)});
        } else {
            return buildString({" %" + std::to_string(*m_storage)});
        }
    }

    auto Menu::getDisplayList() -> std::vector<std::string> {
        std::vector<std::string> list;

        list.reserve(m_submenus.size() + m_entries.size());

        //Append all Submenus
        for (auto &m_submenu: m_submenus) {
            list.push_back(m_submenu->printLine());
        }

        //Append all Entries
        for (auto &m_entry: m_entries) {
            list.push_back(m_entry->toString());
        }

        //Append Go-Back-Entry if we are within a submenu
        if (m_parent != nullptr) {
            list.emplace_back("<- Zurueck");
        }

        return list;
    }

    auto Menu::getSubmenu(int index) -> Menu * {
        if (index >= 0 && index < m_submenus.size()) {
            return m_submenus[index].get();
        } else {
            return nullptr;
        }
    }

    auto Menu::getEntry(int index) -> IMenuEntry* {
        if (index >= m_submenus.size() && index < m_entries.size() + m_submenus.size()) {
            return m_entries[index - m_submenus.size()].get();
        } else {
            return nullptr;
        }
    }
}