#include "mainwidget.h"
#include "ui_mainwidget.h"
#include "cmessagebox.h"
#include <QRadioButton>
#include <QMessageBox>
#include <QFileDialog>
#include <QDesktopServices>

#include "generatefilethread.h"

#include <random>


MainWidget::MainWidget(QWidget *parent /*= 0*/, Skin *skin /*= NULL*/)
    : BaseClass(parent, skin)
{
    initUI();
    connects();
}

MainWidget::~MainWidget()
{
    delete ui;
}

void MainWidget::initUI()
{
    ui = new Ui::MainWidget();
    QWidget *c = this->setup_UI(ui);

    this->setWindowTitle("生成VTK场文件");
    this->set_child_bkg_alpha(128);

    ui->listWidgetPoint->setFlow(QListView::LeftToRight);
    ui->listWidgetPoint->setWrapping(true);
    ui->listWidgetPoint->setResizeMode(QListView::Adjust);

    ui->listWidgetLinearCell->setFlow(QListView::LeftToRight);
    ui->listWidgetLinearCell->setWrapping(true);
    ui->listWidgetLinearCell->setResizeMode(QListView::Adjust);

    ui->listWidgetNonlinearCell->setFlow(QListView::LeftToRight);
    ui->listWidgetNonlinearCell->setWrapping(true);
    ui->listWidgetNonlinearCell->setResizeMode(QListView::Adjust);

    for(int i = 0; i < 23; i++)
    {
        QListWidgetItem* item = new QListWidgetItem;
        item->setText(GlobalStatement::cellIndexToStr(GlobalStatement::CellIndex(i)));

        if(i == 0)
        {
            ui->listWidgetPoint->addItem(item);
        }
        else if(i > 0 && i <= 16)
        {
            ui->listWidgetLinearCell->addItem(item);
        }
        else
        {
            ui->listWidgetNonlinearCell->addItem(item);
        }
    }

    ui->progressBar->hide();
    ui->labelThreadTip->hide();

    ui->labelImage->setScaledContents(true);
    ui->labelImage->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored);

    ui->labelText->setWordWrap(true);

    ui->lineEditCellType->setEnabled(false);

    ui->splitter->setStretchFactor(0, 1);
    ui->splitter->setStretchFactor(1, 20);

    setConfigParam(Global::Instance()->configParam());

    mThread = new GenerateFileThread(this);

    mBgTimer.setInterval(3000);
    mBgTimer.start();
}

void MainWidget::connects()
{
    connect(ui->listWidgetPoint, &QListWidget::itemClicked, this, &MainWidget::clickedCellType);
    connect(ui->listWidgetLinearCell, &QListWidget::itemClicked, this, &MainWidget::clickedCellType);
    connect(ui->listWidgetNonlinearCell, &QListWidget::itemClicked, this, &MainWidget::clickedCellType);

    connect(ui->buttonStart, &QPushButton::clicked, this, &MainWidget::startGenerateVTKFile);
    connect(ui->buttonCancel, &QPushButton::clicked, this, &MainWidget::stopGenerate);
    connect(ui->buttonQuit, &QPushButton::clicked, this, &MainWidget::quitProgram);

    connect(ui->buttonSelect, &QPushButton::clicked, this, &MainWidget::selectOutputPath);
    connect(ui->buttonOpenDir, &QPushButton::clicked, this, &MainWidget::openOutputDir);

    connect(mThread, &GenerateFileThread::progressTip, this, &MainWidget::threadProgress);
    connect(mThread, &QThread::finished, this, [=](){
        ui->progressBar->hide();
        ui->labelThreadTip->hide();
        msgBox("提示", QString("VTK生成完成!\n生成了%1个单元").arg(mThread->getCellNum()));

        unfixedPanel();
    });
    connect(&mBgTimer, &QTimer::timeout, this, &MainWidget::changeBackground);
}

