#include "dataPanel.h"
#include "ui_panelToolWidget.h"

#include "panelConfigurationWidget.h"
#include "customBorderContainer.h"
#include "customMenu.h"
#include "dataManager.h"
#include "dataPanel/dpLineChart.h"
#include "dataPanel/dpBarsChart.h"

#include <QKeyEvent>
#include <QBoxLayout>
#include <QScrollArea>
#include <QPainter>

PanelToolWidget::PanelToolWidget(QWidget* parent)
    :QWidget(parent)
    , ui(new Ui::panelToolWidget)
{
    ui->setupUi(this);
    setWindowFlags(Qt::FramelessWindowHint | Qt::SubWindow);

    ui->btnFullScree->setProperty("currentState", "enterFullScreen");
}
PanelToolWidget::~PanelToolWidget()
{
    delete ui;
}


DataPanel::DataPanel(QWidget *parent, DataPanelType type)
    : QDialog(parent)
    ,m_type(type)
{
    setWindowFlags(Qt::FramelessWindowHint | Qt::SubWindow);
    //setAttribute(Qt::WA_StaticContents, false); // 禁用静态内容优化
    //setAttribute(Qt::WA_PaintOnScreen, false); // 默认使用双缓冲

    m_strName = "";
    m_bMouseEnter = false;
    m_bConfigurationComplete = false;
    m_pContentWidget = nullptr;
    m_pScrollArea = nullptr;

    /*setStyleSheet("QDialog{\n"
                  "   border:2px solid rgb(76,88,105);\n"
                  "   background-color:rgba(24,32,38,250);\n"
                  "}\n");*/

    QWidget* centralWidget = new QWidget(this);
    centralWidget->setObjectName("centralWidget");
    /*centralWidget->setStyleSheet("QWidget #centralWidget{\n"
                                 "   border:2px solid rgb(76,88,105);\n"
                                 "   background-color:rgba(24,32,38,250);\n"
                                 "}\n");*/
    QBoxLayout* centralLayout = new QBoxLayout(QBoxLayout::TopToBottom, this);
    centralLayout->setContentsMargins(0, 0, 0, 0);
    centralLayout->addWidget(centralWidget);
    setLayout(centralLayout);
    m_pLayout = new QBoxLayout(QBoxLayout::TopToBottom, centralWidget);
    m_pLayout->setContentsMargins(10, 5, 10, 10);
    m_pLayout->setSpacing(0);
    centralWidget->setLayout(m_pLayout);

    m_pConfigurationWidget = new PanelConfigurationWidget(this);
    connect(m_pConfigurationWidget, SIGNAL(sgl_configure()), this, SLOT(onSignal_configure()));
    m_pConfigurationWidget->raise();
    //setWiget(m_pConfigurationWidget);
    //resize(533, 300);

    m_pCustomBorderContainer = new CustomBorderContainer(this);
    m_pCustomBorderContainer->setOperationOption(CustomBorderContainer::WidgetMovable | CustomBorderContainer::WidgetResizable | CustomBorderContainer::WidgetAutoAdjustGeometry);

    m_pToolWidget = new PanelToolWidget(this);
    connect(m_pToolWidget->ui->btnSetting, SIGNAL(clicked()), this, SLOT(onToolBtnClicked_setting()));
    connect(m_pToolWidget->ui->btnFullScree, SIGNAL(clicked()), this, SLOT(onToolBtnClicked_fullScreen()));
    connect(m_pToolWidget->ui->btnMenu, SIGNAL(clicked()), this, SLOT(onToolBtnClicked_menu()));
    m_pToolWidget->raise();
    m_pToolWidget->hide();

    m_pToolMenu = new CustomMenu(this);
    connect(m_pToolMenu, SIGNAL(aboutToHide()), this, SLOT(onAboutToHide_toolMenu()));
    m_pToolMenu->addAction(QString::fromWCharArray(L"移除面板"), this, SLOT(onAction_remove()));
    //m_pToolMenu->addAction(QString::fromWCharArray(L"放置最前"), this, SLOT(onAction_moveToFront()));
    m_pToolMenu->addAction(QString::fromWCharArray(L"放置最后"), this, SLOT(onAction_moveToBack()));

    createDataWidget();
    m_cofigurationResults.setModelParent(this);

    connect(DataManager::instance(), &DataManager::dataUpdated, this, &DataPanel::onSignal_dataUpdated);
}

DataPanel::~DataPanel()
{
    // if(m_pToolMenu)
    // {
    //     delete m_pToolMenu;
    //     m_pToolMenu = nullptr;
    // }
    this->disconnect(); //不写也可以，QT本身其实回自动断开所有关联连接
}

