/***************************************************************************
 *   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.
 ***************************************************************************/
#ifndef WORDMATCHER_H
#define WORDMATCHER_H

#include <QStringMatcher>
#include <QVector>


class wordMatcher
{

public:
    wordMatcher();
    wordMatcher(const QString& pattern, const Qt::CaseSensitivity cs = Qt::CaseSensitive);
    inline ~wordMatcher() {}


    int indexIn(const QString& str, const int from = 0) const;
    void setPattern(const QString& pattern, const Qt::CaseSensitivity cs);
    inline int matchedLength() const
    {
        return _matched_length;
    }


private:
    inline int _index_in(const int& s, const QString& str, const int& p0) const
    {
        return _substrings.at(s).indexIn(str, p0);
    }
    inline int _index_in(const int& s, const QString& str, const int& p0, const int& pn) const
    {
        if (p0 >= pn)
            return -1;
        return _substrings.at(s).indexIn(str.unicode(), std::min(_pn, pn), p0);
    }
    inline int _index_around(const QString& str, const int phook) const
    {
        _sp0.fill(-1);
        _sp0[_hook] = phook;

        const int bp0 = std::max(_p0, phook - _stretch);
        const int bpn = std::min(_pn, phook + _stretch);
        for (int i = 0; i < _substring_count; ++i)
            if (_sp0.at(i) == -1)
            {
                const int p0(_index_in(i, str, bp0, bpn));
                if (p0 == -1)
                    return -1;
                _sp0[i] = p0;
            }

        int bp(_pn);
        int fp(_p0);
        for (int i = 0; i < _substring_count; ++i)
        {
            const int p0 = _sp0.at(i);
            if (bp > p0)
                bp = p0;
            const int pn = p0 + _lengths.at(i);
            if (fp < pn)
                fp = pn;
        }
        _matched_length = fp - bp;
        return bp;
    }

    QVector<QStringMatcher> _substrings;
    QVector<int> _lengths;
    int _stretch;
    int _hook;
    int _substring_count;
    mutable QVector<int> _sp0;
    mutable int _matched_length;
    mutable int _p0;
    mutable int _pn;

};

#endif
