#include "../include/shared.hpp"
#include "include/menu.hpp"
#include <PSX/Periphery/periphery.hpp>
#include <PSX/SPU/spu.hpp>

namespace Menu {
    using DigitalButton = Periphery::GenericController::Button;

    void SimpleMenu :: setup(Callback callback, const Entry* entries, size_t size) {
        this->selection_callback = callback;
        this->entries            = entries;
        this->size               = size;
        this->cur_selection      = 0;
    }

    void SimpleMenu :: update(JabyEngine::FontWriter& font_writer, Cursor& cursor, const GPU::PositionI16& start) {
        const auto& controller = Periphery::get_primary_controller_as<JabyEngine::Periphery::GenericController>();

        if(controller.button.went_down(DigitalButton::Up) && this->cur_selection > 0) {
            this->cur_selection -= 1;
        } 

        if(controller.button.went_down(DigitalButton::Down) && this->cur_selection < (this->size - 1)) {
            this->cur_selection += 1;
        }

        if(controller.button.went_down(DigitalButton::Cross)) {
            SPU::voice[0].play();
            this->selection_callback(this->cur_selection);
        }

        cursor.pos = Make::PositionI16(8, 64);
        for(size_t n = 0; n < this->size; n++) {
            const auto& cur_entry = this->entries[n];

            if(this->cur_selection == n) {
                FontWriter::bios_font_writer.write(cursor, ">%s<\n", cur_entry.name);
            }

            else {
                FontWriter::bios_font_writer.write(cursor, "%s\n", cur_entry.name);
            }
        }
    }

    void BackMenu :: setup(JabyEngine::FontWriter* font_writer) {
        this->font_writer = font_writer;
        this->timeout.reset();
        this->waiting = false;
    }

    bool BackMenu :: update(const GPU::PositionI16& position, bool auto_clear) {
        const auto& controller = Periphery::get_primary_controller_as<JabyEngine::Periphery::GenericController>();

        if(Shared::load_test || controller.button.is_down(DigitalButton::Circle)) {
            this->waiting = true;
            if(this->timeout.is_expired_for(2500_ms)) {
                return true;
            }
        }
        
        else {
            this->waiting = false;
            this->timeout.reset();
        }

        if(this->waiting) {
            auto cursor = JabyEngine::Cursor::create(position);
            this->font_writer->write(cursor, "Press and hold O\nto get back", GPU::Color24::Red(0xD0));
        }

        else if(auto_clear) {
            this->font_writer->clear();
        }
        return false;
    }

    void BackMenu :: render() {
        this->font_writer->render();
    }
}