bool DataPanel::event(QEvent* event)
{
    if(event->type() == QEvent::KeyPress)
    {
        QKeyEvent* pKeyEvent = static_cast<QKeyEvent*>(event);
        if (pKeyEvent->key() == Qt::Key_Escape)
            return true;
    }
    else if(event->type() == QEvent::Show)
    {
        //m_pToolWidget->move(this->width() - m_pToolWidget->width() - 8, 3);
        m_pConfigurationWidget->move((this->width() - m_pConfigurationWidget->width()) * 0.5, (this->height() - m_pConfigurationWidget->height()) * 0.5);
    }
    else if(event->type() == QEvent::Resize || event->type() == QEvent::Move)
    {
        if(m_pToolWidget->isVisible())
            m_pToolWidget->move(this->width() - m_pToolWidget->width() - 8, 3);
        if(m_pConfigurationWidget->isVisible())
            m_pConfigurationWidget->move((this->width() - m_pConfigurationWidget->width()) * 0.5, (this->height() - m_pConfigurationWidget->height()) * 0.5);
    }
    else if(event->type() == QEvent::MouseButtonPress)
    {
        raise();
    }
    else if(event->type() == QEvent::Enter)
    {
        //qDebug() << "Enter";
        m_pToolWidget->move(this->width() - m_pToolWidget->width() - 8, 3);
        m_pToolWidget->show();
        QString strCurState = m_pToolWidget->ui->btnFullScree->property("currentState").toString();
        if(strCurState == "enterFullScreen")
            m_pCustomBorderContainer->showBorderDraw();
    }
    else if(event->type() == QEvent::Leave)
    {
        //qDebug() << "Leave";
        if(!m_pToolMenu->isVisible())
        {
            m_pToolWidget->hide();
            m_pCustomBorderContainer->hideBorderDraw();
        }
    }
    else if(event->type() == QEvent::Paint)
    {
        QPainter painter(this);
        painter.setRenderHint(QPainter::Antialiasing);
        // 绘制背景
        painter.fillRect(rect(), QColor(24, 32, 38, 250)); // 原样式表背景色
        // 绘制边框
        QPen pen(QColor(76, 88, 105), 2); // 原样式表边框颜色和宽度
        painter.setPen(pen);
        painter.drawRect(rect().adjusted(1, 1, -1, -1));
    }

    return QDialog::event(event);
}

/*void DataPanel::paintEvent(QPaintEvent* event)
{
    QPainter painter(this);
    painter.setRenderHint(QPainter::Antialiasing);
    // 绘制背景
    painter.fillRect(rect(), QColor(24, 32, 38, 250)); // 原样式表背景色
    // 绘制边框
    QPen pen(QColor(76, 88, 105), 2); // 原样式表边框颜色和宽度
    painter.setPen(pen);
    painter.drawRect(rect().adjusted(1, 1, -1, -1));

    // 双缓冲绘制
    QPainter painter(this);
    QPixmap buffer(size());
    buffer.fill(Qt::transparent);

    QPainter bufferPainter(&buffer);
    bufferPainter.setRenderHint(QPainter::Antialiasing);

    // 绘制带边框的背景
    bufferPainter.setPen(QPen(QColor(76,88,105),2));
    bufferPainter.setBrush(QColor(24,32,38,250));
    bufferPainter.drawRoundedRect(rect().adjusted(1, 1, -1, -1), 0, 0);

    painter.drawPixmap(0, 0, buffer);
}

void DataPanel::keyPressEvent(QKeyEvent* e)
{
    if(e->key() == Qt::Key_Escape)
        return;
    else
        return QDialog::keyPressEvent(e);
}

void DataPanel::mousePressEvent(QMouseEvent* e)
{
    Q_UNUSED(e);
    raise(); //设置为SubWindow后，需要手动置顶
}

void DataPanel::enterEvent(QEnterEvent* e)
{
    Q_UNUSED(e);
    m_pToolWidget->show();
    QString strCurState = m_pToolWidget->ui->btnFullScree->property("currentState").toString();
    if(strCurState == "enterFullScreen")
        m_pCustomBorderContainer->showBorderDraw();
}

void DataPanel::leaveEvent(QEvent* e)
{
    Q_UNUSED(e);
    if(!m_pToolMenu->mouseIsInside()) //打开menu后鼠标会离开进入menu
    {
        m_pToolWidget->hide();
        if(m_pToolMenu->isVisible())
            m_pToolMenu->hide();
        m_pCustomBorderContainer->hideBorderDraw();
    }
}

void DataPanel::resizeEvent(QResizeEvent* e)
{
    m_pToolWidget->move(this->width() - m_pToolWidget->width() - 8, 3);
}*/

