#ifndef __bugsystem_h__
#define __bugsystem_h__

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

#include <kurl.h>

#include <tqobject.h>
#include <tqptrlist.h>
#include <tqmap.h>
#include <tqpair.h>

class TDEConfig;

class BugCommand;
class BugServer;
class BugServerConfig;
class BugJob;

class BugSystem : public TQObject
{
    TQ_OBJECT
  
    friend class BugJob;
  public:
    BugSystem();
    virtual ~BugSystem();

    static BugSystem *self();

    BugCache *cache()const;
    BugServer *server() const { return mServer; }

    /**
      BugSystem takes ownership of the BugServerConfig objects.
    */
    void setServerList( const TQValueList<BugServerConfig> &servers );
    TQValueList<BugServer *> serverList();

    void setCurrentServer( const TQString & );

    void retrievePackageList();
    void retrieveBugList( const Package &, const TQString &component );
    void retrieveBugDetails( const Bug & );

    /**
     * Load the bugs the user reported himself, or for which he is the assigned to person
     */
    void retrieveMyBugsList();

    /**
      Queue a new command.
    */
    void queueCommand( BugCommand * );
    /**
      Forget all commands for a given bug.
    */
    void clearCommands( const TQString &bug );
    /**
      Forget all commands for all bugs.
    */
    void clearCommands();
    /**
      Send all commands (generate the mails).
    */
    void sendCommands();

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

    Package::List packageList() const;

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

    static void saveQuery( const KURL &url );
    static void saveResponse( const TQByteArray &d );
    static TQString lastResponse();

    void readConfig( TDEConfig * );
    void writeConfig( TDEConfig * );

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

    void packageListLoading();
    void bugListLoading( const Package &, const TQString &component );
    void bugListLoading( const TQString &label );
    void bugDetailsLoading( const Bug & );

    void packageListCacheMiss();
    void bugListCacheMiss( const Package &package );
    void bugListCacheMiss( const TQString &label );
    void bugDetailsCacheMiss( const Bug & );

    void bugDetailsLoadingError();

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

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

    void loadingError( const TQString &text );

  protected:
    BugServer *findServer( const TQString &name );

    void registerJob( BugJob * );

    void connectJob( BugJob * );

    void killAllJobs();

  protected slots:
    void unregisterJob( BugJob * );

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

  private:
    bool m_disconnected;

    BugServer *mServer;

    TQValueList<BugServer *> mServerList;

    TQPtrList<BugJob> mJobs;

    static BugSystem *s_self;

    static TQString mLastResponse;
};

#endif
