#include "dashboardFrame.h"
#include "./ui_dashboardFrame.h"
#include "dvieMainWindow.h"
#include "dvieSecondaryWindow.h"
#include "transparentMask.h"
#include "messageDialog.h"
#include "customTabBar.h"
#include "dashboard.h"
#include "customTab.h"
#include "dataPanel.h"
#include "dashboardNamingDialog.h"
#include "panelSelectionDialog.h"
#include "dataPanel/dpConfigurationDialog.h"
#include "dateTimeWidget.h"
#include "util/TimeLine/timeLineWidget.h"
#include "alarmEventRealTimeDock.h"
#include "alarmEventMainDialog.h"
#include "alarmEventConfigDialog.h"

#include <QKeyEvent>
#include <QMenu>
#include <QTimer>
#include <QDateTime>
#include <QMimeData>

DashboardFrame::DashboardFrame(const QString& strName, dashboardFrame::frameType fType, QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::dashboardFrame)
    , m_pParentWindow(nullptr)
    , m_pTransparentMask(nullptr)
    , m_pDashboardHighlight(nullptr)
    , m_pMessageDialog(nullptr)
    , m_pDashboardTabBar(nullptr)
    , m_pDashboardNamingDialog(nullptr)
    , m_curActiveDashboard(nullptr)
    , m_curOperationDashboard(nullptr)
    , m_pPanelSelectionDialog(nullptr)
    , m_pPanelConfigurationDialog(nullptr)
    , m_pAlarmEventRealTimeDock(nullptr)
    , m_pAlarmEventMainDialog(nullptr)
    , m_pAlarmEventConfigDialog(nullptr)
{
    ui->setupUi(this);
    setAcceptDrops(true);

    m_strName = strName;
    setObjectName(strName);
    m_pParentWindow = parent;
    m_type = fType;
    if(m_type == dashboardFrame::ft_main) //只有主window具有报警提示
    {
        m_pAlarmEventRealTimeDock = new AlarmEventRealTimeDock(this);
        connect(m_pAlarmEventRealTimeDock, &AlarmEventRealTimeDock::viewAllRealTimeEvents, this, &DashboardFrame::onSignal_viewAllRealTimeEvents);
        connect(m_pAlarmEventRealTimeDock, &AlarmEventRealTimeDock::openConfigDialog, this, &DashboardFrame::onSignal_openAlarmEventCfgDialog);

        m_pAlarmEventMainDialog = new AlarmEventMainDialog(this);
        connect(m_pAlarmEventMainDialog, SIGNAL(sgl_hide()), this, SLOT(onSignal_subDialogClose()));
        connect(m_pAlarmEventMainDialog, &AlarmEventMainDialog::openConfigDialog, this, &DashboardFrame::onSignal_openAlarmEventCfgDialog);
        m_pAlarmEventMainDialog->hide();

        m_pAlarmEventConfigDialog = new AlarmEventConfigDialog(this);
        connect(m_pAlarmEventConfigDialog, SIGNAL(sgl_hide()), this, SLOT(onSignal_subDialogClose()));
        m_pAlarmEventConfigDialog->hide();
    }
    else
    {
        ui->btnAllEvent->setVisible(false);
        ui->btnAlarm->setVisible(false);
    }

    initializeGlobalVariable();

    m_pDateTimeWidget = new DateTimeWidget(this);
    m_pDateTimeWidget->setObjectName("dateTimeWidget");
    ui->layout_dateTime->addWidget(m_pDateTimeWidget);
    connect(m_pDateTimeWidget, SIGNAL(showMask()), this, SLOT(onSignal_showMask()));
    connect(m_pDateTimeWidget, SIGNAL(hideMask()), this, SLOT(onSignal_hideMask()));
    connect(m_pDateTimeWidget, SIGNAL(viewRealTimeData()), this, SLOT(onSignal_viewRealTimeData()));
    connect(m_pDateTimeWidget, SIGNAL(viewHistoricalData(QDateTime)), this, SLOT(onSignal_viewHistoricalData(QDateTime)));
    connect(m_pDateTimeWidget, SIGNAL(timeRangeChanged(TimeUnit)), this, SLOT(onSignal_timeRangeChanged(TimeUnit)));

    m_pDashboardTabBar = new CustomTabBar(this);
    m_pDashboardTabBar->setFrame(this);
    ui->hLayout_dashboardTabBar->addWidget(m_pDashboardTabBar);
    //connect(m_pDashboardTabBar, SIGNAL(tabMoved(int, int)), this, SLOT(onSignal_dashboardTabMoved(int, int)));
    connect(m_pDashboardTabBar, &CustomTabBar::tabMoved, this, &DashboardFrame::onSignal_dashboardTabMoved);

    m_pTimeLineWidget = new TimeLineWidget(this);
    m_pTimeLineWidget->setObjectName("timeLineWidget");
    m_pTimeLineWidget->setBackground(QColor(24, 32, 38));
    m_pTimeLineWidget->setTimelineColor(QColor(250, 250, 250));
    m_pTimeLineWidget->setTimeScaleSize(200);
    ui->layout_timeLine->addWidget(m_pTimeLineWidget);
    connect(m_pTimeLineWidget, SIGNAL(viewHistoricalData(QDateTime)), this, SLOT(onSignal_viewHistoricalData(QDateTime)));
    connect(m_pTimeLineWidget, SIGNAL(timeScaleUnitChanged(TimeUnit)), this, SLOT(onSignal_timeRangeChanged(TimeUnit)));
    m_pTimeLineWidget->syncTimeUnit();

    connect(ui->btnAddDashboard, SIGNAL(clicked()), this, SLOT(onBtnClicked_addDashboard()));
    connect(ui->btnAddPanel, SIGNAL(clicked()), this, SLOT(onBtnClicked_addDataPanel()));
    //connect(ui->btnDashboradList1, SIGNAL(clicked()), this, SLOT(onBtnClicked_dashboardList()));
    connect(ui->btnDashboradList2, SIGNAL(clicked()), this, SLOT(onBtnClicked_dashboardList()));
    connect(ui->btnAlarm, SIGNAL(clicked()), this, SLOT(onBtnClicked_showRealtimeEvents()));
    connect(ui->btnAllEvent, SIGNAL(clicked()), this, SLOT(onBtnClicked_showHistoricalEvents()));

    m_pTimer_RealTime = new QTimer(this);
    m_pTimer_RealTime->setTimerType(Qt::PreciseTimer); //设置成高精度类型，默认为Qt::CoarseTimer(粗糙定时器)
    connect(m_pTimer_RealTime, SIGNAL(timeout()), this, SLOT(onTimeout_realTime()));
    m_pTimer_RealTime->start(1000);

    //暂时放弃这两个按钮的逻辑
    ui->btnShowDashboards->setVisible(false);
    ui->btnShowNotifications->setVisible(false);
}

