
#include "sanalyzer.h"
#include "sanaly1.h"
#include <QFile>
AnalyzerThread::AnalyzerThread(QObject *parent) : QThread(parent), m_nThread(1), m_pWidget(NULL), m_nSource(0), m_bPeriod(false), m_nPeriod(0)
{
}
AnalyzerThread::AnalyzerThread(int number)
{
}

AnalyzerThread::AnalyzerThread(QMutex &_mutex, int _number, int &_nCount)
{
    AnalyzerThread();
    num = _number;
    mutex = &_mutex;
    nCount = &_nCount;
}

void AnalyzerThread::setThreadNumber(int _nThread)
{
    m_nThread = _nThread;
}

int AnalyzerThread::getThreadNumber()
{
    return m_nThread;
}

void AnalyzerThread::setWidget(QWidget *_pWidget)
{
    m_pWidget = (Widget*)_pWidget;
    m_pTabWidget = m_pWidget->GetTabWidget();
}

QWidget* AnalyzerThread::getWidget()
{
    return m_pQWidget;
}

void AnalyzerThread::setMorphereList(const QStringList morpherelist)
{
    m_slMorphereList.append(morpherelist);
}


void AnalyzerThread::setMorphereList(const QString morphere)
{
    m_slMorphereList.append(morphere);
}

void AnalyzerThread::resetMorphereList()
{
    m_slMorphereList.clear();
}

void AnalyzerThread::setParametersfromWidget(QWidget *_pWidget, int _nSource)
{
    resetMorphereList();
    if(_nSource == 0)
    {
        pWidget = (SAnaly1*)_pWidget;
        setThreadNumber(pWidget->getThread());
        setPeriod(pWidget->getPeriod());
        m_bDateAll = pWidget->getDateAll();
        m_nDateStart = pWidget->getDateStart();
        m_nDateEnd = pWidget->getDateEnd();
        setMorphereList(pWidget->getMorphereList());
    }
}

QStringList AnalyzerThread::getMorphereList()
{
    return m_slMorphereList;
}

void AnalyzerThread::setPeriod(const int _nPeriod)
{
    m_nPeriod = _nPeriod;
}

int AnalyzerThread::getPeriod()
{
    return m_nPeriod;
}

void AnalyzerThread::setDate(const QDateTime _dtStart, const QDateTime _dtEnd)
{
    m_nDateStart = _dtStart.toString("yyyy-MM-dd").replace("-","").toInt();
    m_nDateEnd = _dtEnd.toString("yyyy-MM-dd").replace("-","").toInt();
}
void AnalyzerThread::setDate(const QString _strStart, const QString _strEnd)
{
    m_nDateStart = _strStart.toInt();
    m_nDateEnd = _strEnd.toInt();
}

unsigned int AnalyzerThread::getDateStart()
{
    return m_nDateStart;
}

unsigned int AnalyzerThread::getDateEnd()
{
    return m_nDateEnd;
}

void AnalyzerThread::setTitleBody(const int _n)
{
    m_nTitleBody = _n;
}

void AnalyzerThread::setPosDate(const int _nPos)
{
    m_nPosDate = _nPos;
}

void AnalyzerThread::setPosBody(const int _nPos)
{
    m_nPosBody = _nPos;
}

void AnalyzerThread::setPosTitle(const int _nPos)
{
    m_nPosTitle = _nPos;
}

void AnalyzerThread::setPosPlatformTitle(const int _nPos)
{
    m_nPosPlatformTitle = _nPos;
}

