/* -----------------------------------------------------------------------------
 * Copyright (c) 1994,1995 Southeastern Universities Research Association,
 *                         Continuous Electron Beam Accelerator Facility
 *
 * This software was developed under a United States Government license
 * described in the NOTICE file included as part of this distribution.
 *
 * -----------------------------------------------------------------------------
 *
 * cdevGrpCollectionRequest.h : This class is used to collect the results that
 *                              are generated by numerous service-specific
 *                              cdevCollectionRequest objects.  When all of the
 *                              component collections have responded to this 
 *                              object, the data will be consolidated and
 *                              returned to the caller.
 *
 * Author:  Walt Akers
 *
 * Revision History:
 *   cdevGrpCollectionRequest.h,v
 * Revision 1.1  1996/11/12  20:32:34  akers
 * New collection device source code
 *
 * -----------------------------------------------------------------------------
 */
#ifndef _CDEV_GRP_COLLECTION_REQUEST_H
#define _CDEV_GRP_COLLECTION_REQUEST_H

#include <cdevCollectionRequest.h>

class CDEV_CLASS_SPEC cdevGrpCollectionRequest: public cdevCollectionRequest
{
friend class cdevCollectionRequest;

public:
	// *********************************************************************
	// * This structure is provided as the void * argument to the default
	// * callback whenever the synchronous send is used.  The checkSum is
	// * used to detect if the result returned after the send method stopped
	// * waiting for it.
	// *********************************************************************
	typedef struct
		{
		int       completionCode;
		int       finished;
		cdevData *data;
		} SendStatus;

	// *********************************************************************
	// * These methods get state and access information for the underlying
	// * cdevRequestObjects.
	// *********************************************************************
	virtual int getState (void);
	virtual int getAccess (void);

	// *********************************************************************
	// * This method sets the context of each of the underlying 
	// * cdevRequestObjects.
	// *********************************************************************
	virtual int setContext (cdevData &ctx);

	// *********************************************************************
	// * send : 
	// *	The send interface is used to provide synchronous I/O with the
	// *	service.
	// *
	// *	Returns CDEV_SUCCESS on success or CDEV_ERROR on error.
	// *********************************************************************
	virtual int send ( cdevData & in, cdevData & out ) 
		{ return send(&in, &out); }
	virtual int send ( cdevData * in, cdevData & out ) 
		{ return send(in, &out);  }
	virtual int send ( cdevData & in, cdevData * out ) 
		{ return send(&in, out);  }
	virtual int send ( cdevData * in, cdevData * out );

	// *********************************************************************
	// * sendNoBlock :
	// *	The sendNoBlock interface is used in conjunction with cdevGroup
	// *	or cdevSystem to execute a series of operations.  
	// *
	// *	Returns CDEV_SUCCESS on success or CDEV_ERROR on error.
	// *********************************************************************
	virtual int sendNoBlock (cdevData & in, cdevData & out) 
		{ return sendNoBlock(&in, &out); }
	virtual int sendNoBlock (cdevData * in, cdevData & out) 
		{ return sendNoBlock(in, &out); }
	virtual int sendNoBlock (cdevData & in, cdevData * out) 
		{ return sendNoBlock(&in, out); }
	virtual int sendNoBlock (cdevData * in, cdevData * out);
		
	// *********************************************************************
	// * sendCallback :
	// *	The sendCallback interface provides asynchronous communications
	// *	with the service. 
	// *
	// *	Returns CDEV_SUCCESS on success or CDEV_ERROR on error.
	// *********************************************************************
	virtual int sendCallback (cdevData & in, cdevCallback & callback) 
		{ return sendCallback(&in, callback); }
	virtual int sendCallback (cdevData * in, cdevCallback & callback);

	// *********************************************************************
	// * This method returns the name of the class.
	// *********************************************************************
	const char *className (void) const {return "cdevGrpCollectionRequest";}

protected:
	// *********************************************************************
	// * These are the protected constructor and destructor for this object.
	// *********************************************************************
	cdevGrpCollectionRequest (char **devices, int nDevices, char *msg, cdevSystem& sys);
	virtual ~cdevGrpCollectionRequest (void);
			
	// *********************************************************************
	// * This is the syncCallback method.  It will be used by the send
	// * method in order to detect the completion of the operation.
	// *********************************************************************
	static void syncCallback (int status, void * user, cdevRequestObject &, cdevData &data);

	// *********************************************************************
	// * This callback function is used to receive the individual callbacks
	// * from the underlying cdevRequestObjects and is used by sendCallback.
	// *********************************************************************
	static void asyncCallback (int, void *, cdevRequestObject &, cdevData &);		

	// *********************************************************************
	// * This is the asyncNoBlockCallback method.  It will be used by the 
	// * sendNoBlock method in order to detect the completion of the 
	// * operation.
	// *********************************************************************
	static void asyncNoBlockCallback (int status, void * user, cdevRequestObject &, cdevData &data);
			
private:
	static SendStatus sendStatus;
	static int        sendCheckSum;
	
	// *********************************************************************
	// * These are the cdevCollectionRequest objects that are addressed by 
	// * each call to this cdevGrpCollectionRequest.  The nCollections 
	// * variable contains the number of cdevRequestObjects that are 
	// * represented.
	// *********************************************************************
	cdevCollectionRequest **collections;
	int                     nCollections;

	// *********************************************************************
	// * This is a table of integers that identifies the order in which
	// * results from the incoming collections should be distributed to 
	// * the outbound data.
	// *********************************************************************
	int * requestOrder;
	int   nRequests;
	
	// *********************************************************************
	// * This is the master data structure.  It contains no actual data, 
	// * however, it identifies the data structure that should exist when 
	// * the request has been executed.
	// *
	// * This structure is inspected and updated at the completion of each
	// * callback, and is used to initially create the cdevData objects that
	// * are used for interim data storage.
	// *********************************************************************
	cdevData format;
};

#endif
