/***************************************************************************
 **
 **  Copyright (C) 2018-2023 wangjianjun <wangjianjun1018@qq.com>
 **  Contact: https://blog.csdn.net/wocanimei007?type=blog
 **
 **
****************************************************************************/
#include "fancymodebar.h"
#include "fancymode.h"

#include <QStackedWidget>



/* FancyModeBarPrivate */
class FancyModeBarPrivate : public QObject
{
    Q_OBJECT
public:
    FancyModeBarPrivate();
    virtual ~FancyModeBarPrivate();

    inline bool validIndex(int index)
    { return index >= 0 && index < m_modes.size(); }

    void init();

public slots:
    void showMenu(int index, QPoint pos);
    void hideMenu();

public:
    FancyModeBar *q;
    QStackedWidget *m_modeStack;
    QList<FancyMode *> m_modes;
    int m_menuIndex;
};

FancyModeBarPrivate::FancyModeBarPrivate()
    : m_menuIndex(-1)
{
}

FancyModeBarPrivate::~FancyModeBarPrivate()
{}

void FancyModeBarPrivate::init()
{
    connect(q, SIGNAL(currentChanged(int)), m_modeStack, SLOT(setCurrentIndex(int)));
    connect(q, SIGNAL(menuTriggered(int, QPoint)), this, SLOT(showMenu(int, QPoint)));
}

void FancyModeBarPrivate::showMenu(int index, QPoint pos)
{
    if (m_modes.at(index)->menu()) {
        m_menuIndex = index;
        m_modes.at(index)->menu()->popup(pos);
    }
}

void FancyModeBarPrivate::hideMenu()
{
    q->hideMenu(m_menuIndex);
}

/* FancyModeBar */
FancyModeBar::FancyModeBar(QStackedWidget *modeStack, QWidget *parent)
    : FancyTabBar(parent)
    , d(new FancyModeBarPrivate())
{
    Q_ASSERT(modeStack);

    d->q = this;
    d->m_modeStack = modeStack;
    d->init();
}

FancyModeBar::~FancyModeBar()
{
    delete d;
}

void FancyModeBar::addMode(FancyMode *mode)
{
    if (mode == nullptr) {
        return;
    }
    int index = 0;
    foreach (const FancyMode * m, d->m_modes) {
        if (m->priority() >= mode->priority()) {
            ++index;
        }
    }
    d->m_modes.insert(index, mode);
    d->m_modeStack->insertWidget(index, mode->widget());
    insertTab(index, mode->icon(), mode->displayName(), mode->menu() != nullptr);
    setTabEnabled(index, mode->isEnabled());

    if (mode->menu()) {
        connect(mode->menu(), SIGNAL(aboutToHide()), d, SLOT(hideMenu()));
    }
}

void FancyModeBar::removeMode(FancyMode *mode)
{
    if (mode == nullptr) {
        return;
    }
    int index = d->m_modes.indexOf(mode);
    if (index == -1) {
        return;
    }
    d->m_modes.removeAt(index);
    removeTab(index);
}

void FancyModeBar::setCurrentMode(FancyMode *mode)
{
    int index = d->m_modes.indexOf(mode);
    setCurrentIndex(index);
}

FancyMode *FancyModeBar::currentMode() const
{
    int currentIndex = d->m_modeStack->currentIndex();
    if (currentIndex < 0) {
        return nullptr;
    }
    return d->m_modes.at(currentIndex);
}

FancyMode *FancyModeBar::mode(int index) const
{
    if (d->validIndex(index)) {
        return d->m_modes.at(index);
    }
    return nullptr;
}

void FancyModeBar::setModeEnabled(FancyMode *mode, bool enable)
{
    int index = d->m_modes.indexOf(mode);
    setTabEnabled(index, enable);
}

void FancyModeBar::setModeVisible(FancyMode *mode, bool visible)
{
    int index = d->m_modes.indexOf(mode);
    setTabVisible(index, visible);
}



#include "fancymodebar.moc"
