#include "global.h"

#include <QDir>
#include <QSettings>
#include <QFileInfo>
#include <QDebug>

//√表示完成
QStringList explains {
    /*0√*/"Point：点数据",
    /*1√*/"VTK_VERTEX：顶点，由一个点定义，是零维的基本类型。",
    /*2√*/"VTK_POLY_VERTEX：多顶点，多个顶点组合而成，是零维的组合单元，其定义不受顶点顺序的限制。",
    /*3√*/"VTK_LINE：直线，一维的基本类型，由两个点定义，方向是从第一个点指向第二个点。",
    /*4√*/"VTK_POLY_LINE：折线，由一个或多个线段组合而成，一维的类型。由 n+1个有序的点连接定义的，n 表示折线的线段条数，每两个点(i,+1)定义一条线段",
    /*5√*/"VTK_TRIANGLE：三角形，二维的基本类型，由三个点按逆时针的方向连接定义，点的连接方向和表面法向量符合右手法则，即右手大拇指外的手指沿着点的方向弯曲，大拇指所指向的方向就是表面法向量。",
    /*6*/"(未完成)\nVTK_TRIANGLE_STRIP：三角形条带，由一个或多个三角形组合而成，二维类型。由n+2 个有序的点连接定义的，n 表示三角形条带里三角形的个数，定义三角形条带的点不需要共面。定义每个三角形的顶点顺序为(i, 计1,计2)，0≤i≤n。",
    /*7*/"(未完成)\nVTK_POLYGON：多边形，二维的基本类型，是由共面的三个或三个以上的点按逆时针方向的顺序连接定义的。多边形表面法向量的方向通过右手法则确定。该类型要求多边形可以是非凸的，但是不能含有内部循环或者出现相交的边。多边形有n条边，n就是组成多边形的点的个数。",
    /*8*/"(未完成)\nVTK_PIXEL：二维的基本类型，是由共面的四个点按一定的顺序连接定义的。该类型的单元与四边形的区别在拓扑结构上，Pixel类型要求相邻的两条边必须垂直，而且相对的两条边要与坐标轴平行，因此 Pixel的表面法向量也与其中的一条坐标轴平行。定义Pixel的四个顶点的顺序与四边形的不同，如左图所示，Pixel顶点的计数是先沿着X轴的方向，然后是Y轴，最后是乙轴方向。Pixel是四边形类型的特殊形式，但要注意：这里的 Pixel 是一种单元类型，与图像像素(Pixel)的概念是不同的。Pixel 具体表达什么意思，需要根据上下文判断。",
    /*9√*/"VTK_QUAD：四边形，二维的基本类型，是由共面的四个点按逆时针的方向连接定义的。四边形要求是非自交的凸多边形。利用右手法则可以得到该四边形的表面法向量。",
    /*10*/"VTK_TETRA：四面体，三维的基本类型，是由不共面的四个点两两连接定义的。如左图所示，四面体有六条边和四个面。",
    /*11*/"(未完成)\nVTK_VOXEL：三维的基本类型，与六面体的拓扑一样，但几何上有所区别。Voxel要求相邻的两个面必须垂直，点的连接顺序如左图所示。Voxel 是六面体的特殊形式。与Pixel类似，Voxel与三维图像体素(Voxel)的概念是不同的。",
    /*12*/"VTK_HEXAHEDRON：六面体，三维的基本类型，包含六个四边形表面、12条边和8个顶点。其中8个顶点的连接顺序如左图所示，六面体要求必须是凸的。",
    /*13*/"VTK_WEDGE：楔形，三维的基本类型，由三个四边形面、两个三角形面、九条边和六个顶点构成。六个点的连接顺序如左图所示。要求面和边不能与其他的相交，且楔形必须是凸的。",
    /*14*/"VTK_PYRAMID：角椎体，三维的基本类型，由一个四边形面、四个三角形面、八条边和五个顶点构成。构成角椎体的点的连接顺序如左图所示。定义四边形的四个点要求是共面的，且四个点构成的四边形必须是凸的，第五个点与其他四个点不在一个面上。",
    /*15*/"VTK_PENTAGONAL_PRISM：五棱柱，三维的基本类型，由五个四边形面、两个五边形面、15 条边和10顶点构成。点的连接顺序如左图所示。五棱柱的面和边不能与其他的相交，且五棱柱必须是凸的。",
    /*16*/"VTK_HEXAGONAL_PRISM：六角柱，三维的基本类型，由六个四边形面、两个六边形面、18 条边和12个顶点构成。点的连接顺序如左图所示。六角柱的面和边不能与其他的相交，且六角柱必须是凸的。",
    /*17*/"(未完成)\nVTK_QUADRATIC_EDGE：二次曲线，一维的基本类型，由三个点定义，其中前两个点分别对应曲线的端点，第三个点位于曲线的中间位置(见图3-7a)，曲线的方向是由第一个点指向第二个点。",
    /*18*/"(未完成)\nVTK_QUADRATIC_TRIANGLE：二次三角形，二维的基本类型之一，由六个点定义，其中前三个点对应三角形的三个顶点，另外三个点分别对应三条边的中点,如左图所示。",
    /*19*/"(未完成)\nVTK_QUADRATIC_QUAD：二次四边形，二维的基本类型之一，由八个点定义，其中前四个点分别对应四个顶点，后四个点分别对应四条边的中点,如左图所示。",
    /*20*/"(未完成)\nVTK_QUADRATIC_TETRA：二次四面体，三维的基本类型之一，由 10 个点定义，其中前四个点分别对应四面体的四个顶点，其余六个点分别对应六条边的中点,如左图所示。",
    /*21*/"(未完成)\nVTK_QUADRATIC HEXAHEDRON：二次六面体，三维的基本类型之一，由 20 个点定义，其中前八个点对应六面体的八个顶点，其余12个点分别对应12条边的中点,如左图所示。",
    /*22*/"(未完成)\nVTK_QUADRATIC_WEDGE：二次楔形体，三维的基本类型之一，由 15 个点定义，其中前六个点对应楔形体的六个顶点，其余九个点分别对应九条边的中点,如左图所示。",
    /*23*/"(未完成)\nVTK_QUADRATIC HEXAHEDRON：二次六面体，三维的基本类型之一，由 20 个点定义，其中前八个点对应六面体的八个顶点，其余12个点分别对应12条边的中点,如左图所示。"
};


