//////////////////////////////////////////////////////////////////////
// UCSB - Electrical and Computer Engineering Dept.
//
// IOL_SLU (IOL Servo Lens Unit Class)
//
// Version  When      Who                    Why
// -------  ----      ---                    ---
// 1.0      02/01/00  Daryl Fortney          Initial Design
//
// This class supports SLU access under UNIX & DOS platforms.
// It accomplishes this through the IOL_UART.
//
// Copyright 2000 UCSB.  All rights reserved.
//////////////////////////////////////////////////////////////////////
// Definitions
//////////////////////////////////////////////////////////////////////
#ifndef IOL_SLU_CPP
#define IOL_SLU_CPP

// Dependencies
#include <iol/slu/slu.hpp>

//////////////////////////////////////////////////////////////////////
// Maintainance Functions
//////////////////////////////////////////////////////////////////////

//
// Print(): Simply prints the SLU Attributes to CERR.
//
void	IOL_SLU::Print(void){
#ifdef IOL_SLU_PRINT_FLOWS
cerr<<"IOL_SLU("<<this<<")::Print()"<<endl;
#endif

	#ifdef IOL_SLU_PRINT_PRINT
	cerr<<"IOL_SLU: ";

	// Check For Open UART
	if(IOL_UART::Status()==IOL_OPEN){
		cerr<<"Id = "<<Id()<<" Mode = "<<hex<<Mode()<<dec<<endl
			<<"========================================"<<endl
			<<"Zoom            RW = "<<Zoom()<<endl
			<<"Focus           RW = "<<Focus()<<endl
			<<"Diaphragm       RW = "<<Diaphragm()<<endl
			<<"Overlay         RW = "<<Overlay()<<endl;
	}else
		cerr<<"CLOSED"<<endl;
	#endif
}

//////////////////////////////////////////////////////////////////////
// Attribute Functions
//////////////////////////////////////////////////////////////////////

//
// Config(): Configures SLU for communication.
//
void	IOL_SLU::Config(void){
#ifdef IOL_SLU_PRINT_FLOWS
cerr<<"IOL_SLU("<<this<<")::Config()"<<endl;
#endif

	Overlay(0);
	Focus(AUTO);
}

//
// Parameter(num): Return Parameter Value.
//
long	IOL_SLU::Parameter(long num){
#ifdef IOL_SLU_PRINT_FLOWS
cerr<<"IOL_SLU("<<this<<")::Parameter("<<num<<")"<<endl;
#endif

	// Tx Command (Possibly Throw Error)
	switch(num){
		case ZOOM:			Tx("ZR?",3); break;
		case FOCUS:			Tx("FR?",3); break;
		case DIAPHRAGM:		Tx("DR?",3); break;
		case OVERLAY:		Tx("VW?",3); break;
		default:
			#ifdef IOL_SLU_CHECKS
			#ifdef IOL_SLU_PRINT_ERRORS
				cerr<<"IOL ERROR: IOL_SLU("<<this<<")::Parameter("<<num<<")"<<endl;
			#endif
				throw(IOL_ERROR);
			#endif
			break;
	}

	// Rx Parameter Echo
	char	rx[128];
	Rx(rx,128);

	// Extract Parameter Value
	long	value;
	sscanf(rx+2,"%ld",&value);

	return value;
}

//
// Parameter(num,value): Sets parameter value.
//
long	IOL_SLU::Parameter(long num,long value){
#ifdef IOL_SLU_PRINT_FLOWS
cerr<<"IOL_SLU("<<this<<")::Parameter("<<num<<","<<value<<")"<<endl;
#endif

	// Tx Parameter (Possibly Throw Error)
	char	tx[128];
	switch(num){
		case ZOOM:			sprintf(tx,"ZD%ld",value); break;
		case FOCUS:			if(value==AUTO)
								sprintf(tx,"FA1");
							else
								sprintf(tx,"FD%ld",value);
							break;
		case DIAPHRAGM:		sprintf(tx,"DD%ld",value); break;
		case OVERLAY:		sprintf(tx,"VW%ld",value); break;
		default:
			#ifdef IOL_SLU_CHECKS
			#ifdef IOL_SLU_PRINT_ERRORS
				cerr<<"IOL ERROR: IOL_SLU("<<this<<")::Parameter("<<num<<","<<value<<")"<<endl;
			#endif
				throw(IOL_ERROR);
			#endif
			break;
	}
	Tx(tx,128,0);

	return Parameter(num);
}

//////////////////////////////////////////////////////////////////////
// Tx & Rx Functions
//////////////////////////////////////////////////////////////////////

//
// Tx(): Transmits SLU Command over UART.
//
long	IOL_SLU::Tx(void *block,long num,long until){
#ifdef IOL_SLU_PRINT_FLOWS
cerr<<"IOL_SLU("<<this<<")::Tx(blk,"<<num<<","<<until<<")"<<endl;
#endif

	// Tx Block Through UART
	long n=IOL_UART::Tx(block,num,until);

	// TERMINATING CHARACTER IS A CR!
	IOL_UART::Tx("\r",1);

	// Trash Command Echo
	Rx();

	return n+1;
}

//
// Rx(): Receives SLU Response over UART.
//
long	IOL_SLU::Rx(void *block,long num,long until){
#ifdef IOL_SLU_PRINT_FLOWS
cerr<<"IOL_SLU("<<this<<")::Rx(blk,"<<num<<","<<until<<")"<<endl;
#endif

	// Trash Response
	if(block==NULL){
		char	blk[128];
		return IOL_UART::Rx(blk,128,until);
	}

	// Keep Response
	return IOL_UART::Rx(block,num,until);
}

#endif
