//-----------------------------------------------------------------------------
// 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.
//
//-----------------------------------------------------------------------------
//
// Description:
//      CDEV Resource Name Service Request Object
//
// Author:  Jie Chen
//
//
//
#ifndef _RNS_REQUEST_OBJECT_H
#define _RNS_REQUEST_OBJECT_H

#include <cdevSystem.h>
#include <cdevRequestObject.h>

class rsvcClient;
class rnsService;
class rnsMonitorObj;

class rnsRequestObject: public cdevRequestObject
{
public:
  // constructor and destructor
  rnsRequestObject (char* device,
		    char* msg,
		    rnsService* svc,
		    cdevSystem& system = cdevSystem::defaultSystem());
  ~rnsRequestObject (void);

  int send (cdevData& out, cdevData& result);
  int send (cdevData *out, cdevData& result);
  int send (cdevData& out, cdevData* result);
  int send (cdevData *out, cdevData* result);
  // PURPOSE: Synchronous IO operations 
  // REQUIRE: When do query and get, result must be provided
  // PROMISE: return CDEV_SUCCESS: success. 

  int sendNoBlock (cdevData& out, cdevData& result);
  int sendNoBlock (cdevData* out, cdevData& result);
  int sendNoBlock (cdevData& out, cdevData* result);
  int sendNoBlock (cdevData* out, cdevData* result);
  // PURPOSE: Asynchronous IO operations used in conjunction with
  //	      cdevGroup or system
  // REQUIRE: 
  // PROMISE: return CDEV_SUCCESS: requests have been sent out. 

  int sendCallback (cdevData& out, cdevCallback& callback);
  int sendCallback (cdevData* out, cdevCallback& callback);
  // PURPOSE: Asynchromous IO operations with a user supplied callback function
  // REQUIRE: 
  // PROMISE: User callback function will be called with status information
  //          status = CDEV_DISCONNECTED: channel discconected
  //          status = CDEV_SUCCESS     : everything is OK
  //          status = CDEV_ERROR       : something fishy. 
  //          status = CDEV_INCOMPLETE : data flow will coming (88)
  //          status = CDEV_CBK_FINISHED: query callback finished (89)
  //          status = CDEV_QUERYMSG_ERR: query message syntax erro (91)

  int getState (void);
  // PURPOSE: get connection state
  // REQUIRE: none
  // PROMISE: CDEV_CONNECTED or CDEV_NOTCONNECTED

  const char *className (void) const {return "rnsRequestObject";}

protected:
  // find out action from message
  static int findAction (char* msg, int& action);

  // action value
  typedef enum {GET = 0x2000,QUERY,MONITORON,MONITOROFF,
	       MONITORENTRY, MONITORENTRYOFF, UNKNOWN} RNSENUMVERB;

  // get value callback
  static void getCallback     (int status, void* arg, rsvcData* data);

  // query value callback
  static void queryCallback   (int status, void* arg, rsvcData* data);

  // monitor value callback
  static void monitorCallback (int status, void* arg, rsvcData* data);

  // monitor entry callback
  static void entryCallback   (int status, void* arg, rsvcData* data);

  // data conversion from rsvc to cdev
  static int  dataRsvcToCdev  (rsvcData& data, cdevData& result);

  // data conversion from cdev to rsvc
  static int  dataCdevToRsvc  (cdevData& data, rsvcData& result);

  // remove a monitor object
  int         removeMonitorObject (rnsMonitorObj* mobj);

  // monitor off a callback
  int         monitorOff      (rsvcData& data, rnsMonitorObj* obj);

  // monitor off entry callback
  int         monitorEntryOff (rnsMonitorObj* obj);

  // resend a monitor callback
  int         sendMonitor     (rnsMonitorObj* mobj);

  // resend a monitor entry callback
  int         sendEntryMonitor (rnsMonitorObj* mobj);

private:

  // two tags are needed for all serachs
  static char* stags_[];
  static int   numstags_;

  // action type
  int action_;

  // pointer of underlying client connection
  rsvcClient* client_;

  // friend class
  friend class rnsService;

};
#endif
