#include "VersalogicMMPEEAX.h"
#include <stdio.h>



VersalogicMMPEEAX::VersalogicMMPEEAX()
{
	//Initialize variables
	verMajor = 0;
	verMinor = 0;
	revision = 0;
	adcType = 0;
	isOpen = false;
	for (int i = 0; i < VL_MAXAIN; i++) {
		dAINValues[i] = 0;
	}
	for (int i = 0; i < VL_MAXDIO; i++) {
		ucDIODirections[i] = VL_DIODIRUNSET;
	}

	//First attempt to open a connection
	open();

	if (!isOpen) {
		return;
	}
	

	//Initialize
	if (initialize() != 0) {
		close();
		return;
	}
}

int VersalogicMMPEEAX::initialize() {
	
	getVersion();
	getADCType();
	
	return 0;
}

VersalogicMMPEEAX::~VersalogicMMPEEAX()
{
}

int VersalogicMMPEEAX::open(){
	// Initialize the API
	if (VSL_Open() != 0) {
		isOpen = false;
		return ERROR_OSALIBOPEN;
	}

	isOpen = true;
	return 0;
}
int VersalogicMMPEEAX::close(){
	setAllDIOLevels(DIO_CHANNEL_LOW);
	VSL_Close();
	isOpen = false;
	return 0;
}

int VersalogicMMPEEAX::getVersion(){
	VSL_GetVersion(&verMajor, &verMinor, &revision);
	return 0;
}

int VersalogicMMPEEAX::getADCType(){
	adcType = VSL_GetADCType();
	return 0;
}
int VersalogicMMPEEAX::printVersion(char * buff){
	int adcTypeNumber = 0;

	if (adcType == VSL_ADC_TYPE_A1)
		adcTypeNumber = 1;
	else if (adcType == VSL_ADC_TYPE_A2)
		adcTypeNumber = 2;

	sprintf(buff, "Versalogic MMPEEAX v%i\.%i rev %i | ADCType A%i \0", verMajor, verMinor, revision, adcTypeNumber);
	return 0;}

int VersalogicMMPEEAX::setAIRange(unsigned char channel, unsigned char Range){
	VSL_ADCSetAnalogInputRange(channel, Range);
	return 0;
}
int VersalogicMMPEEAX::readAI(unsigned char channel, double &voltage){
	voltage = VL_ADCGetAnalogInput(channel, 0x01);
	return 0;
}
int VersalogicMMPEEAX::readAllAIChannels(){

	readAI(PCI_AI_CHANNEL_1, dAINValues[0]);
	readAI(PCI_AI_CHANNEL_2, dAINValues[1]);
	readAI(PCI_AI_CHANNEL_3, dAINValues[2]);
	readAI(PCI_AI_CHANNEL_4, dAINValues[3]);
	readAI(PCI_AI_CHANNEL_5, dAINValues[4]);
	readAI(PCI_AI_CHANNEL_6, dAINValues[5]);
	readAI(PCI_AI_CHANNEL_7, dAINValues[6]);
	readAI(PCI_AI_CHANNEL_8, dAINValues[7]);

	return 0;
}


int VersalogicMMPEEAX::setDIODirection(unsigned char channel, unsigned char val){
	// VAL should be DIO_INPUT or DIO_OUTPUT
	if (val == DIO_INPUT || val == DIO_OUTPUT)
	{
		VSL_DIOSetChannelDirection(AX_CHANNEL_MASK & channel, val);
		ucDIODirections[channel - DIO_AX_CHANNEL_1] = val;
		return 0;
	}
	else return -1;
}

int VersalogicMMPEEAX::setDIOOutputLevel(unsigned char channel, unsigned char level){
	//if (ucDIODirections[channel - DIO_AX_CHANNEL_1] == DIO_OUTPUT){
	VSL_DIOSetChannelLevel(AX_CHANNEL_MASK & channel, level);
	//}
	//else { return -1; }
	
	return 0;
}
int VersalogicMMPEEAX::setAllDIOLevels(unsigned char level){
	for (int i = 0; i < VL_MAXDIO; i++){
		// Only do this if it is set as an output
		if (ucDIODirections[i] == DIO_OUTPUT){
			VSL_DIOSetChannelLevel(i+DIO_AX_CHANNEL_1, level);
		}
	}
	
	return 0;
}

int VersalogicMMPEEAX::getDIOChannelLevel(unsigned char channel, unsigned char &level){
	//if (ucDIODirections[channel - DIO_AX_CHANNEL_1] == DIO_INPUT){
	level = VSL_DIOGetChannelLevel(AX_CHANNEL_MASK & channel);
	//}
	//else { return -1; }

	return 0;
}
bool VersalogicMMPEEAX::isConnected() { return isOpen; };
