#include "mainwindow.h"
#include "./ui_mainwindow.h"
#include "savepathwidget.h"

#include <QHBoxLayout>
#include <QFileDialog>
#include <QMessageBox>
#include <QTextCodec>
#include <QMenu>
#include <QAction>
#include <QDragEnterEvent>
#include <QDropEvent>
#include <QMimeData>
#include <QDir>
#include <QFileInfo>
#include <QDebug>

#include "treeitem.h"
#include "treemodel.h"


MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    initUI();
    connects();
}

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

void MainWindow::dragEnterEvent(QDragEnterEvent *e)
{
    e->acceptProposedAction();
}

void MainWindow::dropEvent(QDropEvent *e)
{
    QList<QUrl> urls = e->mimeData()->urls();
    if(urls.isEmpty())
        return ;
    // qDebug() << urls.size();
    foreach (QUrl u, urls)
    {
        QString filepath = u.toLocalFile();
        QFileInfo fileInfo(filepath);
        if(fileInfo.isFile())
        {
            QString completeSuffix = fileInfo.completeSuffix();
            if(completeSuffix.compare("vis") == 0)
            {
                loadVisFile(fileInfo.absoluteFilePath());
            }
            else
            {
                QMessageBox msgBox;
                msgBox.setWindowTitle("提示");
                msgBox.setText("目前仅支持vis模型文件");
                msgBox.exec();
            }
            return;
        }
    }
}

void MainWindow::initUI()
{
    this->setWindowTitle("ReadVis");
    this->setAcceptDrops(true);

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

    const QStringList headers({ "节点" });
    mTreeModel = new TreeModel(headers, "");
    ui->treeViewNode->setModel(mTreeModel);    
    ui->treeViewNode->setContextMenuPolicy(Qt::CustomContextMenu);
    ui->treeViewNode->hide();
    rootItem = mTreeModel->getRootItem();

    mParam = Global::Instance()->param();

    mMenu = new QMenu(ui->treeViewNode);
    mPosAction = new QAction("定位");
    mConvertFbxAction = new QAction("转换成fbx");
    mMenu->addAction(mPosAction);
    mMenu->addAction(mConvertFbxAction);

    mSaveWidget = new SavePathWidget;
    mSaveWidget->setWindowTitle("转为fbx");
    mSaveWidget->setFbxFilePath(mParam.convertFbxPath);
}

void MainWindow::connects()
{
    connect(ui->actionAddBall, &QAction::triggered, this, &MainWindow::addBall);
    connect(ui->actionAddVis, &QAction::triggered, this, &MainWindow::openVisFile);
    connect(ui->actionQuit, &QAction::triggered, this, &MainWindow::quitProgram);

    connect(ui->actionTreeShow, &QAction::triggered, this, &MainWindow::showHideNodeTree);

    // 测试用，检测鼠标点击的节点是否正确
//    connect(ui->treeViewNode, &QTreeView::clicked, this, [=](const QModelIndex &index){
//        TreeItem* item = mTreeModel->getItem(index);
//        VsDatabase* db = fieldPathToDatabase(item->fieldPath());
//        debugVsDatabase(db);
//    });

    connect(ui->treeViewNode, &QTreeView::customContextMenuRequested, this, &MainWindow::showMenu);
    connect(mMenu, &QMenu::triggered, this, &MainWindow::slotActionTriggered);
}

void MainWindow::addBall()
{
    // 设置相机
    float eye[] = {0, 20, -20};
    float tar[] = {0, 0, 0};
    float up[] = {0, 1, 0};
    VsSetCamera(eye, tar, up);
    VsSetNearFar(0.1f, 10000.f, NULL);

    // 地面
    VsOpenField("/scene/model/plane");
    VsSetMaterialDiffuse(0, 0.8, 0);
    VsInsertRect(0, 0, 0,
                 0, 0.1, 0,
                 10, 10);
    VsCloseField();

    // 基本几何体
    VsOpenField("/scene/model/ball");
    VsSetMaterialDiffuse(1, 0, 0);
    VsInsertSphere(0, 1, 0, 1);
    VsInsertSphere(-5, 1, 0, 1);
    VsInsertSphere(5, 1, 0, 1);
    VsCloseField();

    VsInvalidate();
}