void AnalyzerThread::run()
{

    typedef mecab_t* (*mecab_new_fun)(int,char**);
    typedef const char* (*mecab_sparse_tostr_fun)(mecab_t *mecab, const char *str);
    typedef void (*mecab_destroy_fun)(mecab_t *mecab);

    mecab_t *mecab;
    mecab_new_fun mecab_new  = (mecab_new_fun)QLibrary::resolve("libmecab.dll","mecab_new");
    mecab_sparse_tostr_fun mecab_sparse_tostr = (mecab_sparse_tostr_fun)QLibrary::resolve("libmecab.dll","mecab_sparse_tostr");

    QString userdict = pWidget->getUserDictList();

    if(userdict.length() < 1)
    {
        /*
        char *t[]  = {"RRR","-d","dic"};
        int int_t = 3;
        */

        char a[] = "RRR";
        char b[] = "-d";
        char c[] = "dic";
        char *t[3];
        t[0] = a;
        t[1] = b;
        t[2] = c;
        int int_t = 3;

        mecab = mecab_new(int_t, t);
    }
    else
    {
        char *cstr = new char[userdict.toStdString().length() + 1];
        strcpy(cstr, userdict.toStdString().c_str());
        /*
        char **t  = {"RRR","-d","dic","-u",cstr};
        int int_t = 5;
        */
        char a[] = "RRR";
        char b[] = "-d";
        char c[] = "dic";
        char d[] = "-u";

        char *t[5];
        t[0] = a;
        t[1] = b;
        t[2] = c;
        t[3] = d;
        t[4] = cstr;
        int int_t = 5;

        mecab = mecab_new(int_t, t);
        delete[] cstr;
    }
    mecab_destroy_fun mecab_destroy = (mecab_destroy_fun)QLibrary::resolve("libmecab.dll","mecab_destroy");



    //qDebug() << num;

    STable *pCurrent = (STable *)m_pTabWidget->currentWidget();
    int nDate = 0;
    while(true)
    {
        QString strTitle;
        QString strBody;
        QString strDate;
        QString strData;
        QString strPlatformTitle;
        {
            mutex->lock();
            if(*nCount >= pCurrent->rowCount())
            {
                mutex->unlock();
                break;
            }
            strTitle = pCurrent->item((*nCount),m_nPosTitle)->text();
            strDate = pCurrent->item((*nCount),m_nPosDate)->text();
            strPlatformTitle = pCurrent->item((*nCount),m_nPosPlatformTitle)->text();
            strBody = pCurrent->item((*nCount)++,m_nPosBody)->text();

            mutex->unlock();
        }

        {
            switch(m_nTitleBody)
            {
            case 0:
            {
                strData = strTitle;
                break;
            }
            case 1:
            {
                strData = strBody;
                break;
            }
            case 2:
            {
                strData = strTitle + "\n" + strBody;
                break;
            }
            case 3:
                strData = strPlatformTitle;
                break;
            }
            strTitle.clear();
            strBody.clear();
            strPlatformTitle.clear();
        }

        if(strDate.length() < 11)
            continue;

        strDate = strDate.left(11);
        if(strDate.trimmed().length()<10)
        {
            nDate = 0;
        }
        else
        {
            strDate = strDate.replace("-","").trimmed();
            if(strDate.length() < 8)
            {
                nDate = 0;
            }
            else
                nDate = strDate.toInt();
        }

        if(!m_bDateAll)
        {
            if(nDate < m_nDateStart || m_nDateEnd < nDate)
                continue;
        }


        SAnaly1::m_mapKey mapkey;

        switch(m_nPeriod)
        {
        case 0:
        {
            mapkey.strDate = "ALL";
            break;
        }
        case 1:
        {
            mapkey.strDate = "D" + QString::number(nDate);
            break;
        }
        case 2:
        {
            /*
            QDate tempdate = QDate(nDate/10000, (nDate%10000)/100, nDate%100);
            mapkey.strDate = "W" + QString::number(nDate/10000);
            if(tempdate.weekNumber() < 10)
                mapkey.strDate += "0";
            mapkey.strDate += QString::number(tempdate.weekNumber());
            */
            mapkey.strDate = getWeeksInMonth(nDate);
            break;
        }
        case 3:
        {
            mapkey.strDate = "M";
            if((nDate/100) < 10)
                mapkey.strDate += "0";
            mapkey.strDate += QString::number(nDate/100);
            break;
        }
        }

        QString strAnalyzedLine = QString::fromStdString(mecab_sparse_tostr(mecab, strData.toStdString().c_str())) + "\n";
        QStringList strListAll = strAnalyzedLine.split("\n",QString::SkipEmptyParts);

        foreach(QString strLine, strListAll)
        {
            QStringList strListLine = strLine.split("\t");
            if(strListLine.size() < 2)
                continue;
            QStringList strpumsa = strListLine.at(1).trimmed().split(",");
            foreach(QString strMorphere, m_slMorphereList)
            {
                if(strpumsa.at(0).trimmed().contains(strMorphere,Qt::CaseInsensitive))
                {
                    mapkey.strKeyword = strListLine.at(0);
                    mapkey.strMorphere = strMorphere;
                    QString strkey = mapkey.strDate + "~!@" + mapkey.strMorphere + "~!@" + mapkey.strKeyword;
                    if(pWidget->m_HashResult[num].contains(strkey))
                    {
                        (pWidget->m_HashResult[num])[strkey]++;
                    }

                    else
                    {
                        pWidget->m_HashResult[num].insert(strkey,1);
                    }
                }
            }
        }

        //if(m_bDateAll)

        //qDebug() << num << " : " << strData;
    }

    mecab_destroy(mecab);
    /*
    for (int nCount = 0 ; nCount < pCurrent->rowCount(); nCount++ )
    {
        QString strData = pCurrent->item(nCount,m_nPosBody)->text();
        qDebug() << strData;
    }

    for(QHash<QString, int>::iterator iterPos = pWidget->m_HashResult[num].begin(); iterPos != pWidget->m_HashResult[num].end(); iterPos++)
    {
        qDebug() << num << " : " << iterPos.key()  << " ===== " << iterPos.value();
    }

    foreach(QString str, m_slMorphereList)
    {
        qDebug() << num << " : " << str;
    }
    qDebug() << num << " : " << m_bDateAll;
    qDebug() << num << " : " << m_bPeriod;
    qDebug() << num << " : " << m_nDateStart;
    qDebug() << num << " : " << m_nDateEnd;
    qDebug() << num << " : " << pWidget->m_HashResult[num].isEmpty();
    */
}

