/*
    Copyright (c) 2009-2010 Frederik Gladhorn <gladhorn@kde.org>

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
    License as published by the Free Software Foundation; either
    version 2.1 of the License, or (at your option) any later version.

    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
    Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public
    License along with this library.  If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef KNEWSTUFF3_ATTICA_PROVIDER_H
#define KNEWSTUFF3_ATTICA_PROVIDER_H

#include <QtCore/QSet>
#include <QtCore/QPointer>

#include <attica/providermanager.h>
#include <attica/provider.h>

#include "core/provider_p.h"

namespace Attica
{
class BaseJob;
}

namespace KNS3
{
/**
 * @short KNewStuff Attica Provider class.
 *
 * This class provides accessors for the provider object.
 * It should not be used directly by the application.
 * This class is the base class and will be instantiated for
 * websites that implement the Open Collaboration Services.
 *
 * @author Frederik Gladhorn <gladhorn@kde.org>
 *
 * @internal
 */
class AtticaProvider: public Provider
{
    Q_OBJECT
public:
    AtticaProvider(const QStringList &categories);
    AtticaProvider(const Attica::Provider &provider, const QStringList &categories);

    virtual QString id() const;

    /**
     * set the provider data xml, to initialize the provider
     */
    virtual bool setProviderXML(const QDomElement &xmldata);

    virtual bool isInitialized() const;
    virtual void setCachedEntries(const KNS3::EntryInternal::List &cachedEntries);

    virtual void loadEntries(const KNS3::Provider::SearchRequest &request);
    virtual void loadEntryDetails(const KNS3::EntryInternal &entry);
    virtual void loadPayloadLink(const EntryInternal &entry, int linkId);

    virtual bool userCanVote()
    {
        return true;
    }
    virtual void vote(const EntryInternal &entry, uint rating);

    virtual bool userCanBecomeFan()
    {
        return true;
    }
    virtual void becomeFan(const EntryInternal &entry);

private Q_SLOTS:
    void providerLoaded(const Attica::Provider &provider);
    void listOfCategoriesLoaded(Attica::BaseJob *);
    void categoryContentsLoaded(Attica::BaseJob *job);
    void downloadItemLoaded(Attica::BaseJob *job);
    void accountBalanceLoaded(Attica::BaseJob *job);
    void authenticationCredentialsMissing(const Provider &);
    void votingFinished(Attica::BaseJob *);
    void becomeFanFinished(Attica::BaseJob *job);
    void detailsLoaded(Attica::BaseJob *job);

private:
    void checkForUpdates();
    EntryInternal::List installedEntries() const;
    bool jobSuccess(Attica::BaseJob *job) const;

    Attica::Provider::SortMode atticaSortMode(const SortMode &sortMode);

    EntryInternal entryFromAtticaContent(const Attica::Content &);

    // the attica categories we are interested in (e.g. Wallpaper, Application, Vocabulary File...)
    QHash<QString, Attica::Category> mCategoryMap;

    Attica::ProviderManager m_providerManager;
    Attica::Provider m_provider;

    KNS3::EntryInternal::List mCachedEntries;
    QHash<QString, Attica::Content> mCachedContent;

    // Associate job and entry, this is needed when fetching
    // download links or the account balance in order to continue
    // when the result is there.
    QHash<Attica::BaseJob *, QPair<EntryInternal, int> > mDownloadLinkJobs;

    // keep track of the current request
    QPointer<Attica::BaseJob> mEntryJob;
    Provider::SearchRequest mCurrentRequest;

    QSet<Attica::BaseJob *> m_updateJobs;

    bool mInitialized;

    Q_DISABLE_COPY(AtticaProvider)
};

}

#endif
