/****************************************************************************
**
** Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team.
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtTools module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 3 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL3 included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 2.0 or (at your option) the GNU General
** Public license version 3 or any later version approved by the KDE Free
** Qt Foundation. The licenses are as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "qquery_p.h"
#include "qclucene_global_p.h"

#include <CLucene.h>
#include <CLucene/search/PhraseQuery.h>
#include <CLucene/search/SearchHeader.h>

QT_BEGIN_NAMESPACE

QCLuceneQueryPrivate::QCLuceneQueryPrivate()
    : QSharedData()
{
    query = 0;
    deleteCLuceneQuery = true;
}

QCLuceneQueryPrivate::QCLuceneQueryPrivate(const QCLuceneQueryPrivate &other)
    : QSharedData()
{
    query = _CL_POINTER(other.query);
    deleteCLuceneQuery = other.deleteCLuceneQuery;
}

QCLuceneQueryPrivate::~QCLuceneQueryPrivate()
{
    if (deleteCLuceneQuery)
        _CLDECDELETE(query);
}


QCLuceneQuery::QCLuceneQuery()
    : d(new QCLuceneQueryPrivate())
{
    // nothing todo, private
}

QCLuceneQuery::~QCLuceneQuery()
{
    // nothing todo
}

void QCLuceneQuery::setBoost(qreal boost)
{
    d->query->setBoost(qreal(boost));
}

qreal QCLuceneQuery::getBoost() const
{
    return qreal(d->query->getBoost());
}

QString QCLuceneQuery::getQueryName() const
{
    return TCharToQString(d->query->getQueryName());
}

bool QCLuceneQuery::instanceOf(const QString &other) const
{
    if (other == getQueryName())
        return true;

    return false;
}

QString QCLuceneQuery::toString(const QString &field) const
{
    TCHAR *fieldName = QStringToTChar(field);
    QString retValue = TCharToQString(d->query->toString(fieldName));
    delete [] fieldName;

    return retValue;
}

quint32 QCLuceneQuery::hashCode() const
{
    return quint32(d->query->hashCode());
}

QString QCLuceneQuery::toString() const
{
    return TCharToQString(d->query->toString());
}

bool QCLuceneQuery::equals(const QCLuceneQuery &other) const
{
    return d->query->equals(other.d->query);
}


QCLucenePrefixQuery::QCLucenePrefixQuery(const QCLuceneTerm &prefix)
    : QCLuceneQuery()
    , prefix(prefix)
{
    d->query = new lucene::search::PrefixQuery(prefix.d->term);
}

QCLucenePrefixQuery::~QCLucenePrefixQuery()
{
    // nothing todo
}

QString QCLucenePrefixQuery::getClassName()
{
    return TCharToQString(lucene::search::PrefixQuery::getClassName());
}

QCLuceneTerm QCLucenePrefixQuery::getPrefix() const
{
    return prefix;
}


QCLuceneRangeQuery::QCLuceneRangeQuery(const QCLuceneTerm &lowerTerm,
                                       const QCLuceneTerm &upperTerm,
                                       bool inclusive)
    : QCLuceneQuery()
    , lowerTerm(lowerTerm)
    , upperTerm(upperTerm)
{
    d->query = new lucene::search::RangeQuery(lowerTerm.d->term,
        upperTerm.d->term, inclusive);
}

QCLuceneRangeQuery::~QCLuceneRangeQuery()
{
    // nothing todo
}

QString QCLuceneRangeQuery::getClassName()
{
    return TCharToQString(lucene::search::RangeQuery::getClassName());
}

QCLuceneTerm QCLuceneRangeQuery::getLowerTerm() const
{
    return lowerTerm;
}

QCLuceneTerm QCLuceneRangeQuery::getUpperTerm() const
{
    return upperTerm;
}

bool QCLuceneRangeQuery::isInclusive() const
{
    lucene::search::RangeQuery *query =
        static_cast<lucene::search::RangeQuery*> (d->query);

    if (query == 0)
        return false;

    return query->isInclusive();
}

QString QCLuceneRangeQuery::getField() const
{
    lucene::search::RangeQuery *query =
        static_cast<lucene::search::RangeQuery*> (d->query);

    if (query == 0)
        return QString();

    return TCharToQString(query->getField());
}


QCLuceneTermQuery::QCLuceneTermQuery(const QCLuceneTerm &term)
    : QCLuceneQuery()
    , term(term)
{
    d->query = new lucene::search::TermQuery(term.d->term);
}

QCLuceneTermQuery::~QCLuceneTermQuery()
{
    // nothing todo
}

QString QCLuceneTermQuery::getClassName()
{
    return TCharToQString(lucene::search::TermQuery::getClassName());
}

QCLuceneTerm QCLuceneTermQuery::getTerm() const
{
    return term;
}


QCLuceneBooleanQuery::QCLuceneBooleanQuery()
    : QCLuceneQuery()
{
    d->query = new lucene::search::BooleanQuery();
}

QCLuceneBooleanQuery::~QCLuceneBooleanQuery()
{
    qDeleteAll(queries);
}

QString QCLuceneBooleanQuery::getClassName()
{
    return TCharToQString(lucene::search::BooleanQuery::getClassName());
}

quint32 QCLuceneBooleanQuery::getClauseCount() const
{
    lucene::search::BooleanQuery *query =
        static_cast<lucene::search::BooleanQuery*> (d->query);

    if (query == 0)
        return 1024;

    return quint32(query->getClauseCount());
}

quint32 QCLuceneBooleanQuery::getMaxClauseCount() const
{
    lucene::search::BooleanQuery *query =
        static_cast<lucene::search::BooleanQuery*> (d->query);

    if (query == 0)
        return 1024;

    return quint32(query->getMaxClauseCount());
}

void QCLuceneBooleanQuery::setMaxClauseCount(quint32 maxClauseCount)
{
    lucene::search::BooleanQuery *query =
        static_cast<lucene::search::BooleanQuery*> (d->query);

    if (query == 0)
        return;

    query->setMaxClauseCount(size_t(maxClauseCount));
}

void QCLuceneBooleanQuery::add(QCLuceneQuery *query, bool required, bool prohibited)
{
    add(query, false, required, prohibited);
}

void QCLuceneBooleanQuery::add(QCLuceneQuery *query, bool delQuery,
                               bool required, bool prohibited)
{
    lucene::search::BooleanQuery *booleanQuery =
        static_cast<lucene::search::BooleanQuery*> (d->query);

    if (booleanQuery == 0)
        return;

    booleanQuery->add(query->d->query, delQuery, required, prohibited);

    if (delQuery) {
        queries.append(query);
        query->d->deleteCLuceneQuery = false;
    }
}


QCLucenePhraseQuery::QCLucenePhraseQuery()
    : QCLuceneQuery()
{
    d->query = new lucene::search::PhraseQuery();
}

QCLucenePhraseQuery::~QCLucenePhraseQuery()
{
    termList.clear();
}

QString QCLucenePhraseQuery::getClassName()
{
    return TCharToQString(lucene::search::RangeQuery::getClassName());
}

qint32 QCLucenePhraseQuery::getSlop() const
{
    lucene::search::PhraseQuery *phraseQuery =
        static_cast<lucene::search::PhraseQuery*> (d->query);

    if (phraseQuery == 0)
        return 0;

    return qint32(phraseQuery->getSlop());
}

void QCLucenePhraseQuery::setSlop(const qint32 slop)
{
    lucene::search::PhraseQuery *phraseQuery =
        static_cast<lucene::search::PhraseQuery*> (d->query);

    if (phraseQuery == 0)
        return;

    phraseQuery->setSlop(int32_t(slop));
}

void QCLucenePhraseQuery::addTerm(const QCLuceneTerm &term)
{
    lucene::search::PhraseQuery *phraseQuery =
        static_cast<lucene::search::PhraseQuery*> (d->query);

    if (phraseQuery == 0)
        return;

    termList.append(term);
    phraseQuery->add(term.d->term);
}

void QCLucenePhraseQuery::addTerm(const QCLuceneTerm &term, qint32 position)
{
    lucene::search::PhraseQuery *phraseQuery =
        static_cast<lucene::search::PhraseQuery*> (d->query);

    if (phraseQuery == 0)
        return;

    termList.insert(position, term);
    phraseQuery->add(term.d->term, int32_t(position));

}

QString QCLucenePhraseQuery::getFieldName() const
{
    lucene::search::PhraseQuery *phraseQuery =
        static_cast<lucene::search::PhraseQuery*> (d->query);

    if (phraseQuery == 0)
        return QString();

    return TCharToQString(phraseQuery->getFieldName());
}

QList<QCLuceneTerm> QCLucenePhraseQuery::getTerms() const
{
    return termList;
}

QT_END_NAMESPACE
