/***************************************************************************
 *   Copyright (C) 2004-2017 by Pere Constans
 *   constans@molspaces.com
 *   cb2Bib version 1.9.7. Licensed under the GNU GPL version 3.
 *   See the LICENSE file that comes with this distribution.
 ***************************************************************************/
#include "wordMatcher.h"

#include "triads.h"
#include "cb2bib_utilities.h"


wordMatcher::wordMatcher() : _stretch(0), _hook(-1), _substring_count(0), _matched_length(-1), _p0(0), _pn(0)
{}

wordMatcher::wordMatcher(const QString& pattern, const Qt::CaseSensitivity cs) : _p0(0), _pn(0)
{
    setPattern(pattern, cs);
}


void wordMatcher::setPattern(const QString& pattern, const Qt::CaseSensitivity cs)
{
    _hook = -1;
    _matched_length = -1;
    const QStringList substrings(pattern.split(c2bUtils::nonLetter, QString::SkipEmptyParts));
    if (substrings.count() == 0)
        return;
    _substring_count = substrings.count();
    _substrings.resize(_substring_count);
    _lengths.resize(_substring_count);
    _sp0.resize(_substring_count);
    _stretch = 0;
    for (int i = 0; i < _substring_count; ++i)
    {
        _substrings[i] = QStringMatcher(substrings.at(i), cs);
        _lengths[i] = substrings.at(i).length();
        if (_lengths.at(i) > 4)
            _stretch += 50;
        else
            _stretch += 10;
    }
    int lf(10000);
    for (int i = 0; i < _substring_count; ++i)
    {
        const int f(triads::textFrequency(substrings.at(i)));
        if (f < lf)
        {
            lf = f;
            _hook = i;
        }
    }
}

int wordMatcher::indexIn(const QString& str, const int from) const
{
    _matched_length = -1;
    if (_hook == -1)
    {
        c2bUtils::warn(QObject::tr("Warning: Uninitialized wordMatcher"));
        return -1;
    }
    _p0 = from;
    if (_p0 < 0)
        _p0 = 0;
    _pn = str.length();
    if (_pn == 0)
        return -1;

    int hp(_p0);
    int p(-1);
    while (p == -1)
    {
        hp = _index_in(_hook, str, hp);
        if (hp == -1)
            return -1;
        p = _index_around(str, hp);
        hp += _lengths.at(_hook);
    }
    return p;
}
