/****************************************************************************
**
** Copyright (C) 2012 Róbert Márki
**
** This file is part of Web Feeds.
**
** Web Feeds 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.
**
** Web Feeds 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 Web Feeds.  If not, see <http://www.gnu.org/licenses/>.
****************************************************************************/

#ifndef ABSTRACTFEEDAGGREAGATORSERVICE_H
#define ABSTRACTFEEDAGGREAGATORSERVICE_H
#include <QObject>
#include <QList>
#include <QSet>
#include <pageitem.h>
#include <QtPlugin>
#include <QDeclarativeImageProvider>
#include <QMetaObject>
#include <QMetaProperty>
#include <QSettings>
#include "applicationsettings.h"
#include "webserviceclient.h"
#include "pageitem.h"

class AbstractFeedAggreagatorService : public QObject, public QDeclarativeImageProvider
{
    Q_OBJECT
public:
    explicit AbstractFeedAggreagatorService(QObject *parent = 0);
    virtual ~AbstractFeedAggreagatorService();

    virtual void enable(PageItemPtr parentItem) = 0;
    virtual void disable() = 0;
    virtual QString serviceId() const = 0;
    QString imageUrl(const QString& imageId) const;
    virtual QStringList menuItems(PageItemPtr item) const = 0;
    virtual QStringList contextMenuItems(PageItemPtr item) const = 0;
    virtual bool isItemAcceptable(PageItemPtr item);
    virtual QSet<QString> customItemTypeProperties() const;
    void setApplicationSettings(ApplicationSettings* settings);

public slots:
    Q_INVOKABLE virtual QString servicePageUrl() const = 0;
    Q_INVOKABLE virtual QString authenticationSheet() const = 0;
    Q_INVOKABLE virtual QString serviceName() const = 0;
    Q_INVOKABLE virtual QString serviceImageUrl() const = 0;
    Q_INVOKABLE virtual bool isAuthenticationDataSet() const = 0;
    Q_INVOKABLE virtual void clearAuthenticationData() = 0;
    Q_INVOKABLE virtual PageItem* rootItem() const = 0;

private:
    ApplicationSettings* m_settings;
    mutable QSettings* m_pluginSettings;    
    QMultiHash<PageItemWeakRef, WebServiceReplyWeakRef> m_runningRequests;
    QMultiHash<WebServiceReplyWeakRef, QPair<QWeakPointer<QObject>,QString>  > m_busyProperties;

protected:
    QSettings* pluginSettings() const;
    void clearPluginSettings();
    ApplicationSettings* applicationSettings() const;
    template <class T>
    static QSet<QString> itemTypeProperties()
    {
        QSet<QString> ret;
        const QMetaObject metaPageItem = T::staticMetaObject;
        for(int i = metaPageItem.propertyOffset(); i < metaPageItem.propertyCount(); ++i)
        {
            ret << metaPageItem.property(i).name();
        }
        return ret;
    }
    void addRequest(PageItemPtr relatedItem, WebServiceReplyWeakRef reply);
    void removeRequest(WebServiceReplyWeakRef reply);
    void assingBusyPropertyToRequest(WebServiceReplyWeakRef reply, QSharedPointer<QObject> object, const QString &propertyName);
    bool isRequestRunning(int requestType, PageItemPtr relatedItem = PageItemPtr()) const;
    PageItemPtr relatedItem(WebServiceReplyWeakRef reply);
    WebServiceReplyWeakRef relatedReply(PageItemPtr item, int requestType);
    void abortRequest(int type = 0,
                      WebServiceReply::Role role = WebServiceReply::RlUndefined,
                      PageItemPtr relatedItem = PageItemPtr());
    void abortAllRequests();
    void registerItem(PageItemPtr item, bool recursive = false);

protected slots:
    virtual void onItemActivated(PageItemPtr item);
    virtual void onItemDeactivated(PageItemPtr item);
    virtual void onMoreChildrenRequested(PageItemPtr parentItem);

private slots:
    void onActivityStatusChanged(PageItemPtr item, bool active);

signals:
    void authenticationDataChanged(AbstractFeedAggreagatorService*);
    void filterChanged();
};
Q_DECLARE_INTERFACE(AbstractFeedAggreagatorService, "com.webfeeds.feedaggregatorservice")
#endif // ABSTRACTFEEDAGGREAGATORSERVICE_H