DashboardFrame::~DashboardFrame()
{
    delete ui;

    if(m_pTimer_RealTime->isActive())
        m_pTimer_RealTime->stop();
}

bool DashboardFrame::eventFilter(QObject* obj, QEvent* event)
{
    QDialog *pDialog = qobject_cast<QDialog*>(obj);
    if(pDialog)
    {
        if(event->type() == QEvent::KeyPress)
        {
            QKeyEvent* pKeyEvent = static_cast<QKeyEvent*>(event);
            if (pKeyEvent->key() == Qt::Key_Escape)
            {
                return true;
            }
        }
    }
    return QObject::eventFilter(obj, event);
}

void DashboardFrame::resizeEvent(QResizeEvent* event)
{
    //qDebug() << "oldSize:" << event->oldSize() << " size:" << event->size();
    if(event->oldSize() != QSize(-1, -1)) //Qt默认的初始化创建过程中会有从QSize(-1, -1)的变化，需要忽略
    {
        if(m_pTransparentMask  && m_pTransparentMask->isVisible())
            m_pTransparentMask->setGeometry(0, 0, this->width(), this->height());

        if(m_pMessageDialog  && m_pMessageDialog->isVisible())
        {
            int nX = (ui->navigationPanel->width() - m_pMessageDialog->width()) * 0.5;
            int nY = ui->navigationPanel->y() + ui->navigationPanel->height() * 0.5;
            m_pMessageDialog->move(nX, nY);
        }

        if(m_pDashboardNamingDialog  && m_pDashboardNamingDialog->isVisible())
        {
            int nX = (ui->navigationPanel->width() - m_pDashboardNamingDialog->width()) * 0.5;
            int nY = ui->navigationPanel->y() + ui->navigationPanel->height() * 0.5;
            m_pDashboardNamingDialog->move(nX, nY);
        }

        if(m_pAlarmEventMainDialog  && m_pAlarmEventMainDialog->isVisible())
        {
            int nWidth = this->width() * 0.8;
            int nHeight = this->height() * 0.8;
            int nX = this->geometry().x() + (this->width() - nWidth) * 0.5;
            int nY = this->geometry().y() + (this->height() - nHeight) * 0.5;
            m_pAlarmEventMainDialog->setGeometry(nX, nY, nWidth, nHeight);
        }

        if(m_pAlarmEventConfigDialog  && m_pAlarmEventConfigDialog->isVisible())
        {
            int nX = this->geometry().x() + (this->width() - m_pAlarmEventConfigDialog->width()) * 0.5;
            int nY = this->geometry().y() + (this->height() - m_pAlarmEventConfigDialog->height()) * 0.5;
            m_pAlarmEventConfigDialog->move(nX, nY);
        }

        double ratioX = (double)event->size().width() / (double)event->oldSize().width();
        double ratioY = (double)event->size().height() / (double)event->oldSize().height();
        //qDebug() << ratioX << ", " << ratioY;
        if(m_curActiveDashboard)
            m_curActiveDashboard->resizePanel(ratioX, ratioY);
    }

    if(m_pAlarmEventRealTimeDock)
        m_pAlarmEventRealTimeDock->updateGeometry();

    QWidget::resizeEvent(event);
}

