/*
 * Remote Laboratory Instrumentation Server
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * (c) 2009 Timothy Pearson
 * Raptor Engineering
 * http://www.raptorengineeringinc.com
 */

#include <ctype.h>
#include <errno.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <getopt.h>
#include "gpib_functions.h"
#include "parameters.h"
#include "gpib/ib.h"

extern char falpha[1024];

int signal_get_last_error(const char * funcgenType, int gpibDevice, char * extendedError) {
	char error_array[1024];
	int ei;
	char * ep;

	// Zero the error array
	for (ei=0;ei<1024;ei++) {
		error_array[ei] = 0;
	}

	if ((strcmp("AG33250A", funcgenType) == 0)) {
		if (strcmp("AG33250A", funcgenType) == 0) {
			sleep (1);
			sprintf(falpha,"SYSTEM:ERROR?");
			#ifdef ENABLE_EXTRA_DEBUGGING
			printf("[DEBG] Writing: %s\n\r", falpha);
			#endif
			if (gpib_write(gpibDevice, falpha) == 0) {
				ibrd(gpibDevice, error_array, 1024-1);
				ep = strstr(error_array, "+0,");
				if (ep != 0) {
					return 0;
				}
				else {
					sprintf(extendedError, "EXT%s%c\n\r", error_array, 176);
					#ifdef ENABLE_EXTRA_DEBUGGING
					printf("[DEBG] Extended error: %s\n\r", extendedError);
					#endif
					return 3;
				}
			}
			else {
				sprintf(extendedError, "EXTAn unknown communications error has occured!%c\n\r", 176);
				#ifdef ENABLE_EXTRA_DEBUGGING
				printf("[DEBG] Extended error: %s\n\r", extendedError);
				#endif
				return 2;
			}
		}
	}
	sprintf(extendedError, "EXTAn invalid device was selected!%c\n\r", 176);
	#ifdef ENABLE_EXTRA_DEBUGGING
	printf("[DEBG] Extended error: %s\n\r", extendedError);
	#endif
	return 1;
}

int signal_reset(const char * funcgenType, int gpibDevice, char * extendedError)
{
	if ((strcmp("AG33250A", funcgenType) == 0)) {
		printf("[INFO] Resetting function generator\n\r");
		if (strcmp("AG33250A", funcgenType) == 0) {
			sprintf(falpha,"*RST");
			#ifdef ENABLE_EXTRA_DEBUGGING
			printf("[DEBG] Writing: %s\n\r", falpha);
			#endif
			if (gpib_write(gpibDevice, falpha) == 0) {
				sprintf(falpha,"*CLS");
				#ifdef ENABLE_EXTRA_DEBUGGING
				printf("[DEBG] Writing: %s\n\r", falpha);
				#endif
				if (gpib_write(gpibDevice, falpha) == 0) {
					sprintf(falpha,"DISP:TEXT 'Remote Control System v%s.%s%s'", SERVER_MAJOR, SERVER_MINOR, SERVER_REVISION);
					#ifdef ENABLE_EXTRA_DEBUGGING
					printf("[DEBG] Writing: %s\n\r", falpha);
					#endif
					if (gpib_write(gpibDevice, falpha) == 0) {
						sprintf(falpha,"FUNCTION SQUARE");
						#ifdef ENABLE_EXTRA_DEBUGGING
						printf("[DEBG] Writing: %s\n\r", falpha);
						#endif
						if (gpib_write(gpibDevice, falpha) == 0) {
							sprintf(falpha,"OUTPUT:LOAD INFINITY");
							#ifdef ENABLE_EXTRA_DEBUGGING
							printf("[DEBG] Writing: %s\n\r", falpha);
							#endif
							if (gpib_write(gpibDevice, falpha) == 0) {
								sprintf(falpha,"VOLTAGE 3.3");
								#ifdef ENABLE_EXTRA_DEBUGGING
								printf("[DEBG] Writing: %s\n\r", falpha);
								#endif
								if (gpib_write(gpibDevice, falpha) == 0) {
									sprintf(falpha,"FUNCTION SQUARE");
									#ifdef ENABLE_EXTRA_DEBUGGING
									printf("[DEBG] Writing: %s\n\r", falpha);
									#endif
									if (gpib_write(gpibDevice, falpha) == 0) {
										sprintf(falpha,"FUNCTION:SQUARE:DCYCLE 50");
										#ifdef ENABLE_EXTRA_DEBUGGING
										printf("[DEBG] Writing: %s\n\r", falpha);
										#endif
										if (gpib_write(gpibDevice, falpha) == 0) {
											sprintf(falpha,"SYSTEM:BEEPER:STATE ON");
											#ifdef ENABLE_EXTRA_DEBUGGING
											printf("[DEBG] Writing: %s\n\r", falpha);
											#endif
											if (gpib_write(gpibDevice, falpha) == 0) {
												sprintf(falpha,"OUTPUT ON");
												#ifdef ENABLE_EXTRA_DEBUGGING
												printf("[DEBG] Writing: %s\n\r", falpha);
												#endif
												if (gpib_write(gpibDevice, falpha) == 0) {
													sprintf(falpha,"SYSTEM:BEEPER");
													#ifdef ENABLE_EXTRA_DEBUGGING
													printf("[DEBG] Writing: %s\n\r", falpha);
													#endif
													if (gpib_write(gpibDevice, falpha) == 0) {
														return signal_get_last_error(funcgenType, gpibDevice, extendedError);
													}
												}
											}
										}
									}
								}
							}
						}
					}
				}
			}
			else {
				sprintf(extendedError, "EXTAn unknown communications error has occured!�");
				return 2;
			}
		}
	}
	sprintf(extendedError, "EXTAn invalid device was selected!�");
	return 1;
}