bool MainWidget::conditionalJudgment()
{
    ConfigParam p = configParam();
    if(p.outputFile.isEmpty())
    {
        msgBox("提示", "请输出保存文件路径");
        return false;
    }

    QFileInfo info(p.outputFile);
    if(!info.dir().exists())
    {
        msgBox("提示", "保存路径所在目录不存在,请更换其他目录");
        return false;
    }

    if(ui->lineEditCellType->text().isEmpty())
    {
        msgBox("提示", "请选择单元类型");
        return false;
    }

    if(p.cellNum == 0)
    {
        msgBox("提示", "请设置单元的数量");
        return false;
    }

    if(p.xLength <= 0 )
    {
        msgBox("提示", "场形状的长度不能小于或者等于0");
        return false;
    }

    if(p.yLength <= 0 )
    {
        msgBox("提示", "场形状的宽度不能小于或者等于0");
        return false;
    }

    if(p.zLength <= 0 )
    {
        msgBox("提示", "场形状的高度不能小于或者等于0");
        return false;
    }

    if(ui->lineEditCellType->text().isEmpty())
    {
        msgBox("提示", "请选择一个单元类型");
        return false;
    }

    QStringList _listIndex = p.cellIndexs.split(" ");
    QStringList listIndex;
    for(auto i : _listIndex)
    {
        if(!i.isEmpty())
            listIndex.append(i);
    }

    if(ui->checkBoxGroupCell->isChecked())
    {
        for(auto i : listIndex)
        {
            QString str = GlobalStatement::cellIndexToExplain(GlobalStatement::CellIndex(i.toInt()));
            QString cellName = GlobalStatement::cellIndexToStr(GlobalStatement::CellIndex(i.toInt()));

            if(str.contains("(未完成)"))
            {
                msgBox("提示", QString("\"%1\"此形状的场，相关功能还未完成，敬请期待！").arg(cellName));
                return false;
            }
        }
    }
    else
    {
        if(listIndex.size() != 1)
        {
            msgBox("提示", "请不要选择多个单元类型");
            return false;
        }
        else
        {
            QString str = GlobalStatement::cellIndexToExplain(GlobalStatement::CellIndex(listIndex.at(0).toInt()));
            if(str.contains("(未完成)"))
            {
                msgBox("提示", "此形状的场，相关功能还未完成，敬请期待！");
                return false;
            }
        }
    }


    return true;
}

void MainWidget::msgBox(const QString &title, const QString &txt)
{
    // QMessageBox _msgBox;
    // _msgBox.setWindowTitle(title);
    // _msgBox.setText(txt);
    // _msgBox.exec();
    CMessageBox _msgBox;
    _msgBox.setWindowTitle(title);
    _msgBox.setText(txt);
    _msgBox.exec();
}

ConfigParam MainWidget::configParam()
{
    ConfigParam p;
    p.outputFile = ui->lineEditPath->text();

    QString cellNames = ui->lineEditCellType->text();
    if(cellNames.isEmpty())
    {
        p.cellIndexs = "0";
    }
    else
    {
        QString strIndex;
        QStringList listIndex = cellNames.simplified().split(" ");
        for(int i = 0; i < listIndex.size(); i++)
        {
            if(i == 0)
            {
                strIndex = QString::number(GlobalStatement::strToCellIndex(listIndex.at(i)));
            }
            else
            {
                strIndex += " " + QString::number(GlobalStatement::strToCellIndex(listIndex.at(i)));
            }
        }
        p.cellIndexs = strIndex;
    }

    p.cellNum = ui->lineEditCellNum->text().toInt();
    if(ui->buttonCuboid->isChecked())
        p.shape = 0;
    else if(ui->buttonSemisphere->isChecked())
        p.shape = 1;
    else
        p.shape = 2;

    p.xLength = ui->lineEditXLength->text().toInt();
    p.yLength = ui->lineEditYLength->text().toInt();
    p.zLength = ui->lineEditZLength->text().toInt();
    p.groupCell = ui->checkBoxGroupCell->isChecked();
    p.weiDu = ui->spinBoxWeiDu->value();
    return p;
}

