//-*-c++-*-
/***************************************************************************
 *   Copyright (C) 2003 by Fred Schaettgen                                 *
 *   kbluetoothd@schaettgen.de                                             *
 *                                                                         *
 *   This program 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 2 of the License, or     *
 *   (at your option) any later version.                                   *
 ***************************************************************************/

#ifndef DEVICESCANNER_H
#define DEVICESCANNER_H

#include <qobject.h>
#include <dcopobject.h>
#include <qstringlist.h>
#include <knotifyclient.h>
#include <kapplication.h>
#include <map>
#include <list>
#include <set>
#include <vector>
#include <qdatetime.h>
#include <libkbluetooth/deviceaddress.h>
#include <qguardedptr.h>

class QTimer;
class NeighbourMonitor;
class HciListener;
class KProcess;
class KProcessInheritSocket;
namespace KBluetooth {
    class HciSocket;
    class Inquiry;
}

/**
@author Fred Schaettgen
*/
class DeviceScanner : public QObject, virtual public DCOPObject
{
Q_OBJECT
K_DCOP
k_dcop:
    // Global options
    void reloadJobs();
    QStringList getJobs();
    QString getJobDir();
    QString getJobTemplateDir();
    
    QStringList getPagedDevices();
    bool setPageInterval(QString device, int interval);
    int getPageInterval(QString device);
    bool removePagedDevice(QString label);
        
    void setInquiryInterval(int interval);
    int getInquiryInterval();
    
    // Per-job options
    QStringList getJobDeviceList(QString job);
    bool addJobDevice(QString job, QString device);
    bool removeJobDevice(QString label, QString device);
    
    bool getJobEnabled(QString job);
    bool setJobEnabled(QString job, bool enabled);
    
    bool getUseJobList(QString job);
    bool setUseJobList(QString job, bool bJobList);
    
    bool getIsWhitelist(QString job);
    bool setIsWhitelist(QString job, bool bWhitelist);

    int getJobMinExecInterval(QString job);
    bool setJobMinExecInterval(QString job, int interval);
    
    bool setIntervalNotification(QString job, int interval);
    int getIntervalNotification(QString job);
    
    QStringList getCurrentNeighbours();
    
    bool executeJob(QString job);
    bool configureJob(QString job);

public:
    DeviceScanner(QObject *parent, HciListener *hciListener);
    virtual ~DeviceScanner();
    void start();
    
private:
    struct ScanJob {
        // configuration variables
        QString name;
        QString exe;
        bool enabled;
        std::set<KBluetooth::DeviceAddress> deviceList;
        bool useJobList;
        bool isWhitelist;
        int minExecInterval;
        int intervalNotificationTimeout;
        
        // state variables
        std::set<KBluetooth::DeviceAddress> lastNeighbourSet;
        QDateTime lastExecTime;
    };
    std::map<QString, ScanJob> jobs;
    ScanJob currentlyRunningJob;
    
    int inquiryInterval;
    QDateTime lastInquiryTime;
    std::map<KBluetooth::DeviceAddress, int> pageInterval;
    std::map<KBluetooth::DeviceAddress, QDateTime> lastPageTime;
    
    NeighbourMonitor *neighbourMonitor;
    QDateTime nextUpdateTime;
    QTimer * updateTimer;
    QTimer * jobExecuteTimer;
    QGuardedPtr<KProcessInheritSocket> currentProcess;
        
    bool getProperties(QString label, ScanJob &props);
    void load();
    void store();
    std::vector<KBluetooth::DeviceAddress> strListToAddrList(QStringList strList);
    QStringList addrListToStrList(std::vector<KBluetooth::DeviceAddress> addrList);
    QStringList findJobs();
    void executeJob(QString jobName, ScanJob& job, QString cmd, bool bForceExec = false);
    
signals:
    void neighboursChanged();
    
private slots:
    void findAndExecuteJob();
    void slotUpdate();
    void slotNeighboursChanged();
    void slotProcessExited(KProcess *process);
    void slotProcessStderr(KProcess*, char* msg, int);
    void slotProcessStdout(KProcess*, char* msg, int);

};

#endif
