/*
 * Copyright 1988, 1989, 1990, 1991 Massachusetts Institute of Technology
 */


/* a4x1_driver.c: a simple driver for the athena VCG 4x1 switcher,
	otherwise known as the "BOA Source Controller II" */

#include "a4x1.h"
#include "structs.h"
/* --------------------------------------------------------------- */

static int	/* private, internal utility routine */
a4x1_set_state( swtr, output, v, a1, a2 )
	
	SWTR_ptr swtr;
	int	output;		/* the number of the output */
	int	v,a1,a2;	/* the number of the input patched to that channel */
{
	if( !output || output < 1 || output > NUM_OUTPUTS || !swtr)
		return 0;
	output -= 1;	/* adjust for zero-base */

	/* if anything is 0, leave it alone */

	if( v )
	{
		if( v < 1 )
			v = 1;
		else if( v > NUM_INPUTS )
			v = NUM_INPUTS;
		swtr->state[output].VideoSource = v;
	}
	if( a1 )
	{
		if( a1 < 1 )
			a1 = 1;
		else if( a1 > NUM_INPUTS )
			a1 = NUM_INPUTS;
		swtr->state[output].LeftSource = a1;
	}
	if( a2 )
	{
		if( a2 < 1 )
			a2 = 1;
		else if( a2 > NUM_INPUTS )
			a2 = NUM_INPUTS;
		swtr->state[output].RightSource = a2;
	}
	return 0;
}

/* --------------------------------------------------------------- */

int
a4x1_reset( swtr )

	SWTR_ptr	swtr;
{
  char	cmd[10];
  int default_in;

  if( !swtr )
    return -1;

  if( swtr->fd<0 )
    return -1;

  if (swtr->default_input[1] != -1)
    default_in = swtr->default_input[1];
  else default_in = 1;
    sprintf(cmd, "@!%d",default_in);
  a4x1_set_state( swtr, 1, default_in, default_in, default_in);
  ttyutil_write( swtr->fd, cmd, strlen(cmd), 10 );
  return 0;
}

/* --------------------------------------------------------------- */

int
a4x1_set_chan_src( swtr, chan, srcnum, output )

	SWTR_ptr swtr;
	int	output;	/* should always be 1, because only 1 output */
	int	chan;
	int	srcnum;
{
  char  cmd[10];
  int curvid, curch1, curch2;

  if( !swtr )
    return -1;
  
  if( swtr->fd < 0 )
    return -1;
  
/*  if( chan < VIDEO_CHAN )
    chan = VIDEO_CHAN;
  else if( chan > ALL_CHAN )
    chan = ALL_CHAN;*/

  output = 1;	/* make sure it's right */
  
  a4x1_inquire (swtr, output, &curvid, &curch1, &curch2);

  if (chan != ALL_CHAN) {
    if ((chan & VIDEO_CHAN) && (curvid == srcnum))
      chan &= (LEFT_CHAN | RIGHT_CHAN);
    if ((chan & LEFT_CHAN) && (curch1 == srcnum))
      chan &= (VIDEO_CHAN | RIGHT_CHAN);
    if ((chan & RIGHT_CHAN) && (curch2 == srcnum))
      chan &= (VIDEO_CHAN | LEFT_CHAN);
  }

  if( srcnum < 1 )
    srcnum = 1;
  else if( srcnum > NUM_INPUTS )
    srcnum = NUM_INPUTS;

  /* 
   * RMS mod 1/10/91; if we make a change to the state
   * of the video channel, we should wait until we're sure
   * the switch has been made before returning; this could
   * cause video digitizers (for example) to get a bad frame
   * or a frame from the wrong video source.
   */
  
  switch(chan) {
  case VIDEO_CHAN:
    sprintf(cmd, "@V%d", srcnum );
    ttyutil_write( swtr->fd, cmd, strlen(cmd), 10 );
    a4x1_set_state( swtr, output, srcnum, 0, 0 );
    if(curvid != srcnum)
      mpause(200);
    /* microsleep(200000); */
    break;
  case LEFT_CHAN:
    sprintf(cmd, "@L%d", srcnum );
    ttyutil_write( swtr->fd, cmd, strlen(cmd), 10 );
    a4x1_set_state( swtr, output, 0, srcnum, 0 );
    /* microsleep(200000); */
    break;
  case RIGHT_CHAN:
    sprintf(cmd, "@R%d", srcnum );
    ttyutil_write( swtr->fd, cmd, strlen(cmd), 10 );
    a4x1_set_state( swtr, output, 0, 0, srcnum );
    /* microsleep(200000); */
    break;
  case ALL_CHAN:
    sprintf(cmd, "@!%d", srcnum );
    ttyutil_write( swtr->fd, cmd, strlen(cmd), 10 );
    a4x1_set_state( swtr, output, srcnum, srcnum, srcnum );
    if(curvid != srcnum)
      mpause(200);
    /* microsleep(200000); */
    break;
  case (RIGHT_CHAN | LEFT_CHAN):
    sprintf(cmd, "@L%d", srcnum );
    ttyutil_write( swtr->fd, cmd, strlen(cmd), 10 );
    sprintf(cmd, "@R%d", srcnum );
    ttyutil_write( swtr->fd, cmd, strlen(cmd), 10 );
    a4x1_set_state( swtr, output, 0, srcnum, srcnum );
    /* microsleep(200000); */
    break;
  case (RIGHT_CHAN | VIDEO_CHAN):
    sprintf(cmd, "@R%d", srcnum );
    ttyutil_write( swtr->fd, cmd, strlen(cmd), 10 );
    sprintf(cmd, "@V%d", srcnum );
    ttyutil_write( swtr->fd, cmd, strlen(cmd), 10 );
    a4x1_set_state( swtr, output, srcnum, 0, srcnum);
    if(curvid != srcnum)
      mpause(200);
    /* microsleep(200000); */
    break;
  case (LEFT_CHAN | VIDEO_CHAN):
    sprintf(cmd, "@V%d", srcnum );
    ttyutil_write( swtr->fd, cmd, strlen(cmd), 10 );
    sprintf(cmd, "@L%d", srcnum );
    ttyutil_write( swtr->fd, cmd, strlen(cmd), 10 );
    a4x1_set_state( swtr, output, srcnum, srcnum, 0 );
    if(curvid != srcnum)
      mpause(200);
    /* microsleep(200000); */
    break;
  default:
    break;
  }
  return 0;
}

/* --------------------------------------------------------------- */

int
a4x1_inquire( swtr, output, vsrc, lsrc, rsrc )

	SWTR_ptr swtr;
	int	output;
	int *	vsrc;
	int *	lsrc;
	int *	rsrc;
{

	if( output < 1 || output > NUM_OUTPUTS || !swtr)
		return -1;	/* don't mess with the channel return values */
	output -= 1;		/* adjust for zero-base */

	*vsrc = swtr->state[output].VideoSource;
	*lsrc = swtr->state[output].LeftSource;
	*rsrc = swtr->state[output].RightSource;
	return 0;
}

/* --------------------------------------------------------------- */

int
a4x1_setfuncs( swtr )

	SWTR_ptr	swtr;
{
	swtr->reset = a4x1_reset;
	swtr->set_chan_src = a4x1_set_chan_src;
	swtr->inquire = a4x1_inquire;
	swtr->inputs = NUM_INPUTS;	/* from a4x1.h */
	swtr->outputs = NUM_OUTPUTS;	/* from a4x1.h */
	return 0;
}