Global *Global::Instance()
{
    if (mInstance == nullptr)
    {
        QMutexLocker locker(&mMutex);
        if (mInstance == nullptr)
            mInstance = new Global;
    }
    return mInstance;
}

void Global::setRootDirPath(const QString &path)
{
    mRootPath = path;
    checkResource();
}

QString Global::rootDirPath()
{
    return mRootPath;
}

QString Global::resourceDirPath()
{
    return mRootPath + "/config";
}

void Global::setConfigParam(ConfigParam p)
{
    mConfigParam = p;
    QSettings settings(configFilePath(), QSettings::IniFormat);
    settings.setIniCodec("UTF-8");
    settings.setValue("/Param/OutputFile", mConfigParam.outputFile);
    settings.setValue("/Param/CellIndexs", mConfigParam.cellIndexs);
    settings.setValue("/Param/CellNum", mConfigParam.cellNum);
    settings.setValue("/Param/Shape", mConfigParam.shape);
    settings.setValue("/Param/XLength", mConfigParam.xLength);
    settings.setValue("/Param/YLength", mConfigParam.yLength);
    settings.setValue("/Param/ZLength", mConfigParam.zLength);
    settings.setValue("/Param/GroupCell", mConfigParam.groupCell);
    settings.setValue("/Param/WeiDu", mConfigParam.weiDu);
}

ConfigParam Global::configParam()
{
    return mConfigParam;
}

QString Global::configFilePath()
{
    return resourceDirPath() + "/config.ini";
}

Global::Global()
{
    mRootPath = "";
}

void Global::checkResource()
{
    // 检查配置文件目录是否存在
    QList<QString> listPath;
    listPath << rootDirPath() << resourceDirPath();
    for (QString path : listPath)
    {
        QDir dir(path);
        if (!dir.exists())
            dir.mkpath(path);
    }

    // 定义ini文件处理类
    QSettings settings(configFilePath(), QSettings::IniFormat);
    settings.setIniCodec("UTF-8");

    QFileInfo iniFileInfo(configFilePath());
    if (!iniFileInfo.exists())
    {
        settings.setValue("/Param/OutputFile", mConfigParam.outputFile);
        settings.setValue("/Param/CellIndexs", mConfigParam.cellIndexs);
        settings.setValue("/Param/CellNum", mConfigParam.cellNum);
        settings.setValue("/Param/Shape", mConfigParam.shape);
        settings.setValue("/Param/XLength", mConfigParam.xLength);
        settings.setValue("/Param/YLength", mConfigParam.yLength);
        settings.setValue("/Param/ZLength", mConfigParam.zLength);
        settings.setValue("/Param/GroupCell", mConfigParam.groupCell);
        settings.setValue("/Param/WeiDu", mConfigParam.weiDu);
    }
    else
    {

        if (!settings.contains("/Param/OutputFile"))
        {
            settings.setValue("/Param/OutputFile", mConfigParam.outputFile);
        }
        if (!settings.contains("/Param/CellIndexs"))
        {
            settings.setValue("/Param/CellIndexs", mConfigParam.cellIndexs);
        }
        if (!settings.contains("/Param/CellNum"))
        {
            settings.setValue("/Param/CellNum", mConfigParam.cellNum);
        }
        if (!settings.contains("/Param/Shape"))
        {
            settings.setValue("/Param/Shape", mConfigParam.shape);
        }

        if (!settings.contains("/Param/XLength"))
        {
            settings.setValue("/Param/XLength", mConfigParam.xLength);
        }

        if (!settings.contains("/Param/YLength"))
        {
            settings.setValue("/Param/YLength", mConfigParam.yLength);
        }

        if (!settings.contains("/Param/ZLength"))
        {
            settings.setValue("/Param/ZLength", mConfigParam.zLength);
        }

        if (!settings.contains("/Param/GroupCell"))
        {
            settings.setValue("/Param/GroupCell", mConfigParam.groupCell);
        }

        if (!settings.contains("/Param/WeiDu"))
        {
            settings.setValue("/Param/WeiDu", mConfigParam.weiDu);
        }



        mConfigParam.outputFile = settings.value("/Param/OutputFile", mConfigParam.outputFile).toString();
        mConfigParam.cellIndexs = settings.value("/Param/CellIndexs", mConfigParam.cellIndexs).toString();
        mConfigParam.cellNum = settings.value("/Param/CellNum", mConfigParam.cellNum).toInt();
        mConfigParam.shape = settings.value("/Param/Shape", mConfigParam.shape).toInt();

        mConfigParam.xLength = settings.value("/Param/XLength", mConfigParam.xLength).toInt();
        mConfigParam.yLength = settings.value("/Param/YLength", mConfigParam.yLength).toInt();
        mConfigParam.zLength = settings.value("/Param/ZLength", mConfigParam.zLength).toInt();
        mConfigParam.groupCell = settings.value("/Param/GroupCell", mConfigParam.groupCell).toBool();

        mConfigParam.weiDu = settings.value("/Param/WeiDu", mConfigParam.weiDu).toInt();
    }
}

