#ifndef GPANTHERA_LIBRARY_H
#define GPANTHERA_LIBRARY_H

#include <gtkmm.h>
#include <glibmm.h>
#include <glibmm/ustring.h>
#include <utility>
#include <vector>
#include <memory>

namespace gPanthera {
    class DockStack;
    class DockWindow;
    class LayoutManager;

    class DockablePane : public Gtk::Box {
    private:
        Gtk::Label label;
        Glib::ustring name;
        Gtk::Image *icon;
        DockStack *stack;
        DockWindow *window = nullptr;
        std::unique_ptr<Gtk::HeaderBar> header;
        Gtk::Widget *child;
        std::shared_ptr<LayoutManager> layout;
    public:
        DockablePane(std::shared_ptr<LayoutManager> layout, Gtk::Widget &child, const Glib::ustring &name, const Glib::ustring &label, Gtk::Image *icon, DockStack *stack = nullptr, Gtk::Widget *custom_header = nullptr);
        Glib::ustring get_identifier() const;
        Gtk::Image *get_icon() const;
        Gtk::Label *get_label();
        void redock(DockStack *stack);
        void pop_out();
        Gtk::Widget *get_child() const;
    };

    class DockWindow : public Gtk::Window {
    private:
        DockablePane *pane;
    public:
        explicit DockWindow(DockablePane *pane);
    };

    class LayoutManager : public Glib::ObjectBase {
    private:
        std::vector<DockablePane*> panes;
    public:
        std::vector<DockStack*> stacks;
        LayoutManager();

        void add_pane(DockablePane *pane);

        void add_stack(DockStack *stack);
    };

    class DockStack : public Gtk::Stack {
    private:
        std::shared_ptr<LayoutManager> layout;
    public:
        Glib::ustring name;
        explicit DockStack(std::shared_ptr<LayoutManager> layout, const Glib::ustring &name);

        void add_pane(DockablePane &child);
    };

    class DockStackSwitcher : public Gtk::ButtonBox {
    private:
        DockStack *stack;
    public:
        void update_buttons();
        explicit DockStackSwitcher(DockStack *stack);
    };
} // namespace gPanthera

#endif // GPANTHERA_LIBRARY_H