/*
 *-----------------------------------------------------------------------------
 * Copyright (c) 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.
 *
 *-----------------------------------------------------------------------------
 *
 * Description:
 *	This header file contains the class definitions for the classes
 *	associated with the construction of a script service.
 *
 * Author:  Walt Akers
 *
 *-----------------------------------------------------------------------------
 */

#if !defined (_SCRIPT_SERVICE_H_)
#define _SCRIPT_SERVICE_H_

#include <cdevService.h>
#include "ScriptRequestObject.h"

extern "C" cdevService *newScriptService ( char * name, cdevSystem * system );

class ScriptService : public cdevService
{
friend class ScriptRequestObject;

public:	
	// *********************************************************************
	// * ScriptService::ScriptService :
	// *	This constructor is responsible for performing all service
	// *	initialization.
	// *********************************************************************
	ScriptService ( char * name, cdevSystem & system );

	// *********************************************************************
	// * ScriptService::~ScriptService :
	// *	The destructor is protected to prevent it from being called 
	// * 	directly. The destructor performs any clean-up or shutdown 
	// * 	operations.
	// *
	// *	Returns nothing.
	// *********************************************************************
	~ScriptService ( void );

	// *********************************************************************
	// * ScriptService::installTags :
	// *	Installs the tags that the service and service applications
	// *	will use.  This function is static to allow servers to setup
	// *	the necessary tags without having to instanciate a 
	// * 	ScriptService object.
	// *********************************************************************
	void installTags ( void );	
	
	// *********************************************************************
	// * ScriptService::getRequestObject :
	// *	This is the interface that cdev objects will use to obtain a
	// *	cdevSimpleRequestObject object.  The cdevSimpleRequestObject 
	// *	represents a combined device and message pair that is associated 
	// *	with the ScriptService.
	// *
	// *	Returns CDEV_SUCCESS on success or CDEV_ERROR on error.
	// *********************************************************************
	int getRequestObject (char *, char *, cdevRequestObject * &);

	// *********************************************************************
	// * ScriptService::getFd
	// *	This function will return the list of file descriptors that the
	// *	ScriptService is using.  This will allow the file 
	// *	descriptors to be used in global select and poll calls performed
	// *	at the cdevSystem class level.
	// *
	// *	Returns CDEV_SUCCESS on success or CDEV_ERROR on error.
	// *********************************************************************
	int getFd ( int * &fd, int & numFd );

	// *********************************************************************
	// * ScriptService::flush :
	// *	This function flushes all communications buffers that the 
	// *	service may have open.
	// *
	// *	Returns CDEV_SUCCESS on success or CDEV_ERROR on error.
	// *********************************************************************
	int flush ( void );

	// *********************************************************************
	// * ScriptService::poll :
	// *	This function polls the file descriptors used by the service
	// *	until one of them becomes active or a discrete amount of time
	// *	has expired.
	// *
	// *	Returns CDEV_SUCCESS on success or CDEV_ERROR on error.
	// *********************************************************************
	int poll ( void );

	// *********************************************************************
	// * ScriptService::pend :
	// *	Pends until the named file descriptor (or any file descriptor
	// *	if fd = -1) is ready.  Will pend for no longer than the user
	// *	specified number of seconds.
	// *
	// *	Returns CDEV_SUCCESS on success or CDEV_ERROR on error.
	// *********************************************************************
	int pend ( double seconds, int = -1);

	// *********************************************************************
	// * ScriptService::pend :
	// *	Pends until the named file descriptor (or any file descriptor
	// *	if fd =  -1) is ready.  Will pend forever if the descriptor does
	// *	not become active.
	// *
	// *	Returns CDEV_SUCCESS on success or CDEV_ERROR on error.
	// *********************************************************************
	int pend ( int = -1);

	// *********************************************************************
	// * ScriptService::submit :
	// *	This is the mechanism that the request object will use to submit
	// *	a message to the service.  It is important to note that all of 
	// *	the data provided to this object becomes the property of the 
	// *	service and must not be accessed afterwords.
	// *********************************************************************
	int submit (cdevTranObj &, cdevData &);		

	// *********************************************************************
	// * ScriptService::getNameServer :
	// *	This function should obtain the default name server for this 
	// *	object.  It does nothing for now.
	// *********************************************************************
	int getNameServer(cdevDevice * &ns);

	// *********************************************************************
	// * ScriptService::asyncCallback :
	// *	This method is called in response to a sendNoBlock reply.
	// *********************************************************************
	static void asyncCallbackFunc (int, void *, cdevRequestObject &, cdevData &)
		{
		}

	// *********************************************************************
	// * ScriptService::syncCallback :
	// *	This method is called whenever a send is requested from a 
	// *	ScriptRequestObject.
	// *********************************************************************
	static void syncCallbackFunc ( int status, void *arg, cdevRequestObject &req, cdevData &)
		{
		ScriptRequestObject * sReq     = (ScriptRequestObject *)&req;
		int                   syncCode = (int)arg;
		
		if(syncCode == sReq->syncCode)
			{
			sReq->syncFinished = 1;
			sReq->syncStatus   = status;
			}
		}
protected:
	int                FILENAME_TAG;
	class ScriptList * scripts;
	cdevCallback       asyncCallback;
};

#endif /* _SCRIPT_SERVICE_H_ */
