#ifndef _IDATHRD_
#define _IDATHRD_

/*******************************************************************************
* FILE NAME: IDAThrd.hpp                                                       *
*                                                                              *
* DESCRIPTION:                                                                 *
*   Declaration of the class:                                                  *
*     IDAOnThread - execution of actions in a background thread.               *
*     IDAOnThreadAction - action to execute on background thread               *
********************************************************************************
*                                                                              *
*   Each action to be executed on a background thread is created by            *
*   deriving a class from the ABC IDAOnThreadAction.                           *
*                                                                              *
*   Sending notifications from the background is handled automatically         *
*   by any class inheriting from this thread.  If an object does not inherit   *
*   from this class, it must override it's notifyObserver methods to check     *
*   whether this object needs to process the message first (to send it         *
*   to the foreground).                                                        *
*                                                                              *
*   eventData must be persistent - it cannot be automatic (eg: an exception).  *
*   Automatic data on the stack does not remain allocated when an exception is *
*   passed to the foreground.                                                  *
*                                                                              *
*   Objects that do not share this IDAOnThread object cannot be updated        *
*   directly if they will send a notification.  It is safe to update objects   *
*   that have no observers or for which notifications are disabled.            *
*                                                                              *
*******************************************************************************/

/***********************************************

    Licensed Materials - Property of IBM

    5622-880   5801-AAR

    (c) Copyright IBM Corp 1991, 1996.

************************************************/

#ifndef _IDAENV_
#include <idaenv.hpp>
#endif

#ifndef _IDSEXC_
#include <idsexc.hpp>
#endif

#ifndef _ISTDNTFY_
#include <istdntfy.hpp>
#endif

#ifndef _IREFCNT_
#include <irefcnt.hpp>
#endif

/*----------------------------------------------------------------------------*/
/* Align classes on four byte boundary.                                       */
/*----------------------------------------------------------------------------*/
#pragma pack(4)

//*****************************************************************************
// Class definition for IDAOnThreadAction (base class for onThread action)
//*****************************************************************************
class DAX_IMPORTEXPORT IDAOnThreadAction : public IRefCounted
{
  public:
    //---------------------------------------------------------------------------
    // Constructors / destructors
    //---------------------------------------------------------------------------
    // owner is notifier who should send any exception notification
    IDAOnThreadAction(IStandardNotifier* anOwner);
  public:
    IStandardNotifier* owner() { return iOwner; }
    // Override with method to execute in the background
    virtual void execute() = 0;
    // Override these methods for foreground action when
    // backgound execute is complete.  Only one or the other
    // is called.  An exception notification is always sent
    // if an exception occurs
    virtual void executeComplete() {}
    virtual void executeCompleteException() {}
  protected:
    // as this is a reference counted class
    ~IDAOnThreadAction();
    IStandardNotifier* iOwner;
};   //IDAOnThreadAction

//*****************************************************************************
// shorthand OnThread action reference creation
//*****************************************************************************
typedef IReference<class IDAOnThreadAction> IDAActionReference;

//*****************************************************************************
// Class definition for IDAOnThread (base class for onThread handler)
//*****************************************************************************
class DAX_IMPORTEXPORT IDAOnThread : public IStandardNotifier
{
  friend class BackgroundNotifier;
  friend class BackgroundObserver;
  public:
    //---------------------------------------------------------------------------
    // Constructors / destructors
    //---------------------------------------------------------------------------
    // specify the owner if IDAOnThread used via composition vs derivation
    // this allows busyId changes to be notified to the owner's observers
    IDAOnThread( IStandardNotifier* anOwner = 0 );
    virtual ~IDAOnThread();
    //---------------------------------------------------------------------------
    // public member functions
    //---------------------------------------------------------------------------
    Boolean isBusy() const;
    void setBusy(Boolean newBusy = True);
    // throws an exception if busy is true, else busy = newBusy
    void exceptIfBusy(Boolean newBusy = False);
    // execute the defined action in a background thread
    virtual void executeOnThread(IReference<class IDAOnThreadAction> anAction);
    // returns true if called from the background thread of this object
    Boolean isBackground() const;
    // Sends a notification to the observers of the owner
    // Override the owner notification methods to call these when you are
    // using composition (rather than deriviation) to use this part.
    // See the overrides below, called when this class is used via derivation.
    // When using derivation, do not use the notifyObserversOf methods.
    virtual IDAOnThread& notifyObserversOf( IStandardNotifier* owner
                                          , const INotificationEvent& anEvent );
    virtual IDAOnThread& notifyObserversOf( IStandardNotifier* owner
                                          , const INotificationId& anId );
    // overridden to add background thread support for derivation
    virtual IDAOnThread& notifyObservers( const INotificationEvent& event )
    {
      notifyObserversOf( this, event );
      return *this;
    }
    //---------------------------------------------------------------------------
    // public member data
    //---------------------------------------------------------------------------
    static const INotificationId busyId;
    static const INotificationId iExceptionOccurredId;
  protected:
    // overridden to add background thread support for derivation
    virtual IDAOnThread& notifyObservers( const INotificationId& id )
    {
      notifyObserversOf( this, id );
      return *this;
    }
    // called in background thread to execute action
    virtual void executeInBackground();
    // called in foreground thread when action complete
    virtual void executeComplete(Boolean exceptionOccurred);
  private:
    void initializePart();
    Boolean iBusy;
    IReference<class IDAOnThreadAction> iAction;
    class BackgroundNotifier* iBackgroundNotifier;
    class BackgroundObserver* iBackgroundObserver;
    IStandardNotifier* iOwner;
    class IThread* iThread;
};   //IDAOnThread

/*----------------------------------------------------------------------------*/
/* Resume compiler default packing.                                           */
/*----------------------------------------------------------------------------*/
#pragma pack()

#endif