void MainWidget::setConfigParam(ConfigParam p)
{
    ui->lineEditPath->setText(p.outputFile);
    ui->lineEditCellNum->setText(QString::number(p.cellNum));

    if(!p.cellIndexs.isEmpty())
    {
        QStringList listIndex = p.cellIndexs.simplified().split(" ");
        QString cellNames;
        for(int i = 0; i < listIndex.size(); i++)
        {
            if(i == 0)
                cellNames = GlobalStatement::cellIndexToStr(GlobalStatement::CellIndex(listIndex.at(i).toInt()));
            else
                cellNames += " " + GlobalStatement::cellIndexToStr(GlobalStatement::CellIndex(listIndex.at(i).toInt()));
        }
        ui->lineEditCellType->setText(cellNames);
    }
    else
    {
        ui->lineEditCellType->clear();
    }


    if(p.shape == 0)
        ui->buttonCuboid->setChecked(true);
    else if(p.shape == 1)
        ui->buttonSemisphere->setChecked(true);
    else
        ui->buttonSphere->setChecked(true);
    ui->lineEditXLength->setText(QString::number(p.xLength));
    ui->lineEditYLength->setText(QString::number(p.yLength));
    ui->lineEditZLength->setText(QString::number(p.zLength));
    ui->checkBoxGroupCell->setChecked(p.groupCell);
    ui->spinBoxWeiDu->setValue(p.weiDu);
}

void MainWidget::fixedPanel()
{
    ui->groupBox->setEnabled(false);
    ui->lineEditPath->setEnabled(false);
    ui->buttonSelect->setEnabled(false);
    ui->buttonCuboid->setEnabled(false);
    ui->buttonSemisphere->setEnabled(false);
    ui->buttonSphere->setEnabled(false);
    ui->lineEditCellNum->setEnabled(false);
    ui->checkBoxGroupCell->setEnabled(false);
}

void MainWidget::unfixedPanel()
{
    ui->groupBox->setEnabled(true);
    ui->lineEditPath->setEnabled(true);
    ui->buttonSelect->setEnabled(true);
    ui->buttonCuboid->setEnabled(true);
    ui->buttonSemisphere->setEnabled(true);
    ui->buttonSphere->setEnabled(true);
    ui->lineEditCellNum->setEnabled(true);
    ui->checkBoxGroupCell->setEnabled(true);
}

void MainWidget::clickedCellType(QListWidgetItem *item)
{
    int idx = GlobalStatement::strToCellIndex(item->text());
    QString imagePath = QString(":/images/cellidx/%1.png").arg(idx);
    ui->labelImage->setPixmap(QPixmap(imagePath));

    ui->labelText->setText(GlobalStatement::cellIndexToExplain(GlobalStatement::CellIndex(idx)));

    if(ui->checkBoxGroupCell->isChecked())
    {
        QString str1 = ui->lineEditCellType->text();
        QString str2;
        if(str1.isEmpty())
        {
            str2 = item->text();
        }
        else
        {
            QStringList strList = str1.split(" ");
            QList<int> existInt;
            for(int i = 0; i < strList.size(); i++)
            {
                if(strList.at(i) == item->text())
                {
                    existInt.append(i);
                }
            }

            if(existInt.size())
            {
                while (existInt.size())
                {
                    int _idx = existInt.last();
                    existInt.removeLast();
                    strList.removeAt(_idx);
                }

                for(int i = 0; i < strList.size(); i++)
                {
                    str2 += " " + strList.at(i);
                }
            }
            else
            {
                str2 = str1 + " " + item->text();
            }
        }
        ui->lineEditCellType->setText(str2.simplified());
    }
    else
    {
        ui->lineEditCellType->setText(item->text());
    }

}

void MainWidget::startGenerateVTKFile()
{
    if(mThread->isRunning())
    {
        msgBox("提示", "正在生成场文件");
        return;
    }

    if(!conditionalJudgment())
        return;

    ConfigParam p = configParam();

    Global::Instance()->setConfigParam(p);

    fixedPanel();

    mThread->setConfigParam(p);
    mThread->start();
}

