/*
 * Copyright (C) 1992 WIlfried Koch, Palanterstr. 46, D-5000 Koeln 41 (Germany)
 * All rights reserved.
 *
 * This software may be freely copied, modified, and redistributed
 * provided that this copyright notice is preserved on all copies.
 *
 * You may not distribute this software, in whole or in part, as part of
 * any commercial product without the express consent of the authors.
 *
 * There is no warranty or other guarantee of fitness of this software
 * for any purpose.  It is provided solely "as is".
 * Initial version.
 */
#ifndef RRLOOPS_H
#define RRLOOPS_H
#include <time.h>
#include <sys/time.h>
#include <stdio.h>	
#include <math.h>
#include "rrconfig.h"
#include "rpcspec.h"
#include "rrpc.h"
#include "netspec.h"
#define ByteCopy bcopy
#define ByteZero bzero

#define NEXTSERVICE				       \
	curserver = curserver->next ?		       \
		 curserver->next : Servers;
#define SQUARESIZE (RRProg.squaresize)
#define STARTFRAME (RRProg.startframe)
#define ENDFRAME   (RRProg.endframe)
#define SCREENMINX (RRProg.minx)
#define SCREENMAXX (RRProg.maxx)
#define SCREENMINY (RRProg.miny)
#define SCREENMAXY (RRProg.maxy)
#define SCREENXSIZE ((SCREENMAXX-SCREENMINX)+1)
#define SCREENYSIZE ((SCREENMAXY-SCREENMINY)+1)
#define SQUARES_IN_X  ((int)(ceil((double)SCREENXSIZE/(float)SQUARESIZE)))
#define SQUARES_IN_Y  ((int)(ceil((double)SCREENYSIZE/(float)SQUARESIZE)))
#define BUSYCHECK FALSE
typedef struct rrserver {
	char *name;
}	RRServer;


typedef struct rrreqlist   {
		RRreq		 rrreq; 
		struct rrreqlist *next;
		struct rrreqlist *prev;
		rpc_square *square;
}	RRreqList;


typedef struct rrconnlist {
		RRConnection conn;
		struct rrconnlist *next;
}	RRConnList;

typedef struct rrserverlist {
		RRServer server;
		char *exestring;
		struct rrserverlist *next;
}	RRServerList;

	
extern RRreqList  	*rrreqo;                /** sorted List of Outstanding requests**/
extern RRreqList  	*rrreqs;                /** List of Send requests              **/
extern RRreqList  	*rrreqr;                /** sorted List of Received requests   **/
extern RRServerList     *Servers;               /** List of available Services         **/
extern RRConnList       *Connects;              /** LIST of Connections                **/

extern int  ServicesInNetwork;
extern int  ServicesOnServer;

typedef enum rrstatus { 
RRSERVICE_SUCCESS,
RRSERVICE_TIMEDOUT,
RRSERVICE_BROKENCONNECTION,
RRSERVICE_UNCONNECTABLE,
RRSERVICE_UNCONTROLLABLE,
RRSERVICE_ARGSMARSHALLED
} RRStatus;

typedef enum tranmeth {
PARSEERROR,			      /* 0 */			
PORTMAPPER_TCPIP_ON_PORTMAPPER_TCPIP, /* 1 */
PORTMAPPER_TCPIP_PORTMAPPER_TCPIP,    /* 2 */
TRANSPORTMETHODEND
} RRTransport;

typedef enum lightweightflags {
	DONOTHING=		0,
	LINE_SEND=		1,
	FRAME_SEND=		2,
	RENDER_SEND=		4,
	LINE_RECEIVED=		8,
	FRAME_BEGIN=		16,
	SCENE_RECEIVED=		32,
	RENDER_BEGIN=  		64,
	REQUEST_TO_SEND=	128,
	REQUEST_TO_ALLOCATE=	256,
	FRAME_RECEIVED=		512,
	REQUEST_SEND=		1024,
	TO_PEND=		2048, 
	EXPECT_SERVICE=		4096,
	SCENE_SEND=		8096
}LWFlags;

typedef int LightWeightMask;

#define SetLWFlag(flag) LWMask |= flag
#define UnSetLWFlag(flag) LWMask &= ~flag


typedef struct lightweight {
	void (*lwfunc)();
	LWFlags flags;
} LightWeightProc;	


extern struct timeval LISTENTIMEOUT;
extern struct timeval TIMEOUT;
extern struct timeval MTIMEOUT;
extern struct timeval REQTIMEOUT;
extern struct timeval RETRYTIMEOUT;
extern struct timeval NOTIMEOUT;
extern struct timeval FORCETIMEOUT;
extern struct timeval FORCERETRYTIMEOUT;


extern char *MyHostname;
extern time_t RRID;

extern void ClientInfo();
extern void GetServers();
extern bool_t ListenCallback();
extern bool_t DoClient();
extern void   RRUnRegisterService();
extern void   RRUnRegisterCallback();
extern void   RRUnRegisterServiceCore();
extern void   RRUnRegisterCallbackCore();
extern void   *RRNewService();
extern void   *RRSquare();
extern int    RRMarshall();
extern int    *RRRequest();
extern void   RRForceWrite();
extern RRConnList *RRFindConnection();
extern RRreqList *FindReqByConn();


extern void RRInitRender();
extern void RRInitFrame();
extern void RRSendRequest();
extern void RRForceRequest();
extern void RRNextRequest();
extern void RRSaveLine();
extern void RRReqAlloc();
extern void RRPend();
extern void RRExpectService();
extern void RRExpectService();
extern void PlotSquare();


typedef struct RRArg {
	u_long RRID;
} RRArg;

typedef struct rrprog {

/** you have to define  this on the server and client side **/
       char     *name;
       bool_t   (*RRxdr_fnct)		( /*XDR *xdrs, pointer to your geometrical situation*/);

/** you have to define on the server side **/
       void     (*RR_fnct)	  	( /* rpc_square *svc   */);

/***** Client side routines ****/
       void	(*RRPlot_fnct)    	( /*   rpc_square *square  */ );
       void	(*RRRefresh_fnct) 	( /*   void */);
       void	(*RRWriteLine_fnct) 	( /*   rpc_Pixel *line, int frame, int lineno, int length */);
       void	(*RRPause_fnct) 	( /*   void */);
/*******************************/

       RRArg     *arg;
       int      argsize;        
       int	minx;
       int      maxx;
       int      miny;
       int      maxy;
       int 	squaresize;
       int      startframe;
       int      endframe;
       char     lateruse [256];
}RRProgStruct;

typedef struct rrline {
	rpc_Pixel *pixels;
	int frame;
	int lineno;
	int lenght;
	struct rrline *prev;
} RRLine;

typedef struct RRArgList {
       RRArg *rrarg;
       struct RRArgList *next;
} RRArgList;

extern RRArgList *RRArgs;
extern rpc_square svc;
extern int ServeAndExit;
extern RRConnection Conn;

extern RRProgStruct RRProg;

#endif /* RRLOOPS_H */