void DashboardFrame::moveEvent(QMoveEvent* event)
{
    Q_UNUSED(event);
    if(m_pAlarmEventRealTimeDock)
        m_pAlarmEventRealTimeDock->updateGeometry();
}

void DashboardFrame::dragEnterEvent(QDragEnterEvent* event)
{
    const QMimeData* mimeData = event->mimeData();
    if( mimeData->hasFormat("dragData/customTab") )
    {
        event->acceptProposedAction();
        setDashboardAreaHighlight(true);
        //qDebug() << "dragEnterEvent-frame";
    }
    else
        event->ignore();
}
void DashboardFrame::dragLeaveEvent(QDragLeaveEvent* event)
{
    setDashboardAreaHighlight(false);
    //qDebug() << "dragLeaveEvent-frame";
}
void DashboardFrame::dropEvent(QDropEvent* event)
{
    //qDebug() << "dropEvent-frame";
    setDashboardAreaHighlight(false);
    event->setDropAction(Qt::MoveAction);
    event->accept();

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

    if(strFromFrame != this->objectName()) //来自别的frame
    {
        for(int n=0; n<m_listDashboard.count(); n++)
        {
            if(m_listDashboard.at(n)->name() == strTabText)
            {
                QString strError = QString::fromStdWString(L"已存在同名看板");
                showTransparentMask();
                showMessageDialog(type_warning, QString::fromWCharArray(L"错误"), strError);
                return;
            }
        }

        DashboardFrame* fromFrame = getDashboardFrame(strFromFrame);
        if(fromFrame != this && fromFrame != nullptr)
        {
            Dashboard* dashboard = fromFrame->takeDashboard(strTabText);
            addDashboard(dashboard);
        }
    }
}

