/* -*- c++ -*-
 *
 * searchquery.h
 *
 * Copyright (C) 2003-2004 Petter E. Stokke <gibreel@kmldonkey.org>
 * Copyright (C) 2003-2004 Sebastian Sauer <mail@dipe.org>
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 *
 */

#ifndef __libkmldonkey_searchquery_h__
#define __libkmldonkey_searchquery_h__

#include <qstring.h>
#include <qptrlist.h>
#include <kdemacros.h>

class DonkeyMessage;

//! Base class for query operations.
class KDE_EXPORT SearchQuery
{
public:
    enum Operation {
        And = 0,
        Or,
        AndNot,
        Module,
        Keywords,
        MinSize,
        MaxSize,
        Format,
        Media,
        Mp3Artist,
        Mp3Title, // 10
        Mp3Album,
        Mp3Bitrate,
        Hidden
    };

    SearchQuery(Operation op);
    virtual ~SearchQuery();

    Operation operation();
    void setOperation(Operation op);

    //! Returns the SearchQuery as QueryString
    virtual const QString getQuerystring();

    //! Write this query into a DonkeyMessage.
    /*! \param msg The message to write to. */
    virtual void writeQuery(DonkeyMessage& msg);

    //! Returns a SearchQuery matching to the given DonkeryMessage.
    /*! \param msg The DonkeyMessage.
        \return SearchQuery-instance. */
    static SearchQuery* getQuery(DonkeyMessage* msg);

    //! Returns a SearchQuery matching to the given QueryString.
    /*! \param querystring The Querystring (see getQuerystring()).
        \return SearchQuery-instance. */
    static SearchQuery* getQuery(const QString& querystring);

protected:
    Operation Op;
};



//! A base class for queries containing a list of other queries.
class KDE_EXPORT SearchQueryList : public SearchQuery
{
public:
    SearchQueryList(Operation op);

    //! Append a query to the list.
    /*! Queries appended to the query list are owned by the list, and will be freed along with it.
     *  \param q The query to append.
     *  \return A pointer to the list. Useful for code like <tt>query->append(foo)->append(bar)->append(baz)</tt>.
     */
    SearchQueryList* append(SearchQuery* q);

    //! Returns the size of the attached list of queries.
    /*! \return The number of queries in this query list. */
    uint count();
    //! Returns a pointer to the query at a given index in the list.
    /*! \param index The index of the query to retrieve.
     *  \return Pointer to the query at the given index.
     */
    SearchQuery* at(uint index);
    //! Detaches a query from the list.
    /*! This method removes a query from the query list and returns a pointer to it.
     *  When you remove a query, you are responsible for freeing it. The list will no longer take care of this.
     *  \param index The index of the query to detach.
     *  \return The detached query.
     */
    SearchQuery* take(uint index);

    virtual const QString getQuerystring();

    //! Write this query (with its attached queries) into a DonkeyMessage.
    /*! \param msg The message to write to. */
    virtual void writeQuery(DonkeyMessage& msg);

protected:
    const QString toQueryString(const QString& joinstr);

private:
    QPtrList<SearchQuery> queryList;
};



//! A query containing a list of subqueries that must all match.
class KDE_EXPORT QueryAnd : public SearchQueryList
{
public:
    QueryAnd();
    virtual const QString getQuerystring();
};

//! A query containing a list of subqueries of which at least one must match.
class KDE_EXPORT QueryOr : public SearchQueryList
{
public:
    QueryOr();
    virtual const QString getQuerystring();
};

class KDE_EXPORT QueryHidden : public SearchQueryList
{
public:
    QueryHidden();
    virtual const QString getQuerystring();
};


class KDE_EXPORT QueryAndNot : public SearchQuery
{
public:
    QueryAndNot(SearchQuery* q1, SearchQuery* q2);
    ~QueryAndNot();

    SearchQuery* getQueryAnd() { return query1; }
    SearchQuery* getQueryNot() { return query2; }

    virtual const QString getQuerystring();
    virtual void writeQuery(DonkeyMessage& msg);

private:
    SearchQuery *query1, *query2;
};



class KDE_EXPORT QueryModule : public SearchQuery
{
public:
    QueryModule(QString str, SearchQuery* q);
    ~QueryModule();

    const QString& getName() { return string; }
    SearchQuery* getQuery() { return query; }
    virtual const QString getQuerystring();
    virtual void writeQuery(DonkeyMessage& msg);

private:
    QString string;
    SearchQuery* query;
};



class KDE_EXPORT SearchQueryTwoStrings : public SearchQuery
{
public:
    SearchQueryTwoStrings(Operation op, QString str1, QString str2);

    QString getKey() { return s1; }
    void setKey(const QString& key) { s1 = key; }

    QString getValue() { return s2; }
    void setValue(const QString& value) { s2 = value; }

    virtual const QString getQuerystring();
    virtual void writeQuery(DonkeyMessage& msg);

protected:
    QString s1, s2;
};

//! A query that specifies keywords to match.
class KDE_EXPORT QueryKeywords : public SearchQueryTwoStrings
{
public:
    QueryKeywords(QString str1, QString str2);
    virtual const QString getQuerystring();
};

//! A query that defines a minimum file size that must be matched.
class KDE_EXPORT QueryMinSize : public SearchQueryTwoStrings
{
public:
    QueryMinSize(QString str1, QString str2);
    virtual const QString getQuerystring();
};

//! A query that defines a maximum file size that must be matched.
class KDE_EXPORT QueryMaxSize : public SearchQueryTwoStrings
{
public:
    QueryMaxSize(QString str1, QString str2);
    virtual const QString getQuerystring();
};

//! A query that specifies a file format to match.
class KDE_EXPORT QueryFormat : public SearchQueryTwoStrings
{
public:
    QueryFormat(QString str1, QString str2);
    virtual const QString getQuerystring();
};

//! A query that specifies a media type to match.
class KDE_EXPORT QueryMedia : public SearchQueryTwoStrings
{
public:
    QueryMedia(QString str1, QString str2);
    virtual const QString getQuerystring();
};

//! A query that specifies an ID3 artist tag for MP3 files.
class KDE_EXPORT QueryMp3Artist : public SearchQueryTwoStrings
{
public:
    QueryMp3Artist(QString str1, QString str2);
    virtual const QString getQuerystring();
};

//! A query that specifies an ID3 title tag for MP3 files.
class KDE_EXPORT QueryMp3Title : public SearchQueryTwoStrings
{
public:
    QueryMp3Title(QString str1, QString str2);
    virtual const QString getQuerystring();
};

//! A query that specifies an ID3 album tag for MP3 files.
class KDE_EXPORT QueryMp3Album : public SearchQueryTwoStrings
{
public:
    QueryMp3Album(QString str1, QString str2);
    virtual const QString getQuerystring();
};

//! A query that specifies a given MP3 bitrate to match.
class KDE_EXPORT QueryMp3Bitrate : public SearchQueryTwoStrings
{
public:
    QueryMp3Bitrate(QString str1, QString str2);
    virtual const QString getQuerystring();
};

#endif
