// MotorThread.cpp: Implementierung der Klasse MotorThread.
//
//////////////////////////////////////////////////////////////////////

#include "motorthread.h"
#include "motorthreaddialog.h"
#include "threadevent.h"
#include "amcmirrorpanel.h"
#include "amcmotor.h"
#include "amcserialport.h"
#include "amcerror.h"
#include <qmessagebox.h>
#include <qevent.h>
#include <qthread.h>
#include <qstring.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>

#define MAX(a,b) ((a>b) ? a : b )

extern AMCSerialPort* g_pPort[];

//////////////////////////////////////////////////////////////////////
// Konstruktion/Destruktion
//////////////////////////////////////////////////////////////////////

MotorThread::MotorThread( QObject* p_pReceiver )
	: m_pPanel( NULL ), m_pReceiver( p_pReceiver )
{
}

MotorThread::~MotorThread()
{
}

void MotorThread::run()
{
	QString qsMsg;
	qsMsg.sprintf( "Panel (%d,%d)  Port: %d, Box:%d, Driver:%d",
			       m_pPanel->i(), m_pPanel->j(), m_pPanel->port(), m_pPanel->box(), m_pPanel->driver() );
	QThread::postEvent( m_pReceiver, new ThreadEvent( qsMsg ) );

	QTime t;
	t.start();                          // start clock

	
	// We use only one motor instance and reuse it for each panel
	AMCSerialPort* pPort = g_pPort[ m_pPanel->port()-1 ];
	AMCMotor* pMotor = new AMCMotor( pPort );

	bool zLaser = false;
	for( int iRetry = 0; iRetry < 2; iRetry++ )
	{
		try
		{
			pMotor->unselectBox();
			pMotor->selectBox( m_pPanel->box() );
			pMotor->selectDriver( m_pPanel->driver() );
			pMotor->switchLaser( true );			// only for show
			zLaser = true;
			pMotor->getFrequency();
   	
			pMotor->centerMotors();
			pMotor->waitForMotors( pMotor->calcTimeout( 17000 )+2 );
			int x = m_pPanel->getRefX();
			int y = m_pPanel->getRefY();
			int steps = MAX( abs(x), abs(y) );
			if( ! ((x == 0) && (y == 0)) )			// only move is necesary
			{
				pMotor->moveMotors(x,y);
				pMotor->waitForMotors( pMotor->calcTimeout(steps) );
				m_pPanel->setX( x );
				m_pPanel->setY( y );
			}
			pMotor->switchLaser( false );			// only for show
		}
		catch( AMCError& e )
		{
			if( iRetry >= 1 )
			{
				qsMsg.sprintf( "AMCError: Panel (%d,%d)  Port: %d, Box:%d, Driver:%d -- ",
					       				m_pPanel->i(), m_pPanel->j(), m_pPanel->port(), m_pPanel->box(), m_pPanel->driver() );
				qsMsg.append( e.getErrorText() );
				QThread::postEvent( m_pReceiver, new ThreadErrorEvent( qsMsg, e ) );
			}

			// try to switch of laser if we switched it on.
			if( zLaser )
			{
				try
				{
					pMotor->switchLaser( false );			// only for show
				}
				catch( AMCError& e )
				{
				}
			}
      continue;
		}
    break;
			
	}
	delete pMotor;

	qsMsg.sprintf( "Time: %dms", t.elapsed() );
	QThread::postEvent( m_pReceiver, new ThreadEvent( qsMsg ) );
	QThread::postEvent( m_pReceiver, new QCustomEvent( PROGRESS_EVENT ) );

}

void MotorThread::setPanel(AMCMirrorPanel* p_pPanel)
{
	m_pPanel = p_pPanel;
}