void DashboardFrame::showTransparentMask()
{
    if(m_pParentWindow) //遮罩作为子组件最多只能在自身范围内覆盖，无法覆盖到父组件，因此需要父组件其它部分需要父组件去完成
    {
        if(m_type == dashboardFrame::ft_main)
        {
            DvieMainWindow* dvieWindow = qobject_cast<DvieMainWindow*>(m_pParentWindow);
            if(dvieWindow)
                dvieWindow->showTransparentMask();
        }
        else if(m_type == dashboardFrame::ft_secondary)
        {
            DvieSecondaryWindow* dvieWindow = qobject_cast<DvieSecondaryWindow*>(m_pParentWindow);
            if(dvieWindow)
                dvieWindow->showTransparentMask();
        }
    }

    if(m_pTransparentMask == nullptr)
        m_pTransparentMask = new TransparentMask(this);

    m_pTransparentMask->setGeometry(0, 0, this->width(), this->height());
    m_pTransparentMask->show();
}
void DashboardFrame::hideTransparentMask()
{
    if(m_type == dashboardFrame::ft_main)
    {
        DvieMainWindow* dvieWindow = qobject_cast<DvieMainWindow*>(m_pParentWindow);
        if(dvieWindow)
            dvieWindow->hideTransparentMask();
    }
    else if(m_type == dashboardFrame::ft_secondary)
    {
        DvieSecondaryWindow* dvieWindow = qobject_cast<DvieSecondaryWindow*>(m_pParentWindow);
        if(dvieWindow)
            dvieWindow->hideTransparentMask();
    }

    if(m_pTransparentMask && m_pTransparentMask->isVisible())
        m_pTransparentMask->hide();
}

void DashboardFrame::showMessageDialog(MessageDialogType type,const QString& strTitle,const QString& strContent)
{
    if(m_pMessageDialog == nullptr)
    {
        m_pMessageDialog = new MessageDialog(this);
        m_pMessageDialog->installEventFilter(this);
        connect(m_pMessageDialog, SIGNAL(sgl_hide()), this, SLOT(onSignal_subDialogClose()));
    }

    m_pMessageDialog->setMessage(type, strTitle, strContent);
    int nX = (ui->navigationPanel->width() - m_pMessageDialog->width()) * 0.5;
    int nY = ui->navigationPanel->y() + ui->navigationPanel->height() * 0.5;
    m_pMessageDialog->move(nX, nY);
    m_pMessageDialog->raise();
    if(type == type_question)
        m_pMessageDialog->exec();
    else
        m_pMessageDialog->show();
}

void DashboardFrame::addDashboard(const QString& strName)
{
    Dashboard* dashboard = new Dashboard(strName);
    insertDashboard(m_listDashboard.count(), dashboard);
}
void DashboardFrame::addDashboard(Dashboard* dashboard)
{
    insertDashboard(m_listDashboard.count(), dashboard);
}
void DashboardFrame::insertDashboard(int index, Dashboard* dashboard)
{
    if(index < 0)
        index = 0;
    else if(index > m_listDashboard.count())
        index = m_listDashboard.count();

    dashboard->setFrame(this);
    connect(dashboard, SIGNAL(sgl_rename()), this, SLOT(onSignal_renameDashboard()));
    connect(dashboard, SIGNAL(sgl_remove()), this, SLOT(onSignal_removeDashboard()));
    dashboard->setDisplayAreaLayout(ui->hLayout_dashboardDisplayArea);

    //添加tab
    CustomTab* tab = dashboard->tab();
    m_pDashboardTabBar->insertTab(index, tab);
    connect(tab, SIGNAL(clicked()), this, SLOT(onBtnClicked_dashboardTab()));

    m_listDashboard.insert(index, dashboard);
    if(m_curActiveDashboard)
        m_curActiveDashboard->setActive(false);
    dashboard->setActive(true);
    m_curActiveDashboard = dashboard;
}
int DashboardFrame::dashboardCount()
{
    return m_listDashboard.count();
}

Dashboard* DashboardFrame::getDashboard(const QString& strName)
{
    Dashboard* dashboard = nullptr;
    for(int n=0; n<m_listDashboard.count(); n++)
    {
        if(m_listDashboard.at(n)->name() == strName)
        {
            dashboard = m_listDashboard.at(n);
            break;
        }
    }
    return dashboard;
}
Dashboard* DashboardFrame::takeDashboard(const QString& strName)
{
    Dashboard* dashboard = getDashboard(strName);
    dashboard->setParent(nullptr);
    if(dashboard)
        removeDashboard(strName, false);
    return dashboard;
}

