#ifndef _ROBOTSIM_H_
#define _ROBOTSIM_H_

#include <stdio.h>

#include "../h/cdefs.h"
#include "../h/robotTypes.h"
#include "../h/robot_jls.h"

#include "serialDev.h"
#include "linkedList.h"
#include "grf4.h"

#define MAX_LIGHTS 8

typedef struct simFxnDesc {
	char *name;
	int (*fxn)();
	int arg;
	void *ptr;
} SimFxnDesc;

typedef struct locFxnDesc {
	char *name;
	TRSF *(*fxn)(/* TRSF*, int, int, void* */);
	int com;
	int arg;
	void *ptr;
} LocFxnDesc;

typedef struct material {
	struct material *next;
	char *name;
	MATERIAL_DEF def;
	void *ptr;
} MaterialDesc;

typedef struct light {
	struct light *next;
	float x, y, z, w;
	unsigned long color;
	unsigned long ambient;
	int num;
	void *ptr;
} LightDesc;

typedef struct object {
	struct object *next;
	char *name;
	struct object *sons;
	struct object *sibs;
	Grf4Object *go;
	TRSF *loc;
	LocFxnDesc *locfxn;
	MaterialDesc *matdef;
	void *mat;
} ObjectDesc;

typedef struct {
	char *simname;
	int accrcisock;
	int regsock;
	int rcisock;
	int oobsock;

	int readCount;
	int writeCount;
	
	int (*sig1Fxn)();
	int (*sig2Fxn)();
	int sig1Arg;
	int sig2Arg;

	int useSigIO;
	int error;
} HostIO;

typedef struct {
	int rcount;
	int wcount;

  	char *rbuf;
	int rsize;
	char *wbuf;
	int wsize;
	int active;
  } SLUINFO;

typedef struct {

#define POSITION	0x1
#define CURRENT		0x2
#define HOLD		0x3
	int com[MAXJNTS];
	int ctrl[MAXJNTS];
	int stat[MAXJNTS];
	int mode[MAXJNTS];
	int setp[MAXJNTS];
	int enc[MAXJNTS];
	int commandRate;
	int servoRate;
	int baseClkRate;
	float angles[MAXJNTS];
	int encOffsets[MAXJNTS];
	int power;
	int handPos;
	int handForce;

	TRSF tool;
	FORCE extForce;
	DIFF extPosErr;
	float mtorque[MAXJNTS];
	float gravload[MAXJNTS];
	int jDACvalues[MAXJNTS];

	int errorCode;

} RobotState;

typedef struct {

	/* generic devices */

	int numSlu;		/* no. serial line units available */
	int numPioIn;		/* no. parallel input ports avail. */
	int numPioOut;		/* no. parallel output ports avail. */
	int numDAC;		/* no. DAC channels available */
	int numADC;		/* no. ADC channels available */

	SLU *sluBuf;
	unsigned short *pioOutBuf;
	unsigned short *pioInBuf;
	int *DACBuf;
	int *ADCBuf;

	/* special devices */

	int forceAvail;		/* force sensor available */
	int torqueAvail;	/* torque senors available */
	int teleopAvail;	/* teleop data available */
	int jstickAvail;	/* joystick available */
	int potsAvail;		/* potentiometers available */
	int pendantAvail;	/* teach pendant available */

	int forceOn;		/* force being read */
	float forceTscale;	/* translation force measurement scale */
	float forceRscale;	/* rotation force measurement scale */
	
	int torqueOn;		/* torque being read */
	int teleopOn;		/* teleop being read */
	int teleopBuf[6];	
	int jstickOn;		/* joy stick being read */
	int jstickBuf[6];

#define PDNT_VBUFSIZE		3
#define PDNT_TICK_SET		0x01

	int pendantOn;		/* pendant being read */
	unsigned short pendantWBuf;
	unsigned short pendantVBuf[PDNT_VBUFSIZE];

	int pendantFlags;
	int pendantSpeed;
	void *pendantButPtr;
	
} SensorIO;

typedef struct {
	int moperID;		/* moper ID number */
	int robotID;		/* robot ID number */

	unsigned short integration;	/* integration mode bit mask */
	unsigned short calibMode;	/* calibration mode bit mask */
	
	unsigned short markFound;	/* zero index mark found mask */
	unsigned short oldMarkFound;    /* previous value of 'markFound' */
	short calibrated;		/* "robot is calibrated" flag */

	int torqueRead;		    	/* program reading torque values */
	int potRead;		        /* program reading pot values */
	int pendantRead;		/* program reading teach pendant */
	int jstickRead;		        /* program reading joy stick */
	int forceRead;		        /* program reading forces */
	int teleopRead;		        /* program reading forces */
	int testRead;			/* program reading test data */

	char adcOpen[12];
	char sluOpen[2];

	short jmode[MAXJNTS];

	unsigned short jstat[MAXJNTS];	/* for debugging */
	short encread[MAXJNTS];		
	short encset[MAXJNTS];	

	int opFlags;			    /* set in moperx.c */
	int rbtError;
	int errorLoc;

	int interval;
	int offset;
	int maxRunReqs;
	int intervalJustSet;
	int clockRate;	/* instantiated by clockSetup() */
	int jointRate;	/* instantiated by getJointRate() */

} CtrlState;

typedef struct groupDesc {
	struct groupDesc *next;
	long code;
	long active;
	ListDesc robots;
	int interval;
	int cycleCnt;
	ListElem *event;
} GroupDesc;

typedef struct {
	FILE *clf;
	FILE *jlf;
	char *clfName;
	char *jlfName;
	int matlabFormat;
	float *initAngles;
	int nocal;

	int active;
	int softError;
	int hardError;
	int hardErrLoc;

	int numCycles;
	int realTime;
	int exchangeNumber;

	int num;
	long code;

	GroupDesc *gd;

} SimState;	  

typedef struct robotDesc {
	struct robotDesc *next;

	char *name;
	int class;
	int rbtID;
	JLS *jls;
	KYN *kyn;
	void *var;

	RobotState rs;
	CtrlState cs;
	SensorIO sio;
	HostIO hio;
	SimState ss;

	int hasEndEffector;
	struct object *endEffector;
	TRSF *loc;
	LocFxnDesc *locfxn;
	TRSF L[MAXJNTS+1];
	void *rgp;	/* robot graphics pointer */

	int configured;
} RobotDesc;


typedef struct staticRobotDesc {
	struct staticRobotDesc *next;
	
	char *name;
	int class;
	char *basename;
	int rbtID;
	JLS *jls;
	KYN *kyn;
	void *var;

	float *angles;

	int hasEndEffector;
	struct object *endEffector;
	TRSF *loc;
	LocFxnDesc *locfxn;
	TRSF L[MAXJNTS+1];
	void *rgp;

} StaticRobotDesc;

typedef struct {
	int code;
#define DRAW_OBJECT		1
#define DRAW_ROBOT		2
#define DRAW_STATIC_ROBOT	3
	union {
	   ObjectDesc *od;
	   RobotDesc *rd;
	   StaticRobotDesc *sd;
	  } u;
} DrawDesc;

#endif