void DataPanel::setupScrollArea()
{
    if(m_pScrollArea == nullptr)
    {
        m_pScrollArea = new QScrollArea(this);
        m_pScrollArea->setWidgetResizable(true);
        m_pLayout->addWidget(m_pScrollArea);
    }
}

void DataPanel::autoSetGeometry()
{

}

void DataPanel::createDataWidget()
{
    switch(m_type)
    {
    case lineChart:
    {
        dpLineChart* lineChart = new dpLineChart(this);
        setWidget(lineChart);
        break;
    }
    case barChart:
    {
        dpBarsChart* barsChart = new dpBarsChart(this);
        setWidget(barsChart);
        break;
    }
    default:
        break;
    }
}

void DataPanel::setWidget(QWidget* pWidget, eInsertMode InsertMode)
{
    if(m_pContentWidget)
    {
        QWidget* w = takeWidget();
        if(w)
            delete w;
    }

    QScrollArea* scrollAreaWiget = qobject_cast<QScrollArea*>(pWidget);
    if(scrollAreaWiget || InsertMode == ForceNoScrollArea)
    {
        m_pLayout->addWidget(pWidget);
    }
    else
    {
        setupScrollArea();
        m_pScrollArea->setWidget(pWidget);
    }

    m_pContentWidget = pWidget;
}

QWidget* DataPanel::takeWidget()
{
    QWidget* w = nullptr;
    if(m_pScrollArea)
    {
        m_pLayout->removeWidget(m_pScrollArea);
        w = m_pScrollArea->takeWidget();
        delete m_pScrollArea;
        m_pScrollArea = nullptr;
        m_pContentWidget = nullptr;
    }
    else if(m_pContentWidget)
    {
        m_pLayout->removeWidget(m_pContentWidget);
        w = m_pContentWidget;
        m_pContentWidget = nullptr;
    }

    if(w)
        w->setParent(nullptr);

    return w;
}

void DataPanel::setName(const QString& strName)
{
    m_strName = strName;
}
const QString& DataPanel::getName()
{
    return m_strName;
}

DataPanelType DataPanel::getType()
{
    return m_type;
}

void DataPanel::setInitialSize(const QSize& size)
{
    resize(size);
    m_pCustomBorderContainer->updateBorder();
}

void DataPanel::setDisplayAreaSize(const QSize& size)
{
    m_displayAreaSize = size;
}

void DataPanel::resizeByRatio(double ratioX, double ratioY)
{
    QString strCurState = m_pToolWidget->ui->btnFullScree->property("currentState").toString();
    if(strCurState == "exitFullScreen") //当前是全屏状态
        setGeometry(0, 0, parentWidget()->width(), parentWidget()->height());
    else
    {
        QRect geometry = this->geometry();
        QRect newGeometry;
        //double转换为int默认只取整数部分，因此ratio若<1，执行默认操作，反之向上取整
        if(ratioX < 1)
        {
            newGeometry.setX(geometry.x() * ratioX);
            newGeometry.setWidth(geometry.width() * ratioX);
        }
        else
        {
            newGeometry.setX(qCeil(geometry.x() * ratioX));
            newGeometry.setWidth(qCeil(geometry.width() * ratioX));
        }
        if(ratioY < 1)
        {
            newGeometry.setY(geometry.y() * ratioY);
            newGeometry.setHeight(geometry.height() * ratioY);
        }
        else
        {
            newGeometry.setY(qCeil(geometry.y() * ratioY));
            newGeometry.setHeight(qCeil(geometry.height() * ratioY));
        }
        if(newGeometry.x() < 0)
            newGeometry.setX(0);
        if(newGeometry.y() < 0)
            newGeometry.setY(0);

        setGeometry(newGeometry);

        // qDebug() << geometry.x() << "," << geometry.y() << "," << geometry.width() << "," << geometry.height();
        // qDebug() << ratioX << "," << ratioY;
        // qDebug() << newGeometry.x() << "," << newGeometry.y() << "," << newGeometry.width() << "," << newGeometry.height();
    }

    m_curGeometry = QRect(m_curGeometry.x() * ratioX, m_curGeometry.y() * ratioY, m_curGeometry.width() * ratioX, m_curGeometry.height() * ratioY);
    m_pCustomBorderContainer->updateBorder();
}
void DataPanel::resizeByNewSize(const QSize& newSize)
{
    if(m_displayAreaSize == newSize)
        return;

    double ratioX = (double)newSize.width() / (double)m_displayAreaSize.width();
    double ratioY = (double)newSize.height() / (double)m_displayAreaSize.height();
    resizeByRatio(ratioX, ratioY);
}

