/***************************** LICENSE START ***********************************

 Copyright 2012 ECMWF and INPE. This software is distributed under the terms
 of the Apache License version 2.0. In applying this license, ECMWF does not
 waive the privileges and immunities granted to it by virtue of its status as
 an Intergovernmental Organization or submit itself to any jurisdiction.

 ***************************** LICENSE END *************************************/

#ifndef MvTask_DEFINED
#define MvTask_DEFINED

class MvTask;

//! Implements communication with other Metview modules
/*! Most of the methods are private. These are to be used
 *  via friend class MvTask.\n \n
 *  Currently used by PlotMod (and uPlot).
 *  For a simple example, see file \c src/libMetview/Demo.cc
 */
class MvClient {
	friend class MvTask;

	MvTask *Tasks;

	void notify(MvTask *from);

	// No copy
	MvClient(const MvClient&);
	int operator=(const MvClient&);

	//! Callback received when a task has finished
	/*! This is a pure virtual method that needs to be
	 *  implemented in the derived class
	 */
	virtual void endOfTask(MvTask *from) = 0;

	//! Message from task
	virtual void progress(const char*) {};

public:
	//! Constructor
	MvClient();

	//! Destructor
	virtual ~MvClient();

};

typedef void (MvClient::*endOfTaskProc)(MvTask*);


//! Abstract base class for MvServiceTask and MvShellTask
/*! These classes, together with MvClient, implement communication
 *  and sending tasks to other Metview modules.\n \n
 *  Currently used by PlotMod (and uPlot).
 *  For a simple example, see file \c src/libMetview/Demo.cc
 */
class MvTask {

	friend class MvClient;
	MvClient *Client;
	MvTask *Next;
	err     Error;
	Cached  TaskName;

	// No copy
	MvTask(const MvTask&);
	int operator=(const MvTask&);

	// Cannot be delete, call the done() method

	virtual void abort(void) {};


protected:
	void done(void);  // Call when job is done
	void progress(const char*); // Pass info to client
	void setError(err e) { Error = e; }
	virtual ~MvTask();

public:
	//! Constructor, creates a Task and adds it to the clients list
	MvTask(MvClient* client, const char* taskName = 0);

	//! Implements the execution of a task
	/*! This is a pure virtual method that needs to be
	 *  implemented in the derived class
	 */
	virtual void run(void) = 0;

	//! Returns the error/success code
	/*! Type \c err is defined in \c mars.h
	 */
	err getError() 		{ return Error; }

	//! Returns the task name, or "(?)" if name not given
	const char* taskName()  { return TaskName; }
};


#endif