QString AnalyzerThread::getWeeksInMonth(unsigned int _nDate)
{

    QDate qToday(_nDate/10000, (_nDate/100)%100, _nDate%100);
    if(!qToday.isValid())
        return "inVaildDate";

    QDate qTodayFirstDay = QDate(qToday.year(), qToday.month(), 1);
    QDate qTodayLastDay = QDate(qToday.year(), qToday.month(), qToday.daysInMonth());

    int thisFirstDayofWeek = qTodayFirstDay.dayOfWeek();
    int thisLastDayofWeek = qTodayLastDay.dayOfWeek();
    int thisLastDay = qTodayLastDay.daysInMonth();
    int week = 0;
    int firstWeekDays = (WEEK - thisFirstDayofWeek) + 1;
    QString strWeek = "W";

    if(thisFirstDayofWeek < FRIDAY)
    {
        week = 1;
    }
    else
    {
        week = 0;
    }

    if((firstWeekDays < qToday.day()) && (qToday.day() <= (thisLastDay - thisLastDayofWeek)))
    {
        week = week + ((qToday.day() - firstWeekDays + WEEK - 1)/WEEK);
    }
    else if((firstWeekDays >= qToday.day()))
    {
        if(thisFirstDayofWeek >= FRIDAY)
        {

            const int DAYS_IN_WEEK = 7;
            qToday = qToday.addMonths(-1);
            int DaysInMonth = qToday.daysInMonth();
            QDate FirstDayOfMonth = qToday;
            FirstDayOfMonth.setDate(qToday.year(), qToday.month(), 1);

            int WeekCount = DaysInMonth / DAYS_IN_WEEK;
            int DaysLeft = DaysInMonth % DAYS_IN_WEEK;
            if (DaysLeft > 0) {
               WeekCount++;
               // Check if the remaining days are split on two weeks
               if (FirstDayOfMonth.dayOfWeek() + DaysLeft - 1 > DAYS_IN_WEEK)
                  WeekCount++;
            }
            week = WeekCount;
        }
    }
    else
    {
        if(thisLastDayofWeek < THURSDAY)
        {
            week = 1;
            qToday = qToday.addMonths(1);
        }
        else
        {
            week = week + ((qToday.day() - firstWeekDays + WEEK - 1)/WEEK);
        }
    }

    strWeek += qToday.toString("yyyyMM");
    strWeek += QString::number(week);
    return strWeek;

}

void AnalyzerThread::setAnalyzerThread(QMutex &_mutex, int number, int &_nCount)
{
    num = number;
    mutex = &_mutex;
    nCount = &_nCount;
}

