
#include <stdio.h>
#include "videoserver.h"

#include "video_conf.h"

static TUPLE_DESCRIPTOR req_desc;
static TUPLE_DESCRIPTOR rep_desc;

static TUPLE	request;
static TUPLE	reply;

static TUPLE	t;

static VCONF_DEVTABLE	vdt;	/* video device table for the server */
static TUPLE_DESCRIPTOR vtbl_desc;

static TUPLE vdev_tuple[MAXDEVS];
static RELATION mytable;

char *getenv();

main(argc,argv)

	int	argc;
	char	*argv[];
{

	CONNECTION server;			/* this represents the */
						/* server*/
	int	i;
	int	stat;
	int	reqtype;
	int	reqp1, reqp2, reqp3, reqp4;
	char	devname[32];
	char	reqname[32];
	int	devnum;
	int	repcode, repval, reperr;
	char	line[256];
	char	cmd[32];
	int	foundname = 0;
	char	sid[64];
	int	port;
	char *	dispname;
	char	outname[128];
	char	host[64];
	int	dispnum;
	
	if( argc != 1 )
	{
		fprintf(stderr,"\nsyntax: %s\n",argv[0]);
		exit(1);
	}

	gdb_init();

	dispname = getenv("DISPLAY");
	if( !dispname )
	{
		fprintf(stderr,"%s: unable to get environment variable 'DISPLAY'\n",
			argv[0]);
		exit(1);
	}

	gethostname(host,64);

	if( index(dispname,':') )	/* allow name shortcuts */
	{
		if( !strcmp(dispname,":0") || !strcmp(dispname,"unix:0") )
		{
			sprintf(outname,"%s:0",host);
		}
		else if( !strcmp(dispname,":1") || !strcmp(dispname,"unix:1") )
		{
			sprintf(outname,"%s:1",host);
		}
		else
		  {
		    strcpy(outname,dispname);
printf(" dsp %s ==> %s\n",dispname, outname);
		   }
	 }
	else
	{
		strcpy(outname,dispname);
printf(" dsp %s ==> %s\n",dispname, outname);
	}

	vconf_mkupper( outname );
printf("%s ==> ",outname);
	sscanf(outname,"%[^:]:%d",host,&dispnum);
printf("%s:%d\n",host,dispnum);

	port = VIDSERVE_SERVER_BASE_ID + (10*dispnum);
	sprintf(sid,"%s:#%d",host,port);
			
	printf("Attempting connection to server: %s\n", sid);

	server = start_server_connection(sid, "Dummy parms");

	stat = connection_status(server);

        if (server == NULL || stat != CON_UP) 
	{
		fprintf(stderr,"Could not start connection to server %s\n",sid);
		exit(1);
	}

	printf("Connection to videoserver '%s' started successfully.\n",sid);

	req_desc = create_tuple_descriptor( SERVER_REQUEST_FIELDS, 
		server_request_field_names, server_request_field_types );
	rep_desc = create_tuple_descriptor( STD_REPLY_FIELDS, 
		std_reply_field_names, std_reply_field_types );

	request = create_tuple(req_desc);
	reply = create_tuple(rep_desc);

	vtbl_desc = create_tuple_descriptor( VTBL_FIELDS,
		vtbl_field_names, vtbl_field_types );
	mytable = create_relation( vtbl_desc );

	/* ask for the server for the video device table */

	*((int *)FIELD_FROM_TUPLE(request,0)) = VIDSERVE_SERVER_DEVICE;
	*((int *)FIELD_FROM_TUPLE(request,1)) = VIDSERVE_GET_DEVICE_TABLE;

	if (send_object(server, &request, TUPLE_T) == OP_CANCELLED) 
	{
		    fprintf(stderr,"\n\nSend error; unable to retrieve video device table.\n");
		    exit(1);
	}

	if( receive_object(server, &mytable, RELATION_T) == OP_CANCELLED) 
	{
		    fprintf(stderr,"\n\nReceive error; unable to retrieve video device table.\n");
		    exit(1);
	}

	/* break the info out of the relation into local vdt table */

	vdt.ndevs = tuples_in_relation( mytable );

	for( 	i=0, t = FIRST_TUPLE_IN_RELATION(mytable);
				t != NULL;
				i++, t = NEXT_TUPLE_IN_RELATION(mytable,t) )
	{
		vdt.dev[i].type = *(int *)FIELD_FROM_TUPLE(t,0);

		strcpy(vdt.dev[i].name,
			STRING_DATA(*((STRING *)FIELD_FROM_TUPLE(t,1))));

		strcpy(vdt.dev[i].model,
			STRING_DATA(*((STRING *)FIELD_FROM_TUPLE(t,2))));

		strcpy(vdt.dev[i].mon_proc,
			STRING_DATA(*((STRING *)FIELD_FROM_TUPLE(t,3))));

		strcpy(vdt.dev[i].tty,
			STRING_DATA(*((STRING *)FIELD_FROM_TUPLE(t,4))));
 
		vdt.dev[i].baud = *(int *)FIELD_FROM_TUPLE(t,5);

		vdt.dev[i].parity = *(int *)FIELD_FROM_TUPLE(t,6);

		strcpy(vdt.dev[i].channel,
			STRING_DATA(*((STRING *)FIELD_FROM_TUPLE(t,7))));
	}

	printf("devices controllable by this client:\n");

	for( i=0; i < vdt.ndevs; i++ )
	{
		printf("\n=========================================\n");
		printf("device #%d:\n",i);
		printf("\ttype : %s\n",vconf_nameoftype(vdt.dev[i].type) );
		printf("\tname : %s\n",vdt.dev[i].name);
		printf("\tmodel: %s\n",vdt.dev[i].model);
		printf("\tmon  : %s\n",vdt.dev[i].mon_proc);
		printf("\tport : /dev/%s\n",vdt.dev[i].tty);
		printf("\tbaud : %d\n",vdt.dev[i].baud);
		printf("\tpar  : %s\n",vconf_nameofparity(vdt.dev[i].parity));
		printf("\tchan : %s\n",vdt.dev[i].channel);
	}

	while(!feof(stdin))
	{
		gets(line);

		reqp1 = reqp2 = reqp3 = reqp4 = 0;
		sscanf(line,"%s %s %d %d %d %d\n",
			devname,reqname,&reqp1,&reqp2,&reqp3,&reqp4);
	
		vconf_mkupper( devname );
		vconf_mkupper( reqname );

		for( i=0, foundname = 0; i<vdt.ndevs; i++ )
			if( (vdt.dev[i].type == SWTR_DEV || vdt.dev[i].type == RPD_DEV)
				&& !strcmp(vdt.dev[i].name,devname) )
			{
				foundname = 1;
				devnum = i;
				break;
			}

		if( !foundname && !strcmp(devname,"SERVER") )
			devnum = -1;
		else if( !foundname )
		{
			printf("unrecognized device: '%s'\n",devname);
			printf("valid devices are:\n");
			for( i=0; i < vdt.ndevs; i++ )
				if( vdt.dev[i].type == SWTR_DEV || 
					vdt.dev[i].type == RPD_DEV )
				printf("\t%s (%s)\n",vdt.dev[i].name,
					vconf_nameoftype(vdt.dev[i].type) );
			goto next;
		}

		if( devnum >=0 )
		{
		switch( vdt.dev[devnum].type )
		{
		case RPD_DEV:

			if( !strcmp(reqname,"INDEXON") )
			{
				reqtype = VIDSERVE_CMD;
				reqp1 = INDEX_ON;
			}

			else if( !strcmp(reqname,"INDEXOFF") )
			{
				reqtype = VIDSERVE_CMD;
				reqp1 = INDEX_OFF;
			}

			else if( !strcmp(reqname,"A1ON") )
			{
				reqtype = VIDSERVE_CMD;
				reqp1 = A1_ON;
			}

			else if( !strcmp(reqname,"A1OFF") )
			{
				reqtype = VIDSERVE_CMD;
				reqp1 = A1_OFF;
			}

			else if( !strcmp(reqname,"A2ON") )
			{
				reqtype = VIDSERVE_CMD;
				reqp1 = A2_ON;
			}

			else if( !strcmp(reqname,"A2OFF") )
			{
				reqtype = VIDSERVE_CMD;
				reqp1 = A2_OFF;
			}
	
			else if( !strcmp(reqname,"LOAD") )
			{
				reqtype = VIDSERVE_CMD;
				reqp1 = LOAD;
			}

			else if( !strcmp(reqname,"UNLOAD") )
			{
				reqtype = VIDSERVE_CMD;
				reqp1 = UNLOAD;
			}

			else if( !strcmp(reqname,"@") )
				reqtype = VIDSERVE_GETFRAME;

			else if( !strcmp(reqname,"FJOG") )
			{
				reqtype = VIDSERVE_JOG;
				reqp1 = 1;
			}

			else if( !strcmp(reqname,"RJOG") )
			{
				reqtype = VIDSERVE_JOG;
				reqp1 = -1;
			}

			else if( !strcmp(reqname,"RESET") )
				reqtype = VIDSERVE_RESET;

			else if( !strcmp(reqname,"FMAX") )
			{
				reqtype = VIDSERVE_VARSPEED;
				reqp1 = F_MAX;
			}

			else if( !strcmp(reqname,"RMAX") )
			{
				reqtype = VIDSERVE_VARSPEED;
				reqp1 = R_MAX;
			}

			else if( !strcmp(reqname,"FVFAST") )
			{
				reqtype = VIDSERVE_VARSPEED;
				reqp1 = F_VERY_FAST;
			}

			else if( !strcmp(reqname,"RVFAST") )
			{
				reqtype = VIDSERVE_VARSPEED;
				reqp1 = R_VERY_FAST;
			}

			else if( !strcmp(reqname,"FFAST") )
			{
				reqtype = VIDSERVE_VARSPEED;
				reqp1 = F_FAST;
			}

			else if( !strcmp(reqname,"RFAST") )
			{
				reqtype = VIDSERVE_VARSPEED;
				reqp1 = R_FAST;
			}
		
			else if( !strcmp(reqname,"FPLAY") )
			{
				reqtype = VIDSERVE_VARSPEED;
				reqp1 = F_PLAY;
			}

			else if( !strcmp(reqname,"RPLAY") )
			{
				reqtype = VIDSERVE_VARSPEED;
				reqp1 = R_PLAY;
			}

			else if( !strcmp(reqname,"FSLOW") )
			{
				reqtype = VIDSERVE_VARSPEED;
				reqp1 = F_SLOW;
			}

			else if( !strcmp(reqname,"RSLOW") )
			{
				reqtype = VIDSERVE_VARSPEED;
				reqp1 = R_SLOW;
			}

			else if( !strcmp(reqname,"FMIN") )
			{
				reqtype = VIDSERVE_VARSPEED;
				reqp1 = F_VERY_SLOW;
			}

			else if( !strcmp(reqname,"RMIN") )
			{
				reqtype = VIDSERVE_VARSPEED;
				reqp1 = R_VERY_SLOW;
			}

			else if( !strcmp(reqname,"STILL") )
			{
				reqtype = VIDSERVE_VARSPEED;
				reqp1 = STOP;
			}

			else if( !strcmp(reqname,"SEGPLAY") )
			{
				reqtype = VIDSERVE_SEGPLAY;
			}

			else if( !strcmp(reqname,"SEARCH") )
			{
				reqtype = VIDSERVE_SEARCH;
			}
	
			else
			{	/* error */

				printf("invalid RPD request\n");
				goto next;
			}

			break;
		case SWTR_DEV:

			if( !strcmp(reqname,"RESET") )
			{
				reqtype = VIDSERVE_RESET;
				reqp1 = 0;
			}

			else if( !strcmp(reqname,"INQUIRE") )
			{
				reqtype = VIDSERVE_INQUIRE;
				reqp1 = 1;	/* assume only one output ... */
			}

			else if( !strcmp(reqname,"VIDEO") )
			{
				reqtype = VIDSERVE_SET_CHAN_SRC;
				reqp2 = reqp1;	/* slight rearrangement */
				reqp1 = VIDEO_CHAN;
				reqp3 = 1;	/* assume only one output ... */
			}

			else if( !strcmp(reqname,"LEFT") )
			{
				reqtype = VIDSERVE_SET_CHAN_SRC;
				reqp2 = reqp1;	/* slight rearrangement */
				reqp1 = LEFT_CHAN;
				reqp3 = 1;	/* assume only one output ... */
			}

			else if( !strcmp(reqname,"RIGHT") )
			{
				reqtype = VIDSERVE_SET_CHAN_SRC;
				reqp2 = reqp1;	/* slight rearrangement */
				reqp1 = RIGHT_CHAN;
				reqp3 = 1;	/* assume only one output ... */
			}

			else if( !strcmp(reqname,"ALL") )
			{
				reqtype = VIDSERVE_SET_CHAN_SRC;
				reqp2 = reqp1;	/* slight rearrangement */
				reqp1 = ALL_CHAN;
				reqp3 = 1;	/* assume only one output ... */
			}

			else
			{	/* error */

				printf("invalid SWTR request\n");
				goto next;
			}

			break;
		default:
			printf("internal error: can't get device type\n");
			goto next;
			break;
		}	/* end switch */
		}	/* end if */
		else	/* server request */
		{
			if( !strcmp(reqname,"LOCK") )
				reqtype = VIDSERVE_LOCK;

			else if( !strcmp(reqname,"UNLOCK") )
				reqtype = VIDSERVE_UNLOCK;

			else if( !strcmp(reqname,"RESET") )
				reqtype = VIDSERVE_RESET;

			else
			{	/* error */

				printf("invalid SERVER request\n");
				goto next;
			}
		
		}

		*((int *)FIELD_FROM_TUPLE(request,0)) = devnum;
		*((int *)FIELD_FROM_TUPLE(request,1)) = reqtype;
		*((int *)FIELD_FROM_TUPLE(request,2)) = reqp1;
		*((int *)FIELD_FROM_TUPLE(request,3)) = reqp2;
		*((int *)FIELD_FROM_TUPLE(request,4)) = reqp3;
		*((int *)FIELD_FROM_TUPLE(request,5)) = reqp4;

		if (send_object(server, &request, TUPLE_T) == OP_CANCELLED) 
		{
		    fprintf(stderr,"\n\nSend error; server connection is dead.\n");
		    exit(1);
		}

		if( receive_object(server, &reply, TUPLE_T) == OP_CANCELLED) 
		{
		    fprintf(stderr,"\n\nReceive error; server connection is dead.\n");
		    exit(1);
		}

		repcode = *((int *)FIELD_FROM_TUPLE(reply,0));
		repval = *((int *)FIELD_FROM_TUPLE(reply,1));
		reperr = *((int *)FIELD_FROM_TUPLE(reply,2));
		
		printf("reply: %d %d %d\n",repcode,repval,reperr);
		next:;
	}
	
}