DashboardFrame* DashboardFrame::getDashboardFrame(const QString& strName)
{
    DashboardFrame* frame = nullptr;
    if(strName == m_strName)
        frame = this;

    if(m_type == dashboardFrame::ft_main)
    {
        DvieMainWindow* dvieWindow = qobject_cast<DvieMainWindow*>(m_pParentWindow);
        if(dvieWindow)
            frame = dvieWindow->getDashboardFrame(strName);
    }
    else if(m_type == dashboardFrame::ft_secondary)
    {
        DvieSecondaryWindow* dvieWindow = qobject_cast<DvieSecondaryWindow*>(m_pParentWindow);
        if(dvieWindow)
            frame = dvieWindow->getDashboardFrame(strName);
    }

    return frame;
}

void DashboardFrame::removeDashboard(const QString& strName, bool bDelete) //右键删除和移动到别的frame下均会调用该函数，只有删除时才会delete
{
    int nIndex = 0;
    Dashboard* dashboard = nullptr;
    for(int n=0; n<m_listDashboard.count(); n++)
    {
        if(m_listDashboard.at(n)->name() == strName)
        {
            nIndex = n;
            dashboard = m_listDashboard.at(n);
            break;
        }
    }
    if( !dashboard )
        return;

    if(dashboard == m_curActiveDashboard) //删除的是当前所选
    {
        dashboard->setActive(false);
        if(m_listDashboard.count() == 1) //唯一一个
            m_curActiveDashboard = nullptr;
        else
        {
            if(nIndex != 0) //不是第一个，将其前一个置为选中状态
            {
                m_listDashboard.at(nIndex - 1)->setActive(true);
                m_curActiveDashboard = m_listDashboard.at(nIndex - 1);
            }
            else //是第一个,将下一个置为选中状态
            {
                m_listDashboard.at(nIndex + 1)->setActive(true);
                m_curActiveDashboard = m_listDashboard.at(nIndex + 1);
            }
        }
    }

    CustomTab* tab = dashboard->tab();
    if(tab)
        m_pDashboardTabBar->removeTab(tab);
    m_listDashboard.removeAt(nIndex);
    if(bDelete)
    {
        dashboard->deleteSubWidgets();
        delete dashboard;
    }
    else
    {
        dashboard->disconnect(this); //断开和当前frame的信号/槽链接
    }

    if(m_type == dashboardFrame::ft_secondary && m_listDashboard.count() == 0)
    {
        DvieSecondaryWindow* dvieWindow = qobject_cast<DvieSecondaryWindow*>(m_pParentWindow);
        if(dvieWindow)
            dvieWindow->close();
    }
}

void DashboardFrame::setCurrentDashboard(const QString& strName)
{
    for(int n=0; n<m_listDashboard.count(); n++)
    {
        if(m_listDashboard.at(n)->name() == strName)
        {
            if(m_listDashboard.at(n) == m_curActiveDashboard)
                return;

            m_curActiveDashboard->setActive(false);
            m_listDashboard.at(n)->setActive(true);
            CustomTab* tab = m_listDashboard.at(n)->tab();
            m_pDashboardTabBar->ensureWidgetVisible(tab);
            m_curActiveDashboard = m_listDashboard.at(n);
            return;
        }
    }
}

void DashboardFrame::setDashboardAreaHighlight(bool bVisible)
{
    if(m_pDashboardHighlight == nullptr)
    {
        m_pDashboardHighlight = new QWidget(this);
        m_pDashboardHighlight->setStyleSheet("background-color: rgba(0, 141, 212, 85);");
    }

    if(bVisible)
    {
        m_pDashboardHighlight->setGeometry(ui->mainStack->geometry());
        m_pDashboardHighlight->show();
    }
    else
        m_pDashboardHighlight->hide();
}

void DashboardFrame::moveDashboardToNewDVIEWindow(const QString& strDashboard, QPoint pos)
{
    Dashboard* dashboard = takeDashboard(strDashboard);
    if(dashboard)
    {
        if(m_type == dashboardFrame::ft_main)
        {
            DvieMainWindow* dvieWindow = qobject_cast<DvieMainWindow*>(m_pParentWindow);
            if(dvieWindow)
                dvieWindow->creatSecondaryWindowAndAddDashboard(pos, dashboard);
        }
        else if(m_type == dashboardFrame::ft_secondary)
        {
            DvieSecondaryWindow* dvieWindow = qobject_cast<DvieSecondaryWindow*>(m_pParentWindow);
            if(dvieWindow)
            {
                dvieWindow->creatSecondaryWindowAndAddDashboard(pos, dashboard);
                // if(m_listDashboard.count() == 0)
                //     dvieWindow->close();
            }
        }
    }
}

