//
//  motion_controller.cpp - motion controller class implementation
//
//  $Id: motion_controller.cpp 55 2014-04-29 20:38:24Z brian $ 
//
//  Copyright (c) 1999-2014 by Precision Micro Control Corp. All rights reserved.
//
#include "stdafx.h"

MotionController::MotionController(int id) :
	m_ctlr_type(0), m_hctlr_asc(0), m_hctlr_bin(0), m_id(id)
{
}

void MotionController::Open(void)
{
	// binary first
	if ((m_hctlr_bin = MCOpen(m_id, MC_OPEN_BINARY | MC_OPEN_EXCLUSIVE, NULL)) < 0)
	{
		CString Message;
		TRACE("Unable to open motion controller in binary mode, return value %d\r\n", static_cast<int>(m_hctlr_bin));
		Message.LoadString(IDS_UNABLE_TO_OPEN_CONTROLLER_IN_BINARY_MESSAGE);
		AfxMessageBox((const char*)Message, MB_OK | MB_APPLMODAL, 0);
		AfxAbort();			// Abort application
	}
	else
	{
		// Try to get controller configuration
		MCPARAMEX param;
		param.cbSize = sizeof(MCPARAMEX);
		if (MCGetConfigurationEx(m_hctlr_bin, &param) == MCERR_NOERROR)
			m_ctlr_type = param.ControllerType;
		else
		{
			CString Message;
			TRACE("Unable to get controller configuration\r\n");
			Message.LoadString(IDS_UNABLE_TO_OPEN_CONTROLLER_IN_BINARY_MESSAGE);
			AfxMessageBox((const char*)Message, MB_OK | MB_APPLMODAL, 0);
			AfxAbort();		// Abort application
		}
	}

	// ASCII next
	if ((m_hctlr_asc = MCOpen(m_id, MC_OPEN_ASCII | MC_OPEN_EXCLUSIVE, NULL)) < 0)
	{
		CString Message;
		TRACE("Unable to open motion controller in ASCII mode, return value %d\r\n", static_cast<int>(m_hctlr_asc));
		Message.LoadString(IDS_UNABLE_TO_OPEN_CONTROLLER_IN_ASCII_MESSAGE);
		AfxMessageBox((const char*)Message, MB_OK | MB_APPLMODAL, 0);
		AfxAbort();			// Abort application
	}
}

void MotionController::Close(void)
{
	MCClose(m_hctlr_bin);
	m_hctlr_bin = 0;
	MCClose(m_hctlr_asc);
	m_hctlr_asc = 0;
}

int MotionController::GetFilePosition(void)
{
	int dummy = 0; 
	pmccmdex(m_hctlr_bin, 0, TBP, &dummy, MC_TYPE_LONG);
	pmcrpyex(m_hctlr_bin, &dummy, MC_TYPE_LONG);
	return dummy;
}

int MotionController::GetProgramNumber(void)
{
	int dummy = 0; 
	pmccmdex(m_hctlr_bin, 0, TPN, &dummy, MC_TYPE_LONG);
	pmcrpyex(m_hctlr_bin, &dummy, MC_TYPE_LONG);
	return dummy;
}

int MotionController::GetRepeatCount(void)
{
	int dummy = 0; 
	pmccmdex(m_hctlr_bin, 0, TRC, &dummy, MC_TYPE_LONG);
	pmcrpyex(m_hctlr_bin, &dummy, MC_TYPE_LONG);
	return dummy;
}

int MotionController::GetRunStatus(void)
{
	int dummy = 0; 
	pmccmdex(m_hctlr_bin, 0, TRS, &dummy, MC_TYPE_LONG);
	pmcrpyex(m_hctlr_bin, &dummy, MC_TYPE_LONG);
	return dummy;
}

int MotionController::GetSequenceNumber(void)
{
	int dummy = 0; 
	pmccmdex(m_hctlr_bin, 0, TSN, &dummy, MC_TYPE_LONG);
	pmcrpyex(m_hctlr_bin, &dummy, MC_TYPE_LONG);
	return dummy;
}

double MotionController::GetSpindleSpeed(void)
{
	int dummy = 0; 
	double reply = 0.0;
	pmccmdex(m_hctlr_bin, 0, TSS, &dummy, MC_TYPE_LONG);
	pmcrpyex(m_hctlr_bin, &reply, MC_TYPE_DOUBLE);
	return reply;
}

int MotionController::GetToolNumber(void)
{
	int dummy = 0; 
	pmccmdex(m_hctlr_bin, 0, TTN, &dummy, MC_TYPE_LONG);
	pmcrpyex(m_hctlr_bin, &dummy, MC_TYPE_LONG);
	return dummy;
}

bool MotionController::RdyFile(void)
{
	if (GetControllerType() != MFXETH1000)		// non-ethernet is easy, pmcrdy() returns -1 if ready for download
		return pmcrdy(m_hctlr_asc) == -1;
	else										// for ethernet use binary interface to read command interpreter status
	{
		// This doesn't work, may be firmware problem with command interpreter
		//const DWORD address = 0xA0020108;		// MFX command interpreter status address
		//const unsigned char AsciiLoad = 0x80;	// MFX command interpreter status ASCII file load flag
		//unsigned char status;

		//pmcgetramex(m_hctlr_asc, address, &status, sizeof(unsigned char));
		//return (status & AsciiLoad) != 0;
		Sleep(10);
		return true;
	}
}

// Load ASCII file onto motion controller under specified file number
void MotionController::LoadFile(char* filename, int file_no)
{
	std::fstream file;
	
	// Open file for reading
	file.open(filename, std::ios::in);
	if (file.fail())
	{
		TRACE("Unable to open file\r\n");
		file.clear();
		return;
	}
	else
	{
		// Issue File Load file command to controller
		char buffer[256];
		sprintf(buffer, "LO%d\r", file_no);
		PutS(buffer);
			
		// Wait for controller to be ready fo file loading
		while (!RdyFile())
			Sleep(25);

		// Copy file to motion controller
		do
		{
			// Get line of text from stream file, newline character is discarded by getline() function
			file.getline(buffer, sizeof(buffer), '\n');
			if (!file.eof())
			{
				// Append newline to string and send to controller
				int index = strlen(buffer);
				buffer[index++]='\n';
				buffer[index++]='\0';
				PutS(buffer);
			}
		} while (!file.eof());
		
		file.close();
		PutS("\x01A");			// Terminate load of file
		
		double delay = GetTickCount();
		while (GetTickCount() < (delay + 500))
			;
	}	
}
