/***************************************************************************
    smb4ksearch  -  This class searches for custom search strings.
                             -------------------
    begin                : So Apr 27 2008
    copyright            : (C) 2008 by Alexander Reinholdt
    email                : dustpuppy@users.berlios.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.                                   *
 *                                                                         *
 *   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 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 SMB4KSEARCH_H
#define SMB4KSEARCH_H

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

// Qt includes
#include <QObject>
#include <QTimerEvent>
#include <QStringList>
#include <QPair>

// KDE includes
#include <kdemacros.h>
#include <kprocess.h>

// application specific includes
#include <smb4kworkgroup.h>
#include <smb4khost.h>
#include <smb4kshare.h>

/**
 * This class searches for network items (hosts and shares) and returns them.
 * Depending on the settings, it uses nmblookup, smbclient or smbtree.
 *
 * This class belongs to the core of Smb4K.
 *
 * @author Alexander Reinholdt <dustpuppy@users.berlios.de>
 */


typedef QPair<Smb4KHost, bool> HostEntry;

class KDE_EXPORT Smb4KSearch : public QObject
{
  Q_OBJECT

  public:
    /**
     * The constructor.
     *
     * @param parent            The parent of this class
     */
    Smb4KSearch( QObject *parent = 0 );

    /**
     * The destructor.
     */
    ~Smb4KSearch();

    /**
     * Search for a given search item. This can either be a share or a host.
     * The search will be done by default by using Samba's smbtree program.
     * If you provided an IP address, nmblookup will be used automatically.
     *
     * @param string            The search item
     */
    void search( const QString &string );

    /**
     * Abort the search process.
     */
    void abort();

    /**
     * This function reports if the search is running or not.
     *
     * @returns TRUE if the search is running and FALSE otherwise.
     */
    bool isRunning() { return m_working; }

  signals:
    /**
     * This signal emits an Smb4KHost item that matches the search
     * criterion.
     *
     * @param host              The Smb4KHost object
     *
     * @param known             TRUE if the host is known to the application
     *                          and FALSE otherwise
     */
    void result( Smb4KHost *host,
                 bool known );

    /**
     * This signal emits an Smb4KShare item that matches the search
     * criterion.
     *
     * @param share             The Smb4KShare object
     *
     * @param mounted           TRUE if the share is already mounted and FALSE
     *                          otherwise.
     */
    void result( Smb4KShare *share,
                 bool mounted );

    /**
     * This signal emits the run state.
     *
     * @param state         The so-called run state. There are several defined
     *                      in the smb4kdefs.h header file.
     */
    void state( int state );

    /**
     * This signal is emitted when the process finished.
     */
    void finished();

  protected:
    /**
     * Reimplemented from QObject
     */
    void timerEvent( QTimerEvent *e );

  protected slots:
    /**
     * This slot is called when output was received on stderr.
     */
    void slotReadyReadStandardError();

    /**
     * This slot is called when output was received on stdout. It is
     * used to process the search results.
     */
    void slotReadyReadStandardOutput();

    /**
     * This slot is called, when the process exited.
     *
     * @param exitCode           The exit code of the process
     *
     * @param exitStatus         The exit status of the process (@see QProcess::ExitStatus)
     */
    void slotProcessFinished( int exitCode, QProcess::ExitStatus exitStatus );

    /**
     * This slot is invoked when an error occurred with the process.
     *
     * @param errorCode       The error code returned by the process
     */
    void slotProcessError( QProcess::ProcessError errorCode );

    /**
     * Receive the IP address of a host (or for a share) from the IP
     * address scanner.
     *
     * @param host            The Smb4KHost item that carries the IP address.
     */
    void slotReceiveIPAddress( Smb4KHost *host );

  private:
    /**
     * The timer id
     */
    int m_timer_id;

    /**
     * Carries a list of search items that need to be processed
     */
    QStringList m_list;

    /**
     * Already working
     */
    bool m_working;

    /**
     * The process object
     */
    KProcess *m_proc;

    /**
     * Process error
     */
    QProcess::ProcessError m_process_error;

    /**
     * The master browser as reported by smbtree
     */
    Smb4KHost m_master_browser;

    /**
     * The workgroup string
     */
    QString m_workgroup_string;

    /**
     * Was the process aborted?
     */
    bool m_aborted;

    /**
     * Do we need to retry?
     */
    bool m_retry;

    /**
     * The state enumeration
     */
    enum State{ FullSearch,
                IPSearch,
                Idle };

    /**
     * The state
     */
    State m_state;

    /**
     * The list of hosts, that are discovered during one one.
     */
    QList<HostEntry> m_hosts_list;
};

#endif
