#include "customTabBar.h"
#include "customTab.h"
#include "dashboardFrame.h"

#include <QBoxLayout>
#include <QDragEnterEvent>
#include <QMimeData>

CustomTabBar::CustomTabBar(QWidget* parent)
    :QScrollArea(parent)
{
    setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
    setFrameStyle(QFrame::NoFrame);
    setWidgetResizable(true);
    setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
    setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);

    m_pFrame = nullptr;

    m_pPosMarking = new QWidget(this);
    m_pPosMarking->setStyleSheet("QWidget{\n"
                  "   border:0px;\n"
                  "   background-color:rgb(200,200,200);\n"
                  "}\n");
    m_pPosMarking->setMaximumWidth(3);
    m_pPosMarking->setMinimumWidth(3);
    m_pPosMarking->hide();

    m_nCurrentIndex = -1;
    m_pTabsContainerWidget = new QWidget(this);
    m_pTabsContainerWidget->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
    m_pTabsContainerWidget->setObjectName("tabsContainerWidget");
    m_pTabsLayout = new QBoxLayout(QBoxLayout::LeftToRight);
    m_pTabsLayout->setContentsMargins(0, 0, 0, 0);
    m_pTabsLayout->setSpacing(0);
    m_pTabsLayout->addStretch(1);
    m_pTabsContainerWidget->setLayout(m_pTabsLayout);
    setWidget(m_pTabsContainerWidget);

    setFocusPolicy(Qt::NoFocus);
    setAcceptDrops(true);
}

CustomTabBar::~CustomTabBar()
{
}

void CustomTabBar::dragEnterEvent(QDragEnterEvent* event)
{
    const QMimeData* mimeData = event->mimeData();
    if( mimeData->hasFormat("dragData/customTab") )
    {
        event->acceptProposedAction();
        //qDebug() << "dragEnterEvent-tabBar";
    }
    else
        event->ignore();
}

void CustomTabBar::dragMoveEvent(QDragMoveEvent* event)
{
    //qDebug() << "dragMoveEvent";
    event->acceptProposedAction();

    if(m_pTabsLayout->count() == 1) //没有tab
        return;

    int toIndex = -1;
    int lastWidgetIndex = m_pTabsLayout->count() - 2;
    QWidget* lastWidget = m_pTabsLayout->itemAt(lastWidgetIndex)->widget();
    if(lastWidget && event->position().x() > lastWidget->geometry().right()) //移到最后
        toIndex = lastWidgetIndex;
    else
    {
        for (int i = 0; i < count(); ++i)
        {
            CustomTab* dropTab = tab(i);
            if(!dropTab)
                continue;

            QRect tabGeometry = dropTab->geometry();
            if( !tabGeometry.contains(event->position().toPoint()) )
                continue;

            toIndex = m_pTabsLayout->indexOf(dropTab);
            if(toIndex > 0 && m_pPosMarking->isVisible())
            {
                int nIndex = toIndex - 1;
                if(m_pTabsLayout->indexOf(m_pPosMarking) == nIndex)//判断上一帧是否已经将posMarking放入到该tab之前
                    toIndex = -1;
                else if(m_pTabsLayout->indexOf(m_pPosMarking) < toIndex)//在dropTab之前插入了posMarking会让dropTab的索引放生变化（+1）
                    toIndex -= 1;
            }
            break;
        }
    }

    //qDebug() << toIndex;
    if(toIndex != -1)
    {
        m_pPosMarking->show();
        m_pTabsLayout->insertWidget(toIndex, m_pPosMarking);
    }
}

void CustomTabBar::dragLeaveEvent(QDragLeaveEvent* event)
{
    //qDebug() << "dragLeaveEvent-tabBar";
    if(m_pPosMarking->isVisible())
    {
        m_pPosMarking->hide();
        m_pTabsLayout->removeWidget(m_pPosMarking);
    }
}

void CustomTabBar::dropEvent(QDropEvent* event)
{
    //qDebug() << "dropEvent-tabBar";
    event->setDropAction(Qt::MoveAction);
    event->accept();

    int toIndex = m_pTabsLayout->indexOf(m_pPosMarking);
    m_pPosMarking->hide();
    m_pTabsLayout->removeWidget(m_pPosMarking);

    QByteArray itemData = event->mimeData()->data("dragData/customTab");
    QDataStream dataStream(&itemData, QIODevice::ReadOnly);
    QString strTabText = "";
    QString strFromFrame = "";
    dataStream >> strTabText >> strFromFrame;

    if(!m_pFrame)
        return;

    if(strFromFrame == m_pFrame->objectName()) //同一组的tab，做移动操作
    {
        CustomTab* sourceObj = qobject_cast<CustomTab*>(event->source());
        if(!sourceObj)
            return;
        int fromIndex = m_pTabsLayout->indexOf(sourceObj);

        if(toIndex > fromIndex)//因为被移动的tab要先remove出来再insert，如果是向后移动，remove会引起索引的变化，所以要-1
            toIndex -= 1;

        if(toIndex != fromIndex) //移动
        {
            m_pTabsLayout->removeWidget(sourceObj);
            m_pTabsLayout->insertWidget(toIndex, sourceObj);
            emit tabMoved(fromIndex, toIndex);
        }
        //qDebug() << fromIndex << toIndex;
    }
    else
    {
        DashboardFrame* fromFrame = m_pFrame->getDashboardFrame(strFromFrame);
        if(fromFrame != m_pFrame && fromFrame != nullptr)
        {
            Dashboard* dashboard = fromFrame->takeDashboard(strTabText);
            m_pFrame->insertDashboard(toIndex, dashboard);
        }
    }
}

void CustomTabBar::setFrame(DashboardFrame* frame)
{
    m_pFrame = frame;
}
DashboardFrame* CustomTabBar::frame()
{
    return m_pFrame;
}

int CustomTabBar::count()
{
    //含有一个stretch
    return m_pTabsLayout->count() - 1;
}

void CustomTabBar::insertTab(int index, CustomTab* tab)
{
    if(index < 0)
        index = 0;
    else if(index > count())
        index = count();

    m_pTabsLayout->insertWidget(index, tab);
    ensureWidgetVisible(tab); //定位到可以显示该tab的位置
}

void CustomTabBar::addTab(CustomTab* tab)
{
    insertTab(count(), tab);
}
void CustomTabBar::removeTab(CustomTab* tab)
{
    m_pTabsLayout->removeWidget(tab);
}

CustomTab* CustomTabBar::tab(int index)
{
    if (index >= count() || index < 0)
    {
        return nullptr;
    }
    return qobject_cast<CustomTab*>(m_pTabsLayout->itemAt(index)->widget());
}

void CustomTabBar::onTabClicked()
{

}
