/****************************************************************************
**
** 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 FEEDLISTPAGEITEM_H
#define FEEDLISTPAGEITEM_H
#include <QVariant>
#include <QMetaObject>
#include <QSharedPointer>
#include <QWeakPointer>
#include <QDateTime>
#include <QStringList>

class PageItem;
typedef QSharedPointer<PageItem> PageItemPtr;
typedef QWeakPointer<PageItem> PageItemWeakRef;
class AbstractFeedAggreagatorService;
class PageItem : public QObject
{
    Q_OBJECT

    Q_PROPERTY(bool active READ isActive WRITE setActive NOTIFY activityChanged)
    Q_PROPERTY(int childCount READ childCount NOTIFY childCountChanged)
    Q_PROPERTY(PageItem* parent READ parent NOTIFY parentChanged)
    Q_PROPERTY(QString title READ title NOTIFY titleChanged)
    Q_PROPERTY(QString iconSource READ iconSource NOTIFY iconSourceChanged)
    Q_PROPERTY(QString itemId READ itemId)
    Q_PROPERTY(bool enabled READ isEnabled)
    Q_PROPERTY(bool busy READ isBusy WRITE setBusy NOTIFY busyChanged)
    Q_PROPERTY(bool childrenBusy READ childrenBusy WRITE setChildrenBusy NOTIFY childrenBusyChanged)
    Q_PROPERTY(AbstractFeedAggreagatorService* service READ service NOTIFY serviceChanged)

public:
    PageItem(PageItemPtr parent = PageItemPtr(), AbstractFeedAggreagatorService* service = 0);
    ~PageItem();
    void setService(AbstractFeedAggreagatorService* service);

    void insertChildren(int row, const QList<PageItemPtr> &children);
    void appendChildren(const QList<PageItemPtr> &children);
    void prependChildren(const QList<PageItemPtr> &children);
    void insertChild(int row, PageItemPtr childItem);
    void appendChild(PageItemPtr childItem);
    void prependChild(PageItemPtr childItem);
    void removeChild(PageItemPtr childItem);
    QStringList childItemIds() const;

    Q_INVOKABLE PageItem* child(int row);
    PageItemPtr childItem(int row) const;
    PageItemPtr childItem(const QString& itemId) const;
    QList<PageItemPtr> children(const QString& itemId) const;
    QList<PageItemPtr> childItems() const;
    void setChildItems(const QList<PageItemPtr>& children);
    void clearChildItems();
    bool contains(const QString& itemId) const;
    Q_INVOKABLE int childCount() const;
    int row() const;
    PageItem* parent() const;
    PageItemWeakRef parentItem() const;
    bool isActive() const;
    void setActive(bool active = true);
    bool canFetchMore() const;
    void setCanFetchMore(bool canFetchMore);
    void loadMoreChildren();

    QString title() const;
    void setTitle(const QString& title);
    QString itemId() const;
    void setItemId(const QString& itemId);
    bool isEnabled() const;
    void setEnabled(bool enabled = true);
    bool isBusy() const;
    void setBusy(bool busy);
    bool childrenBusy() const;
    void setChildrenBusy(bool busy);
    QString iconSource() const;
    void setIconSource(const QString& source);

public slots:
    Q_INVOKABLE AbstractFeedAggreagatorService* service() const;    
    void showMessage(const QString& message);

private:
    AbstractFeedAggreagatorService* m_service;
    QMultiHash<QString, PageItemPtr> m_childItemIdHash;
    PageItemWeakRef m_parentItem;
    bool m_active;
    bool m_canFetchMore;
    QString m_title;
    QString m_iconSource;
    QString m_itemId;
    bool m_enabled;
    bool m_busy;
    bool m_childrenBusy;    

    void setParent(PageItemPtr parent);
    void setParent(QObject *parent);

private slots:
    void onAboutToBeRemovedFromParent();

protected:
    QList<PageItemPtr> m_childItems;

signals:
    void activityChanged();
    void activityStatusChanged(PageItemPtr item, bool active);
    void aboutToInsertChildren(PageItemPtr parent, int start, int end);
    void aboutToRemoveChildren(PageItemPtr parent, int start, int end);
    void childrenInserted(PageItemPtr parent);
    void childrenRemoved(PageItemPtr parent);
    void moreChildrenRequested(PageItemPtr parent);
    void dataChanged(PageItemPtr);
    void childrenDataChanged(PageItemPtr);
    void serviceMessage(QString message);
    void serviceChanged();
    void aboutToBeRemovedFromParent();

    void titleChanged();
    void busyChanged();
    void childrenBusyChanged();
    void childCountChanged();
    void parentChanged();
    void iconSourceChanged();
};
Q_DECLARE_METATYPE(PageItemPtr)
Q_DECLARE_METATYPE(PageItemWeakRef)

inline uint qHash(const PageItemWeakRef& item)
{
    return qHash(item.data());
}
#endif // FEEDLISTPAGEITEM_H
