/*
 * kthread.h 
 *
 * Copyright (C) 1999 Waldo Bastian
 *
 */

#ifndef _KTHREAD_H_
#define _KTHREAD_H_

#include <qobject.h>

class KThreadWorker;
class KThread_data_;

class KThread : QObject
{
  Q_OBJECT
  friend KThreadWorker;
  KThreadWorker *mWorker;
  KThread_data_ *d;
  bool mRunning;
  bool mOk;
  bool mFinished;
  bool mCanceled;
public:
  /**
   * Returns true if actual threads are supported
   *
   * Without thread support this class will behave 
   * according to spec but realtime behaviour will be 
   * sub-optimal.
   **/ 
  static bool supported();


  KThread(KThreadWorker *);
  ~KThread();

  /**
   * Activate the thread
   */
  void start();
  
  /**
   * Stop the thread at the first syncpoint.
   *
   * When the thread is actually canceled
   * the 'canceled' signal is emitted
   *
   * If 'wait' is true, this function
   * does not return before the thread is 
   * either canceled or finished.
   */
  void cancel(bool wait=false);

  /**
   * Wait for 'msec' milliseconds for
   * the thread to finish.
   * 
   * This function returns 'true' if
   * the thread has finished or 'false'
   * when 'msec' miliseconds have passed.
   * 
   * NOTE1: This function can also be used to
   *        wait for a thread which has been canceled.
   */
  bool finish(int msec);

  /**
   * Returns 'true' when thread exited normally 
   */
  bool isFinished() { return mFinished; }

  /** 
   * Returns 'true' when thread was canceled
   */ 
  bool isCanceled() { return mCanceled; }

  /**
   * Returns 'true' when activation of thread was succesfull
   */
  bool isOk() { return mOk; }
  
signals:
  void progress(int);
  void finished();
  void canceled();

protected slots:  
  // For internal use only.
  void slotAttention(int);  
protected:
  // For internal use only.
  void notifyMainThread(char command, bool wait=true);  
};

class KThreadWorker : QObject
{
  Q_OBJECT
  friend KThread;
  KThread_data_ *d;
public:
  KThreadWorker();
  virtual ~KThreadWorker();

  virtual void exec();
  virtual void finished();
  virtual void canceled();

public slots:
  void slotProgress(int);

protected:
  void syncpoint();
  
public:
  // For internal use only.
  void launch();
};

#endif
