#ifndef __bugsystem_h__
#define __bugsystem_h__

#include "package.h"
#include "bug.h"
#include "bugdetails.h"
#include "bugcache.h"

#include <qobject.h>
#include <qptrlist.h>
#include <qmap.h>

class BugCommand;

class BugSystem : public QObject
{
    Q_OBJECT
public:
    BugSystem();
    virtual ~BugSystem();

    static BugSystem *self();

    BugCache *cache() { return &m_cache; }

    void retrievePackageList();
    void retrieveBugList( const Package & );
    void retrieveBugDetails( const Bug & );

    // Queue a new command
    void queueCommand( BugCommand * );
    // Return all the commands for a given bug
    QPtrList<BugCommand> queryCommands( const Bug & ) const;
    // Return true if we have a least one command for this bug
    bool hasCommandsFor( const Bug &bug ) const;
    // Send all commands (generate the mails)
    void sendCommands();
    // Forget all commands for a given bug
    void clearCommands( const QString &bug );
    // Forget all commands for all bugs.
    void clearCommands();
    // Return true if any command has been created
    bool commandsPending() const;
    // List all pending commands
    QStringList listCommands() const;

    void saveCommands() const;
    void loadCommands();

    void setDisconnected( bool );
    bool disconnected() const;

    Package::List packageList() const;

    Package package( const QString &pkgname ) const;
    Bug bug( const Package &pkg, const QString &number ) const;

signals:
    void packageListAvailable( const Package::List &pkgs );
    void bugListAvailable( const Package &pkg, const Bug::List & );
    void bugDetailsAvailable( const Bug &, const BugDetails & );

    void packageListLoading();
    void bugListLoading( const Package & );
    void bugDetailsLoading( const Bug & );

    void packageListCacheMiss();
    void bugListCacheMiss( const Package & );
    void bugDetailsCacheMiss( const Bug & );

    void infoMessage( const QString &message );
    void infoPercent( unsigned long percent );

    void commandQueued( BugCommand * );
    void commandCanceled( const QString & );

private slots:
    void setPackageList( const Package::List &pkgs );
    void setBugList( const Package &pkg, const Bug::List &bugs );
    void setBugDetails( const Bug &bug, const BugDetails &details );

private:

    Package::List m_packages;

    // Map package -> list of bugs
    QMap< Package, Bug::List > m_bugs;

    // Map bug -> bug details (i.e. contents of the report)
    QMap< Bug, BugDetails > m_bugDetails;

    // Map bug-number -> list of commands
    typedef QMap< QString, QPtrList<BugCommand> > CommandsMap;
    CommandsMap m_commands;

    bool m_disconnected;

    BugCache m_cache;

    KSimpleConfig *m_commandsFile;

    static BugSystem *s_self;
};

#endif

/*
 * vim:sw=4:ts=4:et
 */