void DashboardFrame::openPanelConfigurationDialog(DataPanel* pPanel)
{
    if(m_pPanelConfigurationDialog == nullptr)
    {
        m_pPanelConfigurationDialog = new dpConfigurationDialog(this);
        connect(m_pPanelConfigurationDialog, SIGNAL(sgl_hide()), this, SLOT(onSignal_subDialogClose()));
    }

    m_pPanelConfigurationDialog->setPanel(pPanel);
    showTransparentMask();
    int nX = (ui->navigationPanel->width() - m_pPanelConfigurationDialog->width()) * 0.5;
    int nY = ui->navigationPanel->y() + ui->navigationPanel->height() * 0.5;
    m_pPanelConfigurationDialog->move(nX, nY);
    m_pPanelConfigurationDialog->show();
    m_pPanelConfigurationDialog->raise();
}

void DashboardFrame::onSignal_showMask()
{
    showTransparentMask();
}
void DashboardFrame::onSignal_hideMask()
{
    hideTransparentMask();
}

void DashboardFrame::onBtnClicked_addDashboard()
{
    if(m_pDashboardNamingDialog == nullptr)
    {
        m_pDashboardNamingDialog = new DashboardNamingDialog(this);
        m_pDashboardNamingDialog->installEventFilter(this);
        connect(m_pDashboardNamingDialog, SIGNAL(sgl_hide()), this, SLOT(onSignal_subDialogClose()));
        connect(m_pDashboardNamingDialog, &DashboardNamingDialog::dashboardName, this, &DashboardFrame::onSignal_dashboardNaming);
        //connect(m_pDashboardNamingDialog, SIGNAL(dashboardName(const QString&, const QString&)), this, SLOT(onSignal_dashboardNaming(const QString&, const QString&)));
    }

    showTransparentMask();
    int nX = (ui->navigationPanel->width() - m_pDashboardNamingDialog->width()) * 0.5;
    int nY = ui->navigationPanel->y() + ui->navigationPanel->height() * 0.5;
    m_pDashboardNamingDialog->move(nX, nY);
    m_pDashboardNamingDialog->showUsedForCreat();
    m_pDashboardNamingDialog->raise();
}

void DashboardFrame::onBtnClicked_addDataPanel()
{
    if(m_listDashboard.count() == 0)
    {
        showTransparentMask();
        showMessageDialog(type_warning, QString::fromWCharArray(L"错误"), QString::fromWCharArray(L"只能在数据看板内创建展项，请先创建一个数据看板"));
        return;
    }

    if(m_pPanelSelectionDialog == nullptr)
    {
        m_pPanelSelectionDialog = new PanelSelectionDialog(this);
        m_pPanelSelectionDialog->installEventFilter(this);
        connect(m_pPanelSelectionDialog, SIGNAL(sgl_hide()), this, SLOT(onSignal_subDialogClose()));
        connect(m_pPanelSelectionDialog, SIGNAL(panelType(DataPanelType)), this, SLOT(onSignal_panelSelectResult(DataPanelType)));
    }

    showTransparentMask();
    QPoint originPoint = ui->navigationPanel->mapToGlobal(QPoint(0, 0));
    int nX = originPoint.x() + (ui->navigationPanel->width() - m_pPanelSelectionDialog->width()) * 0.5;
    int nY = originPoint.y() + ui->navigationPanel->height() * 0.5;
    m_pPanelSelectionDialog->setGeometry(nX, nY, m_pPanelSelectionDialog->width(), m_pPanelSelectionDialog->height());
    m_pPanelSelectionDialog->show();
}

