/*  Program : test_filter.cpp
 *  Version : 1.0
 *  Author  : Dave Mills
 *  Copyright : The Random Factory 2004-2008
 *  License : GPL
 *
 *
 *  This program provides a limited test environment for Apogee ALTA 
 *  filter wheels. It utilises the same low-level API provided by the
 *  filter_USB.so and filter_NET.so shared object libraries.
 * 
 *  To build for ALTA-E
 *      g++ -I/opt/apogee/include -I./ApogeeUsb -DLINUX -c ApnFilterWheel.cpp
 *       g++ -I/opt/apogee/include -DALTA_NET -c test_filter.cpp -IFpgaRegs -o test_filtere \
 *                       ApnFilterWheel.o ApogeeNetLinux.o \
 *                       -L/opt/apogee/lib -lcurl
 *
 *  To build for ALTA-U
 *
 *      g++ -I/opt/apogee/include -I./ApogeeUsb -DLINUX -c ApnFilterWheel.cpp
 *      g++ -I/opt/apogee/include  -c test_filter.cpp -IFpgaRegs -o test_filteru \
 *                       ApnFilterWheel.o \
 *                       ApogeeUsbLinux.o \
 *                       /opt/apogee/lib/libusb.so
 *
 *
 *  The program is controlled by a set of command line options
 *  Usage information is obtained by invoking the program with -h
 *
 *  eg   ./alta_filteru -h
 *
 *
 *  Caveats : There is limited error checking on the input options, if you 
 * 	      hang the onboard software, simply power cycle the 
 * 	      unit.
 */


#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <unistd.h>
#include <time.h>
#include "ApnFilterWheel.h"

int parse_options (int argc, char **argv);

/* Declare the filter object. All camera functions and parameters are
 * accessed using the methods and instance variables of this object
 *
 * Their declarations can be found in ApnFilterWheel.h
 */

CApnFilterWheel *filterWheel;

/* Declare globals to store the input command line options */

int ip[4]={0,0,0,0};
int verbose=0;
int unitnum=1;
int wheeltype=1;
unsigned long maxpositions=0;
unsigned long position=0;
unsigned long requested=0;

/* Main executable starts here -----------------------------------------------*/

int main (int argc, char **argv) 
{

	int status;
        unsigned int ipaddr;
        int move;

/*	Obtain user provided options */
	status = parse_options(argc,argv);

/*	Create the camera object , this will reserve memory */
	filterWheel = (CApnFilterWheel *)new CApnFilterWheel();

/*	If this is an NET model, then add the ip address to the 
	driver initialization. The second argument is the default
	port used (80 is the http default). If you have altered 
	this on your camera, then change the source here too!
 */
#ifdef ALTA_NET
        ipaddr = ip[0]*256*256*256 + ip[1]*256*256 + ip[2]*256 + ip[3];
	filterWheel->Init(ipaddr,wheeltype);
#else
	filterWheel->Init(wheeltype,unitnum);
#endif

	filterWheel->GetMaxPositions(&maxpositions);
	filterWheel->GetPosition(&position);

	printf ("Max number of filters = %d\n",maxpositions);
	printf ("Current position = %d\n",position);

	if (requested > 0) {
	   filterWheel->SetPosition(requested);
           move = requested-position;
           if (move < 0) {move=move+maxpositions;}
           sleep(move);
	}


/*	 All done, tidy up */
	 filterWheel->Close();


}

/*  Helper routines start here-------------------------------------------------*/

/*  This routine provides a very simple command line parser
 *  Unknown options should be ignored, but strict type
 *  checking is NOT done.
 */

int parse_options (int argc, char **argv)
{
   int i;
   int goti,gott,gots,gota;

/* Zero out counters for required options */
   goti=0;
   gott=0;
   gots=0;
   gota=0;
   i=1;


/* Loop thru all provided options */
   while (i<argc) {


/*     Unit type */
       if (!strncmp(argv[i],"-t",2)) {
          sscanf(argv[i+1],"%d",&wheeltype);
          gott = 1;
       }

/*     Position */
       if (!strncmp(argv[i],"-p",2)) {
          sscanf(argv[i+1],"%d",&requested);
       }

/*     IP address for ALTA-E models */
       if (!strncmp(argv[i],"-a",2)) {
          sscanf(argv[i+1],"%d.%d.%d.%d",ip,ip+1,ip+2,ip+3);
          gota = 1;
       }


/*     USB camera number */
       if (!strncmp(argv[i],"-u",2)) {
          sscanf(argv[i+1],"%d",&unitnum);
       }


/*     Be more verbose */
       if (!strncmp(argv[i],"-v",2)) {
          sscanf(argv[i+1],"%d",&verbose);
       }

/*     Print usage info */
       if (!strncmp(argv[i],"-h",2)) {
          printf("Apogee filter wheel tester -  Usage: \n \
	 -a a.b.c.d      IP address of unit e.g. 192.168.0.1 (required for ethernet models only)\n \
	 -t num          Type of unit\n \
	 -u num          Unit number (default 1 , USB only) \n \
	 -p position     Filter position to select \n \
	 -v verbosity    Print more details\n");
         exit(0);
        }

/*      All options are 2 args long! */
        i = i+2;
   } 

/* Complain about missing required options, then give up */
   if ( gott == 0 ) printf("Missing argument  -t unit type, try -h for help\n");
#ifdef ALTA_NET
   if ( gota == 0 ) printf("Missing argument  -a IP address, try -h for help\n");
   if ( gota == 0 ) exit(1);
#else
   if (gott != 1) exit(1);
#endif

/* Print exposure details */
   if (verbose > 0) {
      printf("Apogee Filter Wheel test - V1.0\n");
#ifdef ALTA_NET
      if (ip[0]     != 0) printf("	ALTA-E ip address is %d.%d.%d.%d\n",ip[0],ip[1],ip[2],ip[3]);
#endif
      if (requested > 0) printf("	Move to position %d\n",requested);
   }
   return(0);

}

