/***************************************************************************
 *   Copyright (C) 2004, 2005 by Johnathan Burchill                        *
 *   jkerrb@users.sourceforge.net                                          *
 *                                                                         *
 *   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 _KDARCONTROLLER_H_
#define _KDARCONTROLLER_H_

#include "controller.h"

#include <kwallet.h>

#include <qfile.h>
#include "qobject.h"
#include <qtextstream.h>

class KDarConfig;
class kdarView;

class createArchiveThread;
class diffArchiveThread;
class isolateArchiveThread;
class listArchiveThread;
class openArchiveThread;
class populateTreeArchiveThread;
class restoreArchiveThread;
class testArchiveThread;

class KWallet::Wallet;
class QEvent;
class QSemaphore;

/**
 * This is the KDar controller class. It controls the libdar operations
 * based on user inputs, and is responsible for passing results on to the main
 * view.
 *
 * @short KDar Controller
 * @author Johnathan Burchill, <jkerrb@users.sourceforge.net>
 * @version VERSION
 */

class KDarController : public controller
{
    Q_OBJECT

public:

    /**
     * Constructor.
     */
    KDarController();
    /**
     * Destructor.
     */
    ~KDarController();

    /**
     *  setParent sets the parent widget
     */
    void setParent( void* );
    /**
     *  closeArchive is a controller method to close an archive
     *  in anticipation of opening a new archive.
     */
    void closeArchive();
    /**
     * Closes the logFile.
     */
    void closeLogFile();
    /**
     *  createArchive is a controller method to create an archive
     *  from filesystem data.
     *
     * @param updateListView whether to update the listView with the
     * reference archive when doing a differential backup. Defaults to true.
     */
    void createArchive( KDarConfig *, bool updateListView = true );

    /**
     *  diffArchive is a controller method to compare an archive
     *  against the filesystem.
     */
    void diffArchive( KDarConfig * );

    /**
     *  isolateArchive is a controller method to isolate an archive
     *  catalog into its own file.
     */
    void isolateArchive( KDarConfig * );

    /**
     *  listArchive is a controller method to initiate listing the
     *  contents of an archive in the browser window (KListView).
     */
    void listArchive( KDarConfig *, bool loadArchive = true );

    /**
     *  openArchive is a controller method to open an archive.
     */
    void openArchive( KDarConfig *, bool updateListView = true );
    /**
     * Opens the logFile for appending.
     */
    void openLogFile( const QString & logFile );
    /**
     *  populateArchiveTree is a controller method to list the contents
     *  of a subdirectory in an archive. It needs to receive a QListViewItem
     */
    void populateArchiveTree( KDarConfig *, QListViewItem * );
    /**
     *  restoreArchive is a controller method to restore the contents
     *  of an archive to the filesystem.
     */
    void restoreArchive( KDarConfig * );
    /**
     *  testArchive is a controller method to test an archive.
     */
    void testArchive( KDarConfig * );
    /**
     *  waitForThread checks to see if the given thread type
     *  is running, and waits for it to finish.
     */
    void waitForThread( controller::threadType );
    /**
     * Writes a message to the logfile.
     */
    void writeLogMessage( QString & message );
    /**
     *  customEvent deals with custom events
     */
    void customEvent( QCustomEvent *e );
    /**
     * Cancel a running thread. Use only with a threadsafe libdar.
     * This method attempts to cancel the first running libdar operation
     * that it finds. Any other running threads will not be cancelled.
     */
     bool cancelOperation();
    /**
     * Opens the KDEWallet for storing and retrieving a password.
     */
    bool openKDEWallet();
    /**
     * Obtain a password from a wallet or the user, and store it temporarily
     * in the controller. The stored password can be retrieved
     * with @ref password(). This password should be cleared from memory
     * with @ref clearPassword() once it is not required.
     */
    bool obtainPassword();
    /**
     * Get the password that is temporarily stored in the controller.
     */
    QString password();
    /**
     * Clear the password from memory.
     */
    void clearPassword();
    /**
     * Change the password that is stored in the wallet
     */
    bool changePassword();
    /**
     * Store a boolean response from user ( for KDarInteraction::pause() )
     *
     * Returns true if successful, false if not (e.g. user cancelled).
     */
    void setUserResponse( const bool );
    /**
     * Get the boolean response from the controller
     * ( for KDarInteraction::pause() )
     */
    bool userResponse();
    /**
     * Returns the pointer to the controller's semaphore object.
     * Use this to put a thread to sleep, and to signal it to wake up.
     */
    QSemaphore * semaphore();

    /**
     * Returns whether libdar supports extended attributes
     */
    bool handlesEA() const;
    /**
     * Returns whether libdar supports largefiles (>2GB) 
     */
    bool handlesLargefiles() const;
    /**
     * Returns whether libdar supports ext2 nodump feature
     */
    bool handlesNoDump() const;
    /**
     * Returns whether libdar uses Special Memory Allocation scheme
     */
    bool usesSpecialAlloc() const;
    /**
     * Returns size of integer type 
     */
    libdar::U_I integerSizeBits() const;
    /**
     * Returns whether libdar is thread-safe
     */
    bool isThreadSafe() const;
    /**
     * Returns whether libdar supports libz compression
     */
    bool handlesZCompression() const;
    /**
     * Returns whether libdar supports libbz2 compression
     */
    bool handlesBZ2Compression() const;
    /**
     * Returns whether libdar supports strong encryption
     */
    bool handlesStrongCrypto() const;

private:

    createArchiveThread *m_createThread;
    diffArchiveThread *m_diffThread;
    isolateArchiveThread *m_isolateThread;
    listArchiveThread *m_listThread;
    openArchiveThread *m_openThread;
    populateTreeArchiveThread *m_populateTreeThread;
    restoreArchiveThread *m_restoreThread;
    testArchiveThread *m_testThread;

    kdarView *m_parent;

    QFile m_logFile;
    QTextStream m_logStream;

    KWallet::Wallet *m_localWallet;
    /** Temporary holding space for a password. **/
    QString m_password;
    /** Temporary holding space for a boolean response from user. **/
    bool m_userResponse;
    QSemaphore *m_semaphore;
    //Libdar's compiled-in capabilities:
    /** Extended Attributes support**/
    bool m_handlesEA;
    /** Largefile support (>2GB) **/
    bool m_handlesLargefiles;
    /** Handles ext2 filesystem nodump flag **/
    bool m_handlesNoDump;
    /** Special memory allocation scheme **/
    bool m_usesSpecialAlloc;
    /** Integer size ( one of 0 ( infinite ), 32, or 64 ) **/
    libdar::U_I m_integerSizeBits;
    /** Thread-safe library **/
    bool m_isThreadSafe;
    /** libz compression support **/
    bool m_handlesZCompression;
    /** libbz2 compression support **/
    bool m_handlesBZ2Compression;
    /** Strong encryption support **/
    bool m_handlesStrongCrypto;

};

#endif // _KDARCONTROLLER_H_