void DataPanel::setDateTime(const QDateTime& dateTime)
{
    dpBaseWidget* baseWidget = qobject_cast<dpBaseWidget*>(m_pContentWidget);
    if(baseWidget)
        baseWidget->setDateTime(dateTime);

    //请求数据
    //DataManager::instance()->requestData("dataType", this);
}

void DataPanel::setTimeRange(TimeUnit unit)
{
    dpBaseWidget* baseWidget = qobject_cast<dpBaseWidget*>(m_pContentWidget);
    if(baseWidget)
        baseWidget->setTimeRange(unit);
}

void DataPanel::configurationComplete()
{
    if(m_pConfigurationWidget->isVisible())
        m_pConfigurationWidget->hide();

    dpBaseWidget* baseWidget = qobject_cast<dpBaseWidget*>(m_pContentWidget);
    if(baseWidget)
        baseWidget->synchronizeConfigData(m_cofigurationResults);
}

void DataPanel::onToolBtnClicked_setting()
{
    emit sgl_openCofigurationDialog(this);
}

void DataPanel::onToolBtnClicked_fullScreen()
{
    QString strCurState = m_pToolWidget->ui->btnFullScree->property("currentState").toString();
    if(strCurState == "enterFullScreen")
    {
        m_pToolWidget->ui->btnFullScree->setProperty("currentState", "exitFullScreen");
        m_pToolWidget->ui->btnFullScree->setStyleSheet("QPushButton{\n"
                                                       "   padding:3px;\n"
                                                       "   image: url(:/images/icon_exitfullscreen.png);\n"
                                                       "}\n"
                                                       "QPushButton:hover{\n"
                                                       "   padding:2px;\n"
                                                       "}\n"
                                                       "QPushButton:pressed{\n"
                                                       "   padding:3px;\n"
                                                       "}\n");
        m_pCustomBorderContainer->setOperationOption(CustomBorderContainer::WidgetNoOperation);
        m_pCustomBorderContainer->hideBorderDraw();
        m_curGeometry = geometry();
        setGeometry(0, 0, parentWidget()->width(), parentWidget()->height());
    }
    else if(strCurState == "exitFullScreen")
    {
        m_pToolWidget->ui->btnFullScree->setProperty("currentState", "enterFullScreen");
        m_pToolWidget->ui->btnFullScree->setStyleSheet("QPushButton{\n"
                                                       "   padding:3px;\n"
                                                       "   image: url(:/images/icon_fullscreen.png);\n"
                                                       "}\n"
                                                       "QPushButton:hover{\n"
                                                       "   padding:2px;\n"
                                                       "}\n"
                                                       "QPushButton:pressed{\n"
                                                       "   padding:3px;\n"
                                                       "}\n");
        m_pCustomBorderContainer->setOperationOption(CustomBorderContainer::WidgetMovable | CustomBorderContainer::WidgetResizable | CustomBorderContainer::WidgetAutoAdjustGeometry);
        m_pCustomBorderContainer->showBorderDraw();
        setGeometry(m_curGeometry);
        m_pCustomBorderContainer->updateBorder();
    }
}

void DataPanel::onToolBtnClicked_menu()
{
    QPoint originPoint = m_pToolWidget->mapToGlobal(QPoint(0, 0));
    int nX = originPoint.x() - (m_pToolMenu->width() - m_pToolWidget->width());
    int nY = originPoint.y() + m_pToolWidget->height() + 2;
    // m_pToolMenu->move(nX,nY);
    // m_pToolMenu->show();
    m_pToolMenu->popup(QPoint(nX, nY));
}

void DataPanel::onAction_remove()
{
    emit sgl_remove(m_strName);
}
void DataPanel::onAction_moveToFront()
{
    this->raise();
}
void DataPanel::onAction_moveToBack()
{
    this->lower();
}

void DataPanel::onAboutToHide_toolMenu()
{
    m_pToolWidget->hide();
    m_pCustomBorderContainer->hideBorderDraw();
}

void DataPanel::onSignal_configure()
{
    emit sgl_openCofigurationDialog(this);
}

void DataPanel::onSignal_dataUpdated(const QString& dataKey, const QVariant& data)
{

}
