/*
   This file is part of the Nepomuk KDE project.
   Copyright (C) 2007 Sebastian Trueg <trueg@kde.org>

   This library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Library General Public
   License version 2 as published by the Free Software Foundation.

   This library is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   Library General Public License for more details.

   You should have received a copy of the GNU Library General Public License
   along with this library; see the file COPYING.LIB.  If not, write to
   the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
   Boston, MA 02110-1301, USA.
 */

#ifndef _NEPOMUK_SEARCH_TERM_H_
#define _NEPOMUK_SEARCH_TERM_H_

#include <QtCore/QList>
#include <QtCore/QUrl>
#include <QtCore/QSharedDataPointer>

#include <Soprano/LiteralValue>

#include <nepomuk/nepomuk_export.h>


namespace Nepomuk {
    namespace Search {
        class NEPOMUK_EXPORT Term
        {
        public:
            /**
             * Each search term has a type.
             */
            // FIXME: Missing: <, >, <=, >=
            enum Type {
                InvalidTerm,    /**< An invalid term does not do anything */
                LiteralTerm,    /**< A literal term is the simplest form: it just matches a word. */
                AndTerm,        /**< Match all of the subterms. */
                OrTerm,         /**< Match one of the subterms. */
                ContainsTerm,   /**< Match a value inside a field. */
                EqualityTerm,   /**< A field needs to match exactly. \deprecated Use ComparisonTerm */
                ComparisonTerm  /**< A comparision. */
            };

            enum Comparator {
                Equal,
                Greater,
                Smaller,
                GreaterOrEqual,
                SmallerOrEqual
            };

            /**
             * Constructs an invalid term.
             */
            Term();

            /**
             * Copy constructor.
             */
            Term( const Term& other );

            /**
             * Construct a literal term.
             */
            Term( const Soprano::LiteralValue& value );

            /**
             * Construct a ContainsTerm term.
             * \param field A string that will be matched against a field label
             * \param value A value that will be matched against the field value. Unsupported
             *        types are converted to string.
             */
            Term( const QString& field, const Soprano::LiteralValue& value );

            /**
             * Construct a ContainsTerm term.
             * \param field The exact field to match
             * \param value A value that will be matched against the field value. Unsupported
             *        types are converted to string.
             */
            Term( const QUrl& field, const Soprano::LiteralValue& value );

            /**
             * Construct an EqualityTerm term.
             * \param field The exact field to match
             * \param value The resource that should be matched.
             */
            Term( const QUrl& field, const QUrl& resource );

            /**
             * Construct a ComparisonTerm term.
             * \param field The exact field to match
             * \param value A value that will be matched against the field value. Unsupported
             *        types are converted to string.
             * \param comparator The Comparator to use
             */
            Term( const QUrl& field, const Soprano::LiteralValue& value, Comparator comparator );

            /**
             * Destructor
             */
            ~Term();

            /**
             * Assign another term to this one.
             */
            Term& operator=( const Term& other );

            /**
             * Make the term a literal term.
             */
            Term& operator=( const Soprano::LiteralValue& other );

            bool isValid() const;
            Type type() const;
            Soprano::LiteralValue value() const;
            QUrl resource() const;
            Comparator comparator() const;

            // propertyLabel
            QString field() const;
            QUrl property() const;
            QList<Term> subTerms() const;

            void setType( Type );
            void setValue( const Soprano::LiteralValue& );
            void setResource( const QUrl& );

            /**
             * Defaults to Equal
             */
            void setComparator( Comparator );
            void setField( const QString& );
            void setProperty( const QUrl& );
            void setSubTerms( const QList<Term>& );
            void addSubTerm( const Term& );

        private:
            class Private;
            QSharedDataPointer<Private> d; 
        };
    }
}

QDebug operator<<( QDebug, const Nepomuk::Search::Term& );

#endif
