/******************************************************************************
*                                                                             *
*      Copyright(c) 2018 ScanPrint                                            *
*                                                                             *
*      Sample code for connecting to ScanPrint SP5001 using the syc api       *
*                                                                             *
*******************************************************************************/
#include "stdafx.h"
#include "CyberSC.h"
#include <iostream>

using namespace std;

// Forward declaration of functions.
void WriteBitmap(LPBITMAPINFO pBitmap, LPCWSTR filename);
void HandleErrors();

int main()
{
	// Setup the scanner to use the sync APIs
	if(!ScSyncInit())
	{
		cout << "No Scanner." << endl;
		return -1;
	}

	// Wait for an image to be scanned or a fatal error.
	cout << "Waiting for a scan." << endl;
	LPBITMAPINFO pBitmap = ScSyncScan(false);
			
	// If there is no bitmap then report the error.
	if(!pBitmap)
	{
		HandleErrors();
		cout << "Scan Failed." << endl;
		return -2;
	}
	
	// Save the bitmap to a file.
	WriteBitmap(pBitmap, L"sync-cpp.bmp");

	// Release the bitmap.
	ScSyncFreeBitmap(pBitmap);

    return 0;
}

// Write any error messages to the console.
void HandleErrors()
{
	DWORD error;
	DWORD errorType;
	char msg[CV_ERROR_BUFFER_SIZE];
	bool moreErrors = false;
	do
	{
		// Fill in the error information.
		// If this returns True there are more errors to read.
		moreErrors = ScSyncLastError(&error, &errorType, msg);
		if (error == CV_DEBUG) 
		{
			// Only debug messages have an text message.
			cout << "Debug Msg: " << msg << endl;
		}
		else
		{
			cout << "Fatal Error: " << error << endl;
		}
	} while (moreErrors);

}	


// Save the recorded bitmap to a file.
void WriteBitmap(LPBITMAPINFO pBitmap, LPCWSTR filename) 
{
	DWORD infoSize = sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * pBitmap->bmiHeader.biClrUsed;
	DWORD dataSize = pBitmap->bmiHeader.biSizeImage;

	//A bimap file has an extra header.
	BITMAPFILEHEADER   bmfHeader;
	bmfHeader.bfType = 0x4D42; //Must always be set to bitmap BM   
	bmfHeader.bfSize = infoSize + dataSize + sizeof(BITMAPFILEHEADER);
	bmfHeader.bfOffBits = infoSize + sizeof(BITMAPFILEHEADER);	//Where the data starts.
	bmfHeader.bfReserved1 = 0;
	bmfHeader.bfReserved2 = 0;

	//Write the bitmap to a file.
	DWORD dwBytesWritten = 0;
	HANDLE hFile = CreateFile(filename, GENERIC_WRITE, 0, NULL,
		CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
	WriteFile(hFile, (LPSTR)&bmfHeader, sizeof(BITMAPFILEHEADER), &dwBytesWritten, NULL);
	WriteFile(hFile, (LPSTR)pBitmap, infoSize + dataSize, &dwBytesWritten, NULL);

	CloseHandle(hFile);
}