void DashboardFrame::onBtnClicked_dashboardList()
{
    if(m_listDashboard.count() ==0 )
        return;

    QMenu menu;
    menu.setStyleSheet("QMenu{\n"
                       "   background-color:rgb(36,43,50);\n"
                       "   border:1px solid rgb(6, 6, 6);\n"
                       "}\n"
                       "QMenu:scroller{\n"
                       "   show-arrows:true;\n"
                       "}\n"
                       "QMenu:item{\n"
                       "   padding-left:15px;\n"
                       "   padding-right:15px;\n"
                       "   font:9pt \"微软雅黑\";\n"
                       "   color:rgb(220,220,220);\n"
                       "   height:26px;\n"
                       "}\n"
                       "QMenu:item:selected{\n"
                       "   background-color: rgba(67,160,249, 80);\n"
                       "}\n");
    for(int n=0; n<m_listDashboard.count(); n++)
    {
        menu.addAction(m_listDashboard.at(n)->name(), this, SLOT(onMenuAction_dashboardList()));
    }

    QPoint originPoint = ui->btnDashboradList2->mapToGlobal(QPoint(0, 0));
    int nX = originPoint.x();
    originPoint = ui->navigationPanel->mapToGlobal(QPoint(0, 0));
    int nY = originPoint.y() + ui->navigationPanel->height();
    menu.exec(QPoint(nX, nY));
}

void DashboardFrame::onBtnClicked_dashboardTab()
{
    CustomTab* pBtn = qobject_cast<CustomTab*>(sender());
    QString strName = pBtn->text();
    setCurrentDashboard(strName);
}

void DashboardFrame::onBtnClicked_showRealtimeEvents()
{
    m_pAlarmEventMainDialog->setMode(Historical_Unconfirmed);
    int nWidth = this->width() * 0.8;
    int nHeight = this->height() * 0.8;
    int nX = this->geometry().x() + (this->width() - nWidth) * 0.5;
    int nY = this->geometry().y() + (this->height() - nHeight) * 0.5;
    showTransparentMask();
    m_pAlarmEventMainDialog->setGeometry(nX, nY, nWidth, nHeight);
    m_pAlarmEventMainDialog->show();
    m_pAlarmEventMainDialog->raise();
}

void DashboardFrame::onBtnClicked_showHistoricalEvents()
{
    m_pAlarmEventMainDialog->setMode(Historical_All);
    int nWidth = this->width() * 0.8;
    int nHeight = this->height() * 0.8;
    int nX = this->geometry().x() + (this->width() - nWidth) * 0.5;
    int nY = this->geometry().y() + (this->height() - nHeight) * 0.5;
    showTransparentMask();
    m_pAlarmEventMainDialog->setGeometry(nX, nY, nWidth, nHeight);
    m_pAlarmEventMainDialog->show();
    m_pAlarmEventMainDialog->raise();
}

void DashboardFrame::onMenuAction_dashboardList()
{
    QAction* action = qobject_cast<QAction*>(sender());
    QString strName = action->text();
    setCurrentDashboard(strName);
}

void DashboardFrame::onTimeout_realTime()
{
    QDateTime curDateTime = QDateTime::currentDateTime();
    m_pDateTimeWidget->setDateTime(curDateTime);
    m_pTimeLineWidget->setDateTime(curDateTime);
    if(m_curActiveDashboard)
        m_curActiveDashboard->setDateTime(curDateTime);
}

void DashboardFrame::onSignal_subDialogClose()
{
    hideTransparentMask();
}

void DashboardFrame::onSignal_dashboardNaming(const QString& strName, const QString& strUsedFor)
{
    for(int n=0; n<m_listDashboard.count(); n++)
    {
        if(m_listDashboard.at(n)->name() == strName)
        {
            QString strError = QString::fromStdWString(L"已存在同名看板");
            m_pDashboardNamingDialog->showErrorInfo(strError);
            return;
        }
    }

    if(strUsedFor == "create")
        addDashboard(strName);
    else if(strUsedFor == "rename" && m_curOperationDashboard)
        m_curOperationDashboard->setName(strName);
    m_pDashboardNamingDialog->hide();
    hideTransparentMask();
}

void DashboardFrame::onSignal_dashboardTabMoved(int nFromIndex, int nToIndex)
{
    //同步相应数据在其存储接结构中的位置
    Dashboard* movingDashboard = m_listDashboard.takeAt(nFromIndex);
    m_listDashboard.insert(nToIndex, movingDashboard);
}

