#ifndef Toolbox_Roll_Widget_H
#define Toolbox_Roll_Widget_H
#include <QObject>
#include <QHBoxLayout>
#include <algorithm>
#include <functional>
#include <vector>
namespace Toolbox {
    template<typename T>
    class Roll_Object : QObject {
    public:
        explicit Roll_Object(QObject *parent = nullptr) : QObject(parent) {}
        explicit Roll_Object(std::vector<T *> widgets, std::function<void(T *)> enter_func,
                            std::function<void(T *)> leave_func, QObject *parent) :
                widgets(std::move(widgets)), enter_func(enter_func), leave_func(leave_func), QObject(parent) {
            if (!this->widgets.empty() && enter_func) enter_func(this->widgets[index]);
        }
        int index = 0;
        std::vector<T *> widgets;
        std::function<void(T *)> enter_func;
        std::function<void(T *)> leave_func;
        T *cur() {
            if (widgets.empty()) return nullptr;
            return widgets[index];
        }
        void set_cur(T *cur) {
            if (widgets.empty()) return;
            auto it = std::find(widgets.begin(), widgets.end(), cur);
            if (it == widgets.end()) return;
            int new_index = static_cast<int>(std::distance(widgets.begin(), it));
            if (leave_func) leave_func(widgets[index]);
            index = new_index;
            if (enter_func) enter_func(widgets[index]);
            widgets[index]->update();
        }
        void roll_right() {
            if (widgets.empty()) return;
            if (leave_func) leave_func(widgets[index]);
            widgets[index]->update();
            if (widgets.back() != widgets[index]) {
                index++;
            } else {
                index = 0;
            }
            if (enter_func) enter_func(widgets[index]);
            widgets[index]->update();
        }
        void roll_left() {
            if (widgets.empty()) return;
            if (leave_func) leave_func(widgets[index]);
            widgets[index]->update();
            if (widgets.front() != widgets[index]) {
                index--;
            } else {
                index = static_cast<int>(widgets.size()) - 1;
            }
            if (enter_func) enter_func(widgets[index]);
            widgets[index]->update();
        }
        QHBoxLayout *hbox_layout(int space) {
            auto ret = new QHBoxLayout;
            ret->setMargin(0);
            ret->setSpacing(space);
            for (auto widget: widgets) {
                ret->addWidget(widget, 1);
            }
            return ret;
        }
    };
}
#endif



