//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
#include <iostream>
#include <conio.h>
#include <mvIMPACT_CPP/mvIMPACT_acquire.h>
#include "saveimg.h"


#ifdef MALLOC_TRACE
	#include <mcheck.h>
#endif	// MALLOC_TRACE

#ifdef linux
#define PRESS_A_KEY				\
		cout << "Press a key..." << endl;	\
		getchar();
#else
#define PRESS_A_KEY				\
		cout << "Press a key..." << endl;	\
		char ch = getch();
#endif

//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
using namespace mvIMPACT::acquire;
using namespace std;

//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
int main( int argc, char* argv[])
//-----------------------------------------------------------------------------
{
	char* pDevSerial = "SD*";
// 	const char* pDevSerial = "MT*";
#ifdef MALLOC_TRACE
	mtrace();
#endif	// MALLOC_TRACE

	cout << "\n ++ Start sample: " << __DATE__ << "/" << __TIME__ << endl;

	if( argc > 1 )
		pDevSerial = argv[1];

	//
	unsigned int uiDevCount = 0;
	DeviceManager DevMgr;
	if(( uiDevCount = DevMgr.deviceCount()) == 0 )
	{
		cout << "*** Error: No MATRIX VISION device found! Unable to continue!" << endl;
		PRESS_A_KEY
		return 0;
	}

	cout << "Have found " << uiDevCount << " devices on this platform!" << endl;

	for( unsigned i = 0; i < uiDevCount; i++ )
	{
		Device* pDevTmp = DevMgr.getDevice( i );

		cout << " " << i << " Serial: " << pDevTmp->serial.read() << endl;
	}

	cout << "Initialising the device: "<< pDevSerial << ". This might take some time..." << endl;
	// create an interface to the first MATRIX VISION device with the serila number pDevSerial
	Device* pDev = DevMgr.getDeviceBySerial( pDevSerial );

	try
	{
		pDev->open();
	}
	catch( ImpactAcquireException& e )
	{
		// this e.g. might happen if the same device is already opened in another process...
		cout << "*** Error: An error occurred while opening the device(error code: " << e.errCode() << "). Press any key to end the application..." << endl;
		PRESS_A_KEY
		return 0;
	}

	FunctionInterface fi( pDev );

	// only 8Bit/pixel destination image are supported by the \c writeFile() function
	ImageDestination imgDst( pDev );
	imgDst.pixelFormat.write( idpfMono8 );

	// make sure there is at least 1 request to capture an image
	// requests are structures containing information for the driver how to capture an image
	// and return information about the image back to user when the image has been captured
	fi.ensureRequests( 1 );

	// send a request to the default request queue of the device and wait for the result.
	fi.imageRequestSingle();
	const int iMaxWaitTime_ms = 5000;
	// wait for results from the default capture queue
	int iRequestNr = fi.imageRequestWaitFor( iMaxWaitTime_ms );

	cout << "Request Nr.: " << iRequestNr << endl;
	// check if the image has been captured without any problems
	if( !fi.isRequestNrValid( iRequestNr ) )
	{
		// this can not happen in this sample, but may happen if you wait for a request without
		// sending one to the driver before
		cout << "*** Error: No request has been send to the driver." << endl;
		return 0;
	}

	const Request* psRequest = fi.getRequest(iRequestNr);
	if( !fi.isRequestOK( psRequest ) )
	{
		cout << "*** Error: Code " << psRequest->getResult().result << endl;
		return 0;
	}

	// everything went well. Display the result
	const ImageBuffer& sIB = psRequest->getImageBuffer();
// 	printf(" == %s (%s: %d)\n", __FUNCTION__, __FILE__, __LINE__ );

	char* pImageName = "SingCapt.pgm";

	cout << "Will save the file as:  " << pImageName << endl;
	if( writeFile( (const unsigned char*)sIB.vpData, sIB.iWidth, sIB.iHeight, sIB.pChannels[0].iLinePitch, sIB.pChannels[0].iPixelPitch, pImageName ) < 0)
		cout << "*** Error: File: "<< pImageName << " could not be saved!!" << endl;

	// unlock the buffer to let the driver know that you no longer need this buffer
	fi.imageRequestUnlock( iRequestNr );

	cout << "Press any key to end the application" << endl;

	PRESS_A_KEY

	// free resources
	fi.imageRequestReset( 0, 0 );

	pDev->close();

	return 0;
}

//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------


