/*
 * Copyright 2015 Luca Beltrame <lbeltrame@kde.org>
 *
 * This file is part of Danbooru Client.
 *
 * Danbooru Client 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 3 of the License, or
 * (at your option) any later version.
 *
 * Danbooru Client 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 Danbooru Client. If not, see <http://www.gnu.org/licenses/>.
 */

#ifndef DANBOORUPOST_H
#define DANBOORUPOST_H

/**
 * @brief File containing classes to represent Danbooru posts.
 * @file danboorupost.h
 **/

// Qt

#include <QObject>
#include <QVariant>
#include <QSet>
#include <QXmlStreamAttributes>
#include <QPixmap>

// KDE

#include <QUrl>

// Own

#include "danbooru.h"

namespace Danbooru
{

/**
 * @brief A class representing a Danbooru post.
 *
 * A Danbooru post is an object that models the posts present in a
 * Danbooru board, that is an image with associated information.
 *
 * In particular, posts contain information on the id, size and dimensions
 * of the image, its tags, "preview url" (URL to the thumbnail) and
 * file URL.
 *
 * This is used directly by the DanbooruService class.
 *
 * @author Luca Beltrame (lbeltrame@kde.org)
 *
 * @see DanbooruService, DanbooruPool
 *
 **/
class DanbooruPost : public QObject
{

    Q_OBJECT

    Q_PROPERTY(const QPixmap pixmapData READ pixmap WRITE setPixmap)
    Q_PROPERTY(int id READ id)
    Q_PROPERTY(QUrl fileUrl READ fileUrl)
    Q_PROPERTY(QSet<QString> tags READ tags)
    Q_PROPERTY(QUrl thumbnailUrl READ thumbnailUrl)
    Q_PROPERTY(QUrl sampleUrl READ sampleUrl)

public:

    /**
     * @brief Ratings for a Danbooru item
     *
     * A rating is how appropriate is an item for a general audience.
     *
     **/
    enum Rating {
        Safe = 1, /**< Safe for the general public **/
        Questionable = 2, /**< Might contain hints of risqueness of violence **/
        Explicit = 4 /**< Explicit material **/
    };
    Q_DECLARE_FLAGS(Ratings, DanbooruPost::Rating)
    Q_ENUMS(Rating)

private:

    QPixmap m_pixmap;

    // basic features of a post

    int m_id;
    int m_height;
    int m_width;
    int m_size;

    QUrl m_url;
    QUrl m_thumbnailUrl;
    QUrl m_sampleUrl;
    QSet<QString> m_tags;
    DanbooruPost::Rating  m_rating;

    static const QMap<QString, Rating> RATING_MAP;

    // Private functions

    static const QMap< QString, Rating > initRatingMap();

public:

    /**
     * @brief Construct a Danbooru post from a QVariantMap.
     *
     * This form is the easiest to use and should be used when dealing with
     * responses in JSON format. Unfortunately most Danbooru
     * implementations produce broken JSON for some responses.
     *
     * @param postData A QVariantMap from parsed JSON representing the
     *      data from a single post.
     * @param pixmap A QPixmap pointer to the post thumbnail.
     * @param parent A pointer to the parent QObject.
     *
     **/

    explicit DanbooruPost(QVariantMap postData, QPixmap pixmap = QPixmap(),
                          QObject *parent = 0);

    explicit DanbooruPost(QObject *parent = 0);

    /**
     * @brief Construct a Danbooru post from XML attributes
     *
     * This is an overloaded function which uses XML attributes rather
     * than JSON. It should be used in case the JSON responses aren't
     * complete or broken (for example pools' posts in most Danbooru
     * instances).
     *
     * @param postData A QXmlStreamAttributes instance holding the
     *      attributes for the given post.
     * @param pixmap A QPixmap pointer to the post thumbnail.
     * @param parent A pointer to the parent QObject.
     *
     **/
    explicit DanbooruPost(QXmlStreamAttributes &postData,
                          QPixmap pixmap = QPixmap(),  QObject *parent = 0);

    bool operator==(const DanbooruPost &);

    ~DanbooruPost();

    // Post attributes

    /**
     * @return The ID of the post.
     **/
    int id() const;

    /**
     * @return The height in pixels of the post's image.
     **/
    int height() const;

    /**
     * @return The width in pixels of the post's image.
     **/
    int width() const;

    /**
     * @return The size in bytes of the post's image.
     **/
    int size() const;

    /**
     * @return The URL to the post's image.
     **/
    const QUrl fileUrl() const;

    const QUrl sampleUrl() const;

    /**
     * @return The tags associated to the post.
     **/
    const QSet< QString > tags() const;

    /**
     * @return The URL to the post's thumbnail.
     **/
    const QUrl thumbnailUrl() const;

    /**
     * @return A pointer to the thumbnail's pixmap.
     **/
    QPixmap pixmap() const;

    /**
     * @return The current post's rating.
     **/
    Rating rating() const;

    /**
     * Set the post's pixmap to a specific QPixmap instance's pointer.
     *
     **/
    void setPixmap(const QPixmap &pixmap);

    /**
     * @return A string representation of the post.
     *
     * **/
    const QString toString();

};

Q_DECLARE_OPERATORS_FOR_FLAGS(DanbooruPost::Ratings)

} // namespace Danbooru

Q_DECLARE_METATYPE(Danbooru::DanbooruPost *)
Q_DECLARE_METATYPE(Danbooru::DanbooruPost::Rating)
Q_DECLARE_METATYPE(QSet<QString>)

#endif // DANBOORUPOST_H