void MainWidget::stopGenerate()
{
    if(mThread->isRunning())
    {
        mThread->wait();
        mThread->terminate();
    }

    unfixedPanel();
}

void MainWidget::quitProgram()
{
    stopGenerate();
    this->close();
}

void MainWidget::selectOutputPath()
{
    QString lastPath = ui->lineEditPath->text();
    if(lastPath.isEmpty())
        lastPath = Global::Instance()->rootDirPath();
    else
    {
        QFileInfo info(lastPath);
        lastPath = info.dir().path();
    }
    QString fileName = QFileDialog::getSaveFileName(this,
                                                    "保存VTK文件", lastPath, "VTK文件 (*.vtk)");
    if(fileName.isEmpty())
        return;

    ui->lineEditPath->setText(fileName);
}

void MainWidget::openOutputDir()
{
    QString lastPath = ui->lineEditPath->text();
    if(lastPath.isEmpty())
        lastPath = Global::Instance()->rootDirPath();
    else
    {
        QFileInfo info(lastPath);
        lastPath = info.dir().path();
    }
    QDesktopServices::openUrl(QUrl::fromLocalFile(lastPath));
}

void MainWidget::threadProgress(int val, int sum, const QString &tip)
{
    ui->labelThreadTip->setText(tip);
    ui->progressBar->setRange(0, sum);
    ui->progressBar->setValue(val);
    if(val == 1)
    {
        ui->progressBar->show();
        ui->labelThreadTip->show();
    }
}

void MainWidget::changeBackground()
{
    std::random_device rd;  // 随机数引擎的种子源
    std::mt19937 gen(rd()); // 以 rd() 播种的 mersenne_twister_engine
    std::uniform_int_distribution<> distrib(1, 10);

    int idx = distrib(gen);
    QString styleStr = QString("*{color:%1; background:transparent; font-size:16px; font-family:\"Microsoft Yahei\";}");
    if(idx == 1)
    {
        styleStr = styleStr.arg("#CE20C9");
    }
    else if(idx == 2)
    {
        styleStr = styleStr.arg("#EFF0F2");
    }
    else if(idx == 3)
    {
        styleStr = styleStr.arg("#33B71E");
    }
    else if(idx == 4)
    {
        styleStr = styleStr.arg("#13D3A8");
    }
    else if(idx == 5)
    {
        styleStr = styleStr.arg("#2B49EB");
    }
    else if(idx == 6)
    {
        styleStr = styleStr.arg("#E16415");
    }
    else if(idx == 7)
    {
        styleStr = styleStr.arg("#5273CD");
    }
    else if(idx == 8)
    {
        styleStr = styleStr.arg("#E14D15");
    }
    else if(idx == 9)
    {
        styleStr = styleStr.arg("#E19415");
    }
    else
    {
        styleStr = styleStr.arg("#9E2FDD");
    }
    this->setStyleSheet(styleStr);

    QString bgPath = QString(":/images/bg/bg%1.jpg").arg(idx);
    skin()->set_client_pixmap(bgPath);
    redraw_background();
}



void MainWidget::btn_open_bg_image_clicked()
{
    QString filename = QFileDialog::getOpenFileName(
        this,
        "choose an image",
        "", // QDir::currentPath(),
        "Image files (*.bmp; *.png; *.jpg;);;All files(*.*)");

    if (!filename.isNull())
    {
        // load client image
        skin()->set_client_pixmap(filename);
        // skinman->get("sub_main")->set_client_pixmap(filename);

        // QRect rect = skin()->client_pixmap().rect();
        // QRect fix_size(0, 0, 400, 600);
        // if (rect.width() > fix_size.width() || rect.height() > fix_size.height())
        // {
        //     rect = fix_size;
        // }
        // this->resize(rect.size());
        this->redraw_background();
    }
}



