/*
 * AlignmentCalibrate.c
 * 
 * Gocator 2000 Sample
 * Copyright (C) 2011 by LMI Technologies Inc.
 * 
 * Licensed under The MIT License.
 * Redistributions of files must retain the above copyright notice.
 *
 * Purpose: Connect to Gocator system and perform alignment calibration to a flat surface
 *
 */
#include <Go2.h>
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>

#define RECEIVE_TIMEOUT	30000000 // 30 second timeout for calibration to complete

void main(int argc, char **argv)
{
	int status;
	Go2System system = GO2_NULL;
	Go2Data data = GO2_NULL;
	unsigned int address;
	unsigned int i;

	// initialize Go2 API
	if ((status = Go2Api_Initialize()) != GO2_OK)
	{
		printf("Error: Go2Api_Initialize:%d\n", status);
		return;
	}

	// construct Go2 system object
	if ((status = Go2System_Construct(&system)) != GO2_OK)
	{
		printf("Error: Go2System_Construct:%d\n", status);
		return;
	}

	// convert ip address string to Go2IPAddress object
	if ((status = Go2IPAddress_Parse("192.168.1.10", &address)) != GO2_OK)
	{
		printf("Error: Go2IPAddress_Parse:%d\n", status);
		return;
	}

	// connect to Gocator system at default address
	if ((status = Go2System_Connect(system, address)) != GO2_OK)
	{
		printf("Error: Go2System_Connect:%d\n", status);
		return;
	}

	// set alignment target to none (meaning the target is a flat reference surface)
	if ((status = Go2System_SetAlignmentTarget(system, GO2_CALIBRATION_TARGET_NONE)) != GO2_OK)
	{
		printf("Error: Go2System_SetAlignmentTarget:%d\n", status);
		return;
	}	

	// establish a Gocator data connection	
	if ((status = Go2System_ConnectData(system, GO2_NULL, GO2_NULL)) != GO2_OK)
	{
		printf("Error: Go2System_ConnectData:%d\n", status);
		return;
	}

	// ensure Gocator is in Alignment Calibration Mode	
	if ((status = Go2System_SetMode(system, GO2_MODE_ALIGN_CAL)) != GO2_OK)
	{
		printf("Error: Go2System_SetMode:%d\n", status);
		return;
	}

	// Start Gocator system	
	if ((status = Go2System_Start(system)) != GO2_OK)
	{
		printf("Error: Go2System_Start:%d\n", status);
		return;
	}

	printf("Waiting for alignment calibration data to be collected...\n\n");
	
	status = Go2System_ReceiveData(system, RECEIVE_TIMEOUT, &data);
	
	if (status == GO2_ERROR_TIMEOUT)
	{
		printf("Failed to collect date for calibration within timeout limit...\n");
	}
	else if (status != GO2_OK)
	{
		printf("Error: Go2System_ReceiveData:%d\n", status);
	}
	else
	{
		//each result can have multiple data items
		for (i = 0; i < Go2Data_ItemCount(data); ++i)
		{
			Go2Data dataItem = Go2Data_ItemAt(data, i); 
			if (Go2Object_Type(dataItem) == GO2_TYPE_ALIGNMENT_DATA)
			{   
				if ((status = Go2AlignmentData_Status(dataItem)) == GO2_OK)
				{
					printf("Calibration successful!\n\n", status);
				}
				else
				{
					printf("Calibration failed.\n\n", status);
				}
			}       
		}
	}

	if ((status = Go2Data_Destroy(data)) != GO2_OK)
	{
		printf("Error: Go2Data_Destroy:%d\n", status);
		return;
	}

	// Stop Gocator system	
	if ((status = Go2System_Stop(system)) != GO2_OK)
	{
		printf("Error: Go2System_Stop:%d\n", status);
		return;
	}

	// destroy system handle
	if ((status = Go2System_Destroy(system)) != GO2_OK)
	{
		printf("Error: Go2System_Destroy:%d\n", status);
		return;
	}

	// terminate Go2 API
	if ((status = Go2Api_Terminate()) != GO2_OK)
	{
		printf("Error: Go2Api_Terminate:%d\n", status);
		return;
	}

	printf("Press any key to continue...\n");
	getchar();

	return;
}
