#include <QDate>
#include <QMap>
#include <QString>
#include "sfilteralgorithm.h"
#include "../Json/sjson.h"
#include <QDebug>

void FilterSearch(QVector<QStringList> *m_data, bool *m_bDataFlag, QString _strJson);
void FilterCounter(QVector<QStringList> *m_data, bool *m_bDataFlag, QString _strJson);
void FilterReplace(QVector<QStringList> *m_data, bool *m_bDataFlag, QString _strJson);
void FilterDate(QVector<QStringList> *m_data, bool *m_bDataFlag, QString _strJson, int _nDateColumn);
void FilterLength(QVector<QStringList> *m_data, bool *m_bDataFlag, QString _strJson);

void SFilterAlgorithm::FilterDate(QVector<QStringList> *m_data, bool *m_bDataFlag, QString _strJson, int _nDateColumn)
{
    SJson json;
    int nSelect = json.Get(_strJson,"Article").toInt() - 1;
    if (nSelect < 0) return;
    m_bDataFlag[nSelect] = true;
    QVector <QStringList> copyData;
    QDate dateStart = QDate::fromString(json.Get(_strJson,"Start"),"yyyy-MM-dd");
    QDate dateEnd = QDate::fromString(json.Get(_strJson,"End"),"yyyy-MM-dd");
    foreach(const QStringList& strList , m_data[nSelect])
    {
        bool bFlag = false;
        QString strTime = strList.at(_nDateColumn).trimmed();
        if (strTime.size() >= 10)
        {
            QChar ch = strTime.at(4);
            QString strFormat = QString("yyyy")+ch+QString("MM")+ch+QString("dd");
            QDate date = QDate::fromString(strTime.left(10),strFormat);
            if (dateStart <= date && dateEnd >= date)
                bFlag = true;
        }
        if (bFlag)
            copyData.push_back(strList);
    }
    m_data[nSelect].clear();
    m_data[nSelect] = copyData;
}

void SFilterAlgorithm::FilterLength(QVector<QStringList> *m_data, bool *m_bDataFlag, QString _strJson)
{
    SJson json;
    int nSelect = json.Get(_strJson,"Article").toInt() - 1;
    if (nSelect < 0) return;
    m_bDataFlag[nSelect] = true;

    int nCatalog = json.GetNumber(_strJson,"Category");
    int nComp = json.GetNumber(_strJson,"Comp");
    int nFlag = json.GetNumber(_strJson,"InsDel");
    int nLength = json.Get(_strJson,"String").toInt();

    QVector <QStringList> copyData;
    foreach(const QStringList& strList , m_data[nSelect])
    {
        bool bFlag = false;
        int nCurrentLength = strList.at(nCatalog).trimmed().length();
        switch(nComp)
        {
        case E_LENGTH_COMP_GREATER:
            if (nCurrentLength > nLength)
                bFlag = true;
            break;
        case E_LENGTH_COMP_LESS:
            if (nCurrentLength < nLength)
                bFlag = true;
            break;
        case E_LENGTH_COMP_EQUAL:
            if (nCurrentLength == nLength)
                bFlag = true;
            break;
        }
        if (nFlag == 1) bFlag = !bFlag;
        if (bFlag)
            copyData.push_back(strList);
    }
    m_data[nSelect].clear();
    m_data[nSelect] = copyData;
}

void SFilterAlgorithm::FilterCounter(QVector<QStringList> *m_data, bool *m_bDataFlag, QString _strJson)
{
    SJson json;
    int nSelect = json.Get(_strJson,"Article").toInt() - 1;
    if (nSelect < 0) return;
    m_bDataFlag[nSelect] = true;

    int nCatalog = json.GetNumber(_strJson,"Category");
    int nComp = json.GetNumber(_strJson,"Comp");
    int nFlag = json.GetNumber(_strJson,"InsDel");
    int nCounter = json.Get(_strJson,"String").toInt();

    QMap <QString, int> mapData, mapDataresult;
    foreach(const QStringList& strList , m_data[nSelect])
    {
        QString str = strList.at(nCatalog).trimmed();
        if(mapData.contains(str))
            mapData[str]++;
        else
            mapData.insert(str, 1);
    }

    for(QMap <QString, int>::iterator iterPos = mapData.begin(); iterPos != mapData.end(); iterPos++)
    {
        bool bFlag = false;
        switch(nComp)
        {
        case E_LENGTH_COMP_GREATER:
            if (iterPos.value() > nCounter)
                bFlag = true;
            break;
        case E_LENGTH_COMP_LESS:
            if (iterPos.value() < nCounter)
                bFlag = true;
            break;
        case E_LENGTH_COMP_EQUAL:
            if (iterPos.value() == nCounter)
                bFlag = true;
            break;
        }
        if (nFlag == 1) bFlag = !bFlag;
        if (bFlag)
            mapDataresult.insert(iterPos.key(), iterPos.value());
    }

    mapData.clear();

    QVector <QStringList> copyData;
    foreach(const QStringList& strList , m_data[nSelect])
    {
        QString str = strList.at(nCatalog).trimmed();
        if(mapDataresult.contains(str))
            copyData.push_back(strList);
    }
    m_data[nSelect].clear();
    m_data[nSelect] = copyData;
}