void MainWindow::openVisFile()
{
    QFileInfo info(mParam.inputVisPath);
    QString lastDirPath;
    if(info.dir().exists())
    {
        lastDirPath = info.dir().path();
    }
    else
    {
        lastDirPath = Global::Instance()->rootDirPath();
    }
    QString fileName = QFileDialog::getOpenFileName(this,
                                                    "打开模型", lastDirPath,
                                                        "VIS文件 (*.vis)");    
    if(fileName.isEmpty())
        return;

    try
    {
        loadVisFile(fileName);
    }
    catch (...)
    {
        QMessageBox msgBox;
        msgBox.setWindowTitle("致命");
        msgBox.setText("哦，糟糕，平台的API出现异常，我也解决不了!");
        msgBox.exec();
    }


}

void MainWindow::quitProgram()
{
    //this->close();
    qApp->quit();
}

void MainWindow::showHideNodeTree()
{    
    ui->treeViewNode->setVisible(!ui->treeViewNode->isVisible());
}

void MainWindow::slotActionTriggered(QAction *action)
{
    if(action == mConvertFbxAction)
    {
        mSaveWidget->raise();
        mSaveWidget->activateWindow();
        mSaveWidget->show();
    }
}

void MainWindow::showMenu(const QPoint &point)
{
    TreeItem* item = mTreeModel->getItem(ui->treeViewNode->currentIndex());
    if(item->fieldPath().contains("model"))
    {
        mSaveWidget->setFieldPath(item->fieldPath());
        QPoint pos = QCursor::pos();
        //    QPoint parentPos = ui->treeViewNode->pos();
        //    QPoint pos = mapToGlobal(parentPos);
        //    pos += point;
        //    pos.setY(pos.y() + mMenu->height());
        mMenu->move(pos);
        mMenu->show();
    }
}

void MainWindow::debugInfo(VsDatabase* node)
{
    VS_KEY key1 = node->key;

    char szFieldPath[4095]; // 节点路径
    VsShowFieldPathName(key1, szFieldPath);
    char name[255]; // 节点名称
    VsShowFieldName(key1, name);

    qDebug() << "key:" << key1 << ", name:" << name << ", path:" << szFieldPath;

    // 处理子节点
    VsDatabase* pChild = node->childList;
    while (pChild)
    {
        debugInfo(pChild);
        pChild = pChild->next;
    }
}

void MainWindow::loadVisFile(const QString &fileName)
{
    mParam.inputVisPath = fileName;
    Global::Instance()->setInputVisPath(fileName);

    VsOpenField("/");
    VtkReadStreamFile(fileName.toLocal8Bit().toStdString().c_str(),
                      MvoGetUserData,
                      (DWORD_PTR)mView,
                      NULL);
    VsCloseField();

    //VsRebuildInclude("/");

    const char* fieldPath = "/";
    VS_KEY key = VsFieldExists(fieldPath);
    if (key == VS_INVALID_KEY)
    {
        qDebug() << "VS_INVALID_KEY";
        return;
    }

    VsDatabase* pVsDb = nullptr;
    VsShowDatabaseByKey(key, pVsDb);
    //debugInfo(pVsDb);

    rootItem->clear();

    peNodeRecurse(pVsDb, rootItem);
    mTreeModel->updateData();

    if(!ui->treeViewNode->isVisible())
        ui->treeViewNode->setVisible(true);
}


void MainWindow::peNodeRecurse(VsDatabase* node, TreeItem* parentItem)
{
    VS_KEY key1 = node->key;
    char szFieldPath[4095]; // 节点路径
    VsShowFieldPathName(key1, szFieldPath);
    char name[255]; // 节点名称
    VsShowFieldName(key1, name);
    //qDebug() << "key:" << key1 << ", path:" << szFieldPath;

    QTextCodec *pTextCodec = QTextCodec::codecForName("System");
    assert(pTextCodec != nullptr);
    QString _name = pTextCodec->toUnicode(name);
    QString _path = pTextCodec->toUnicode(szFieldPath);

    QString parentFieldPath;
    QVector<QVariant> columnData;
    columnData << _name;
    TreeItem* item = new TreeItem(columnData, parentItem);
    item->setFieldPath(_path);
    VsDatabase* pChild = node->childList;
    while (pChild)
    {
        peNodeRecurse(pChild, item);
        pChild = pChild->next;
    }
}
