/***************************************************************************
 *   Copyright (C) 2004 by Roberto Virga                                   *
 *   rvirga@users.sourceforge.net                                          *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU Library General Public License as       *
 *   published by the Free Software Foundation; either version 2 of the    *
 *   License, or (at your option) any later version.                       *
 *                                                                         *
 *   This program 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 Library General Public     *
 *   License along with this program; if not, write to the                 *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/

#ifndef KBSRPCMONITOR_H
#define KBSRPCMONITOR_H

#include <qmap.h>
#include <qsocket.h>
#include <qstringlist.h>

#include <kurl.h>

#include <kbsboincdata.h>

class KBSBOINCMonitor;

class KBSRPCMonitor : public QObject
{
  Q_OBJECT
  public:
    KBSRPCMonitor(const QString &host, KBSBOINCMonitor *parent, const char *name=0);
    
    virtual bool canRPC() const;
    
    virtual int interval() const;
    virtual void setInterval(int interval);
    
    virtual QString host() const;
    virtual void setHost(const QString &host);
    
    virtual unsigned port() const;
    virtual void setPort(unsigned port);
    
    virtual QString password() const;
    virtual void setPassword(const QString &password);
    
    virtual void quit();
    
    virtual const KBSBOINCMsgs *messages() const;
    virtual const KBSBOINCFileTransfers *fileTransfers() const;
    
    virtual KBSBOINCRunMode runMode() const;
    virtual void setRunMode(KBSBOINCRunMode mode);
    
    virtual KBSBOINCNetworkMode networkMode() const;
    virtual void setNetworkMode(KBSBOINCNetworkMode mode);
    
    virtual void runBenchmarks();
    
    virtual void setProxyInfo(const KBSBOINCProxyInfo &info);
    
    virtual void lookupWebsite(const QString &name);
    
    virtual void getProjectConfig(const KURL &project_url);
    virtual void createAccount(const KURL &project_url, const QString &email,
                               const QString &username, const QString &password);
    virtual void lookupAccount(const KURL &project_url, const QString &email,
                               const QString &username, const QString &password);
    virtual void accountManagerRPC(const KURL &acct_mgr_url,
                                   const QString &login, const QString &passwd);
    
    virtual void attachProject(const KURL &url, const QString &account_key);
    virtual void detachProject(const KURL &url);
    virtual void resetProject(const KURL &url);
    virtual void updateProject(const KURL &url);
    virtual void suspendProject(const KURL &url, bool suspend);
    virtual void extinguishProject(const KURL &url, bool extinguish);
    
    virtual void showGraphics(const KURL &url, const QString &result);
    virtual void abortResult(const KURL &url, const QString &result);
    virtual void suspendResult(const KURL &url, const QString &result, bool suspend);
    
    virtual void abortFileTransfer(const KURL &url, const QString &name);
    virtual void retryFileTransfer(const KURL &url, const QString &name);
    
    virtual void sendCommand(const QDomDocument &command, bool blocking=true);
    
  signals:
    void intervalChanged(int interval);
    
    void updated();
    void runModeUpdated();
    void networkModeUpdated();
    void proxyInfoUpdated();
    void messagesUpdated();
    void fileTransfersUpdated();
    
    void output(const KBSBOINCProjectConfig &config);
    void output(const QString &tag, const QString &account_key);
    void error(const QString &tag, int num, QStringList messages=QStringList());
  
  protected:
    virtual KBSBOINCMonitor *monitor();
    
    virtual void projectCommand(const QString &tag, const KURL &url);
    virtual void resultCommand(const QString &tag, const KURL &url, const QString &result);
    virtual void fileTransferCommand(const QString &tag, const KURL &url, const QString &name);
    
    virtual void getRunMode();
    virtual void getNetworkMode();
    virtual void getMessages();
    virtual void getFileTransfers();
    
    virtual void timerEvent(QTimerEvent *);
  
  private:
    void startConnection();
    void resetConnection();
    
    void sendQueued();
    void sendImmediate(const QDomDocument &command);
    void sendAuth1();
    void sendAuth2();
    
    void massageFileTransfers(KBSBOINCFileTransfers &fileTransfers);
  
  private slots:
    void slotConnected();
    void slotConnectionClosed();
    void slotReadyRead();
    void slotError(int error);

  protected:
    KBSBOINCRunMode m_runMode;
    KBSBOINCNetworkMode m_networkMode;
    KBSBOINCMsgs m_msgs;
    int m_seqno;
    KBSBOINCFileTransfers m_fileTransfers;
  
  private:
    QString m_host;
    QSocket *m_socket;
    enum {Disconnected, Connecting, Idle, Authenticating, Active} m_status;
    int m_interval, m_timer;
    unsigned m_port;
    QString m_password, m_nonce;
    QDomDocument m_command;
    QValueList<QDomDocument> m_blocking;
    QMap<QString,QDomDocument> m_polling;
    QString m_output;
};

#endif