void SFilterAlgorithm::FilterReplace(QVector<QStringList> *m_data, bool *m_bDataFlag, QString _strJson)
{
    SJson json;
    int nSelect = json.Get(_strJson,"Article").toInt() - 1;
    if (nSelect < 0) return;
    m_bDataFlag[nSelect] = true;

    int nCatalog = json.GetNumber(_strJson,"Category");
    QString strFind = json.Get(_strJson,"String_Find");
    QString strReplace = json.Get(_strJson,"String_Replace");

    bool bFlag = false;
    QStringList strListKeyword;
    if (json.GetNumber(_strJson,"Find") == E_REPLACE_SPACE)
    {
        bFlag = true;
        strListKeyword = strFind.split(" ");
    }

    for (int i = 0 ; i < m_data[nSelect].size(); i++)
    {
        if (bFlag)
        {
            foreach(const QString& str,strListKeyword)
            {
                m_data[nSelect][i][nCatalog] = m_data[nSelect][i][nCatalog].replace(str,strReplace);
            }
        }
        else
            m_data[nSelect][i][nCatalog] = m_data[nSelect][i][nCatalog].replace(strFind,strReplace);
    }
}

void SFilterAlgorithm::FilterSearch(QVector<QStringList> *m_data, bool *m_bDataFlag, QString _strJson)
{
    SJson json;
    int nSelect = json.Get(_strJson,"Article").toInt() - 1;
    if (nSelect < 0) return;
    m_bDataFlag[nSelect] = true;
    {
        SKeyword stKeyword;
        stKeyword.m_nCatalog = json.GetNumber(_strJson,"Category");
        stKeyword.m_nKeyword = json.GetNumber(_strJson,"Keyword");
        stKeyword.m_strListKeyword = json.Get(_strJson,"String").split(" ");
        if (json.GetNumber(_strJson,"Method") == 1)
        {
            for (int i = 0 ; i < stKeyword.m_strListKeyword.size(); i++ )
                stKeyword.m_strListKeyword[i] = " " + stKeyword.m_strListKeyword[i] + " ";
        }
        m_vecKeyword.push_back(stKeyword);
    }
    if (json.GetBool(_strJson,"Last")) //
    {
        QVector <QStringList> copyData;

        foreach(const QStringList& strList , m_data[nSelect])
        {
            bool bFlag = false;
            foreach(const SKeyword& stKeyword,m_vecKeyword)
            {
                QString strData = strList.at(stKeyword.m_nCatalog);
                switch(stKeyword.m_nKeyword)
                {
                    case E_SEARCH_KEYWORD_OR:
                    {
                        foreach(const QString& strKey , stKeyword.m_strListKeyword)
                            if (strData.contains(strKey)){bFlag = true;break;}
                        break;
                    }
                    case E_SEARCH_KEYWORD_AND:
                    {
                        int nKeyCount = 0;
                        foreach(const QString& strKey , stKeyword.m_strListKeyword)
                            if (strData.contains(strKey)) nKeyCount++;
                        if (nKeyCount == stKeyword.m_strListKeyword.size())
                            bFlag = true;
                        break;
                    }
                    case E_SEARCH_KEYWORD_CELL_DELETE_OR:
                    {
                        bFlag = true;
                        foreach(const QString& strKey , stKeyword.m_strListKeyword)
                            if (strData.contains(strKey)){bFlag = false;break;}
                        break;
                    }
                    case E_SEARCH_KEYWORD_CELL_DELETE_AND:
                    {
                        bFlag = true;
                        int nCount = 0;
                        foreach(const QString& strKey , stKeyword.m_strListKeyword)
                            if (strData.contains(strKey)){nCount++;}
                        if (nCount == stKeyword.m_strListKeyword.size())
                            bFlag = false;
                        break;
                    }
                }
            }
            if (bFlag) copyData.push_back(strList);
        }
        m_data[nSelect].clear();
        m_data[nSelect] = copyData;
        m_vecKeyword.clear();
    }
}
