/*
 *    SCCS ID: %Z%%M% %I% %E% SST 
 *
 *    Copyright (c) 1992-1993 Mark Soloway.  All rights reserved.
 *    See SST_LEGAL_NOTICE file for terms of the license.
 */

#ifndef _TT_MESSAGE_H
#define _TT_MESSAGE_H

#include <desktop/tt_c.h>
#include <rpc/types.h>
#include <rpc/xdr.h>

#include "TTBoolean.h" 
#include "TTGeneric.h" 
#include "TTSharedTypes.h"

class TTMessage;
class TTObjectSpec;
class TTPattern;
class TTSession;

typedef Tt_callback_action (*TTMessageCallback) (TTMessage *);

class TTMessage : public TTGeneric {
public:
  TTMessage (Tt_status&);
  TTMessage (const char *op, Tt_class, Tt_scope, Tt_address, Tt_status&);
  TTMessage (const char *op, Tt_class, Tt_scope, Tt_status&);
  TTMessage (const char *objid, const char *op, Tt_class, Tt_scope, Tt_status&);
  TTMessage (const TTObjectSpec&,
	     const char *op,
	     Tt_class,
	     Tt_scope,
	     Tt_status&);
  TTMessage (const TTMessage&);
  TTMessage &operator= (const TTMessage&);
  ~TTMessage ();

  TTMessage *createSuperClassMessage (Tt_status&) const;

  Tt_status setAddress (Tt_address);
  Tt_status setClass (Tt_class);
  Tt_status setDisposition (Tt_disposition);
  Tt_status setFile (const char *);
  Tt_status setHandler (const char *);
  Tt_status setHandlerPType (const char *);
  Tt_status setObject (const char *);
  Tt_status setObjectSpec (const TTObjectSpec&);
  Tt_status setOp (const char *);
  Tt_status setOType (const char *);
  Tt_status setScope (Tt_scope);
  Tt_status setSenderPType (const char *);
  Tt_status setSession (const char *);
  Tt_status setStatus (int);
  Tt_status setStatusString (const char *);

  Tt_address      getAddress (Tt_status&) const;
  Tt_class        getClass (Tt_status&) const;
  Tt_disposition  getDisposition (Tt_status&) const;
  char           *getFile (Tt_status&) const;
  gid_t           getGID (Tt_status&) const;
  char           *getHandler (Tt_status&) const;
  char           *getHandlerPType (Tt_status&) const;
  char           *getObject (Tt_status&) const;
  TTObjectSpec   *getObjectSpec (Tt_status&) const;
  char           *getOp (Tt_status&) const;
  int             getOpNum (Tt_status&) const;
  char           *getOType (Tt_status&) const;
  TTPattern      *getPattern (Tt_status&) const;
  Tt_scope        getScope (Tt_status&) const;
  char           *getSender (Tt_status&) const;
  char           *getSenderPType (Tt_status&) const;
  char		 *getSendID (Tt_status&) const;
  char           *getSession (Tt_status&) const;
  Tt_state        getState (Tt_status&) const;
  int             getStatus (Tt_status&) const;
  char           *getStatusString (Tt_status&) const;
  uid_t           getUID (Tt_status&) const;

  Tt_status addArg (Tt_mode, const char *, int);
  Tt_status addArg (Tt_mode, const char *, const char *);
  Tt_status addArg (Tt_mode, const char *, const unsigned char *, int);
  Tt_status addArg (Tt_mode, const char *, xdrproc_t, void *);

  Tt_status setArgValue (int, int);
  Tt_status setArgValue (int, const char *);
  Tt_status setArgValue (int, const unsigned char *, int);
  Tt_status setArgValue (int, xdrproc_t, void *);

  Tt_status getArgValue (int, int&) const;
  Tt_status getArgValue (int, char*&) const;
  Tt_status getArgValue (int, unsigned char*&, int&) const;
  Tt_status getArgValue (int, xdrproc_t, void *);

  int getArgsCount (Tt_status&) const;

  Tt_mode        getArgMode (int, Tt_status&) const;
  char          *getArgType (int, Tt_status&) const;
  Tt_value_type  getArgValueType (int, Tt_status&) const;

  Tt_status addContext (const char *name, int);
  Tt_status addContext (const char *name, const char *);
  Tt_status addContext (const char *name, const unsigned char *, int);
  Tt_status addContext (const char *name, xdrproc_t, void *);

  Tt_status getContextValue (const char *, int&) const;
  Tt_status getContextValue (const char *, char*&) const;
  Tt_status getContextValue (const char *, unsigned char*&, int&) const;
  Tt_status getContextValue (const char *, xdrproc_t, void *);

  Tt_value_type getContextValueType (const char *name, Tt_status&) const;

  int   getContextsCount (Tt_status&) const;
  char *getContextName (int, Tt_status&) const;

  // When receiving a message in a callback, the callback function
  // is responsible for deleting the message object is it returns
  // TT_CALLBACK_PROCESSED.

  // NOTE: Message callbacks are not executed unless the TTSession object 
  //       the message is sent by has received the message either
  //       through one of the "waitFor..." member functions, from the reply in
  //       sendSynchronousMessage or by a call to receiveAsynchronousMessage. 
  Tt_status setCallback (TTMessageCallback);

protected:
  // If called with TT_TRUE (by a derived class), the defaultMessageCallback 
  // function is called when the reply to the message is received by
  // the sender.  The defaultMessageCallback can be overridden by the
  // derived class. 
  Tt_status                  useDefaultMessageCallback (TTBoolean);

private:
  TTMessageCallback messageCallback;
  TTBoolean	    sentFlag;
  Tt_message        ttMessage;
  TTBoolean         useDefaultMessageCallbackFlag;

  TTMessage () { setTTMessageDefaults (); }
  TTMessage (Tt_message message)
    {
      setTTMessageDefaults ();
      setMessage (message);
    }

  void       setTTMessageDefaults ();
  Tt_status  refresh ();
  Tt_message getMessage () const;
  void       setMessage (Tt_message);
  void	     setSentFlag (TTBoolean);
  void       copy (const TTMessage&);
  void       destroy ();
  void       checkNewMessage (Tt_status);
  void       initializeOrIncreaseReferenceCount ();
  void       increaseReferenceCount ();
  void       decreaseReferenceCount ();

  virtual Tt_callback_action defaultMessageCallback ();

#ifdef __GNUC__
public:
#endif
  static Tt_callback_action internalMessageCallback (Tt_message,
						     Tt_pattern);

friend class TTPattern;
friend class TTSession;
};

#endif