int signal_set_frequency(float desired_frequency, const char * funcgenType, int gpibDevice, char * extendedError) {
	if ((strcmp("AG33250A", funcgenType) == 0)) {
		printf("[INFO] Setting function generator frequency to %f\n\r", desired_frequency);
		if (strcmp("AG33250A", funcgenType) == 0) {
			// FIXME
			sprintf(falpha,"FREQUENCY %E", desired_frequency);
			#ifdef ENABLE_EXTRA_DEBUGGING
			printf("[DEBG] Writing: %s\n\r", falpha);
			#endif
			if (gpib_write(gpibDevice, falpha) == 0) {
				return signal_get_last_error(funcgenType, gpibDevice, extendedError);
			}
			else {
				sprintf(extendedError, "EXTAn unknown communications error has occured!�");
				return 2;
			}
		}
	}
	else {
		sprintf(extendedError, "EXTAn invalid device was selected!�");
		return 1;
	}
}

int signal_set_duty_cycle(float desired_dcycle, const char * funcgenType, int gpibDevice, char * extendedError) {
	if ((strcmp("AG33250A", funcgenType) == 0)) {
		printf("[INFO] Setting function generator period to %f\n\r", desired_dcycle);
		if (strcmp("AG33250A", funcgenType) == 0) {
			// FIXME
			sprintf(falpha,"FUNCTION:SQUARE:DCYCLE %E", desired_dcycle);
			#ifdef ENABLE_EXTRA_DEBUGGING
			printf("[DEBG] Writing: %s\n\r", falpha);
			#endif
			if (gpib_write(gpibDevice, falpha) == 0) {
				return signal_get_last_error(funcgenType, gpibDevice, extendedError);
			}
			else {
				sprintf(extendedError, "EXTAn unknown communications error has occured!�");
				return 2;
			}
		}
	}
	else {
		sprintf(extendedError, "EXTAn invalid device was selected!�");
		return 1;
	}
}

int signal_set_waveform(char * waveform, const char * funcgenType, int gpibDevice, char * extendedError) {
	if ((strcmp("AG33250A", funcgenType) == 0)) {
		printf("[INFO] Setting function generator waveform to %s\n\r", waveform);
		if (strcmp("AG33250A", funcgenType) == 0) {
			// FIXME
			sprintf(falpha,"FUNCTION %s", waveform);
			#ifdef ENABLE_EXTRA_DEBUGGING
			printf("[DEBG] Writing: %s\n\r", falpha);
			#endif
			if (gpib_write(gpibDevice, falpha) == 0) {
				return signal_get_last_error(funcgenType, gpibDevice, extendedError);
			}
			else {
				sprintf(extendedError, "EXTAn unknown communications error has occured!�");
				return 2;
			}
		}
	}
	else {
		sprintf(extendedError, "EXTAn invalid device was selected!�");
		return 1;
	}
}

int signal_set_peak_peak_voltage(float desired_voltage, const char * funcgenType, int gpibDevice, char * extendedError) {
	if ((strcmp("AG33250A", funcgenType) == 0)) {
		printf("[INFO] Setting function generator peak-peak voltage to %f\n\r", desired_voltage);
		if (strcmp("AG33250A", funcgenType) == 0) {
			// FIXME
			sprintf(falpha,"VOLTAGE %E", desired_voltage);
			#ifdef ENABLE_EXTRA_DEBUGGING
			printf("[DEBG] Writing: %s\n\r", falpha);
			#endif
			if (gpib_write(gpibDevice, falpha) == 0) {
				return signal_get_last_error(funcgenType, gpibDevice, extendedError);
			}
			else {
				sprintf(extendedError, "EXTAn unknown communications error has occured!�");
				return 2;
			}
		}
	}
	else {
		sprintf(extendedError, "EXTAn invalid device was selected!�");
		return 1;
	}
}

int signal_set_offset_voltage(float desired_voltage, const char * funcgenType, int gpibDevice, char * extendedError) {
	if ((strcmp("AG33250A", funcgenType) == 0)) {
		printf("[INFO] Setting function generator peak-peak voltage to %f\n\r", desired_voltage);
		if (strcmp("AG33250A", funcgenType) == 0) {
			// FIXME
			sprintf(falpha,"VOLTAGE:OFFSET %E", desired_voltage);
			#ifdef ENABLE_EXTRA_DEBUGGING
			printf("[DEBG] Writing: %s\n\r", falpha);
			#endif
			if (gpib_write(gpibDevice, falpha) == 0) {
				return signal_get_last_error(funcgenType, gpibDevice, extendedError);
			}
			else {
				sprintf(extendedError, "EXTAn unknown communications error has occured!�");
				return 2;
			}
		}
	}
	else {
		sprintf(extendedError, "EXTAn invalid device was selected!�");
		return 1;
	}
}