/* CSL - Common Sound Layer
 * Copyright (C) 2000-2001 Stefan Westerfeld and Tim Janik
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General
 * Public License along with this library; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
 * Boston, MA 02111-1307, USA.
 */
#ifndef __ARTS_MCOP_DISPATCHER_H__
#define __ARTS_MCOP_DISPATCHER_H__

#include <csl/csldefs.h>
#include <csl/artssocket.h>
#include <csl/artsmcopmarshal.h>

#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */


/* --- MCOP Dispatcher structs --- */
typedef enum
{
  ARTS_MCOP_RESULT_VOID,
  ARTS_MCOP_RESULT_LONG,
  ARTS_MCOP_RESULT_FLOAT,
  ARTS_MCOP_RESULT_BYTE,
  ARTS_MCOP_RESULT_BYTE_SEQ,
  ARTS_MCOP_RESULT_BOOLEAN,
  ARTS_MCOP_RESULT_STRING,
  ARTS_MCOP_RESULT_STRING_SEQ,
  ARTS_MCOP_RESULT_OBJECT,
  ARTS_MCOP_RESULT_CUSTOM
} ArtsMcopResultType;

typedef struct
{
  ArtsMcopResultType	result_type : 16;
  unsigned int	    	pending : 1;
  unsigned int	    	completed : 1;	/* !pending && !completed => free */
  unsigned int	    	result_broken : 1;
  union {
    int	            	v_long;
    float           	v_float;
    unsigned char   	v_byte;
    struct {
      unsigned int    	n_bytes;
      unsigned char    *bytes;
    } v_byte_seq;
    CslBool	    	v_boolean;
    char*	    	v_string;
    struct {
      unsigned int  	n_items;
      char            **items;
    } v_string_seq;
    ArtsMcopObjectReference *v_object;
    struct {
      void            *data;
      void*            (*demarshal) (ArtsBinBuffer *buffer);
      void             (*free) (void *data);
    } v_custom;
  } result;
} ArtsMcopRequest;

typedef struct _ArtsMcopDispatcher ArtsMcopDispatcher;
struct _ArtsMcopDispatcher
{
  ArtsSocket              *csock;
  char                    *csl_server_name;
  char                    *arts_server_name;
  char			  *cookie_file;
  unsigned int             state;
  int			   timeout;
  ArtsMcopObjectReference *interface_repo_ref;
  ArtsMcopObjectReference *global_comm_ref;
  int			   global_comm__get;
  ArtsMcopObjectReference *arts_sound_server;
  unsigned int		   n_requests;
  ArtsMcopRequest	  *requests;
};

typedef struct
{
  ArtsMcopDispatcher     *dispatcher;
  int			 object_id;

  int			 method_use_remote;
  int			 method_release_remote;
  int			 method_copy_remote;
} ArtsMcopObject;


ArtsMcopDispatcher*	_arts_mcop_dispatcher_new		(const char		*server_spec,
								 const char		*cookie_file);
void			_arts_mcop_dispatcher_destroy		(ArtsMcopDispatcher	*dispatcher);
unsigned int		_arts_mcop_dispatcher_alloc_request	(ArtsMcopDispatcher	*dispatcher,
								 ArtsMcopResultType	 result_type);
void			_arts_mcop_dispatcher_free_request	(ArtsMcopDispatcher	*dispatcher,
								 unsigned int		 request_id);
CslBool			_arts_mcop_dispatcher_wait_for_result	(ArtsMcopDispatcher	*dispatcher,
								 unsigned int		 request_id);
int			_arts_mcop_dispatcher_lookup_hex_method	(ArtsMcopDispatcher	*dispatcher,
								 int			 object_id,
								 const char		*hex_method_def);
char*			_arts_mcop_dispatcher_global_comm_get	(ArtsMcopDispatcher	*dispatcher,
								 const char		*var_name);
CslBool			_arts_mcop_dispatcher_invoke		(ArtsMcopDispatcher      *dispatcher,
								 ArtsBinBuffer	        *buffer,
								 unsigned int	         request_id);
int			_arts_mcop_dispatcher_setup_invocation	(ArtsMcopDispatcher      *dispatcher,
								 ArtsBinBuffer           *buffer,
								 int                     object_id,
								 int		         method_id,
								 ArtsMcopResultType       result_type);
void			_arts_mcop_dispatcher_setup_oneway_invocation
								(ArtsMcopDispatcher      *dispatcher,
								 ArtsBinBuffer           *buffer,
								 int                     object_id,
								 int		         method_id);
void			_arts_mcop_dispatcher_oneway_invoke      (ArtsMcopDispatcher      *dispatcher,
								 ArtsBinBuffer	        *buffer);

void			_arts_mcop_object_use_remote		(ArtsMcopObject	        *object);
void			_arts_mcop_object_release_remote	(ArtsMcopObject	        *object);
void			_arts_mcop_object_copy_remote		(ArtsMcopObject	        *object);

#ifdef __cplusplus
}
#endif /* __cplusplus */

#endif /* __ARTS_MCOP_DISPATCHER_H__ */