void DashboardFrame::onSignal_removeDashboard()
{
    Dashboard* dashboard = qobject_cast<Dashboard*>(sender());
    if(dashboard)
    {
        showTransparentMask();
        QString strName = dashboard->name();
        QString strMsg = QString::fromStdWString(L"确认删除名为 \"") + strName + QString::fromStdWString(L"\" 的数据看板吗？");
        showMessageDialog(type_question, QString::fromStdWString(L"删除看板"), strMsg);
        if(g_msgDlgBtn == btn_No)
            return;

        removeDashboard(strName, true);
    }
}

void DashboardFrame::onSignal_renameDashboard()
{
    m_curOperationDashboard = qobject_cast<Dashboard*>(sender());

    if(m_pDashboardNamingDialog == nullptr)
    {
        m_pDashboardNamingDialog = new DashboardNamingDialog(this);
        connect(m_pDashboardNamingDialog, SIGNAL(dlgHide()), this, SLOT(onSignal_subDialogClose()));
        connect(m_pDashboardNamingDialog, &DashboardNamingDialog::dashboardName, this, &DashboardFrame::onSignal_dashboardNaming);
    }

    showTransparentMask();
    //QPoint originPoint = ui->navigationPanel->mapToGlobal(QPoint(0, 0));
    int nX = (ui->navigationPanel->width() - m_pDashboardNamingDialog->width()) * 0.5;
    int nY = ui->navigationPanel->y() + ui->navigationPanel->height() * 0.5;
    m_pDashboardNamingDialog->setGeometry(nX, nY, m_pDashboardNamingDialog->width(), m_pDashboardNamingDialog->height());
    m_pDashboardNamingDialog->showUsedForRename();
    m_pDashboardNamingDialog->raise();
}

void DashboardFrame::onSignal_panelSelectResult(DataPanelType type)
{
    //m_pPanelSelectionDialog->hide();
    hideTransparentMask();
    m_curActiveDashboard->addPanel(type);
}

void DashboardFrame::onSignal_timeRangeChanged(TimeUnit unit)
{
    QObject* pObject = QObject::sender();
    if(pObject->objectName() == "dateTimeWidget")
    {
        m_pTimeLineWidget->setTimeScaleUnit(unit);
    }
    else if(pObject->objectName() == "timeLineWidget")
    {
        m_pDateTimeWidget->setRange(unit);
    }

    if(m_curActiveDashboard)
        m_curActiveDashboard->setTimeRange(unit);
}

void DashboardFrame::onSignal_viewRealTimeData()
{
    if(!m_pTimer_RealTime->isActive())
        m_pTimer_RealTime->start(1000);

    m_pTimeLineWidget->setDisplayState(realTime);
}

void DashboardFrame::onSignal_viewHistoricalData(QDateTime dateTime)
{
    //qDebug() << "viewHistoricalData: " + dateTime.date().toString("yyyy/MM/dd");
    hideTransparentMask();

    if(m_pTimer_RealTime->isActive())
        m_pTimer_RealTime->stop();

    QObject* pObject = QObject::sender();
    if(pObject->objectName() == "dateTimeWidget")
    {
        m_pTimeLineWidget->setDateTime(dateTime);
        m_pTimeLineWidget->setDisplayState(historical);
    }
    else if(pObject->objectName() == "timeLineWidget")
    {
        m_pDateTimeWidget->setDateTime(dateTime);
        m_pDateTimeWidget->setState(historical);
    }
}

void DashboardFrame::onSignal_viewAllRealTimeEvents()
{
    onBtnClicked_showRealtimeEvents();
}

void DashboardFrame::onSignal_openAlarmEventCfgDialog()
{
    showTransparentMask();
    int nX = this->geometry().x() + (this->width() - m_pAlarmEventConfigDialog->width()) * 0.5;
    int nY = this->geometry().y() + (this->height() - m_pAlarmEventConfigDialog->height()) * 0.5;
    m_pAlarmEventConfigDialog->move(nX, nY);
    m_pAlarmEventConfigDialog->show();
    m_pAlarmEventConfigDialog->raise();
}