Global *Global::mInstance = nullptr;
QMutex Global::mMutex;
Global::GC Global::gc;

namespace GlobalStatement
{
    QString cellIndexToStr(CellIndex idx)
    {
    if(Point == idx)
        return "点";
    else if(Vertex == idx)
        return "顶点";
    else if(PolyVertex == idx)
        return "多点";
    else if(Line == idx)
        return "线段";
    else if(PolyLine == idx)
        return "多段线";
    else if(Triangle == idx)
        return "三角形";
    else if(TriangleStrip == idx)
        return "三角带";
    else if(Polygon == idx)
        return "多边形";
    else if(Pixel == idx)
        return "四边形1";
    else if(Quad == idx)
        return "四边形2";
    else if(Tetra == idx)
        return "四面体";
    else if(Voxel == idx)
        return "六面体1";
    else if(Hexahedron == idx)
        return "六面体2";
    else if(Wedge == idx)
        return "楔形";
    else if(Pyramid == idx)
        return "金字塔";
    else if(PentagonalPrism == idx)
        return "五角棱柱";
    else if(HexagonalPrism == idx)
        return "六角棱柱";
    else if(QuadraticEdge == idx)
        return "二次曲线段";
    else if(QuadraticTriangle == idx)
        return "二次三角形";
    else if(QuadraticQuad == idx)
        return "二次四边形";
    else if(QuadraticTetra == idx)
        return "二次四面体";
    else if(QuadraticHexahedron == idx)
        return "二次六面体";
    else if(QuadraticWedge == idx)
        return "二次楔形";
    else if(QuadraticPyramid == idx)
        return "二次金字塔";
    return "点";
}

CellIndex strToCellIndex(const QString& str)
{
    if(str.compare("点") == 0)
        return Point;
    else if(str.compare("顶点") == 0)
        return Vertex;
    else if(str.compare("多点") == 0)
        return PolyVertex;
    else if(str.compare("线段") == 0)
        return Line;
    else if(str.compare("多段线") == 0)
        return PolyLine;
    else if(str.compare("三角形") == 0)
        return Triangle;
    else if(str.compare("三角带") == 0)
        return TriangleStrip;
    else if(str.compare("多边形") == 0)
        return Polygon;
    else if(str.compare("四边形1") == 0)
        return Pixel;
    else if(str.compare("四边形2") == 0)
        return Quad;
    else if(str.compare("四面体") == 0)
        return Tetra;
    else if(str.compare("六面体1") == 0)
        return Voxel;
    else if(str.compare("六面体2") == 0)
        return Hexahedron;
    else if(str.compare("楔形") == 0)
        return Wedge;
    else if(str.compare("金字塔") == 0)
        return Pyramid;
    else if(str.compare("五角棱柱") == 0)
        return PentagonalPrism;
    else if(str.compare("六角棱柱") == 0)
        return HexagonalPrism;
    else if(str.compare("二次曲线段") == 0)
        return QuadraticEdge;
    else if(str.compare("二次三角形") == 0)
        return QuadraticTriangle;
    else if(str.compare("二次四边形") == 0)
        return QuadraticQuad;
    else if(str.compare("二次四面体") == 0)
        return QuadraticTetra;
    else if(str.compare("二次六面体") == 0)
        return QuadraticHexahedron;
    else if(str.compare("二次楔形") == 0)
        return QuadraticWedge;
    else if(str.compare("二次金字塔") == 0)
        return QuadraticPyramid;
    return Point;
}

QString cellIndexToExplain(CellIndex idx)
{
    int _idx = idx;
    if(_idx >= 0 && _idx < explains.size())
        return explains.at(_idx);
    return explains.at(0);
}

}
