// SnapDisplayDlg.cpp
//

#include "stdafx.h"
#include "SampleSnap.h"
#include "SnapDisplayDlg.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CSnapDisplayDlg
CSnapDisplayDlg::CSnapDisplayDlg(CWnd* pParent /*=NULL*/)
	: CDialog(CSnapDisplayDlg::IDD, pParent)
{
	//{{AFX_DATA_INIT(CSnapDisplayDlg)
	//}}AFX_DATA_INIT
}

void CSnapDisplayDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CSnapDisplayDlg)
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CSnapDisplayDlg, CDialog)
	//{{AFX_MSG_MAP(CSnapDisplayDlg)
	ON_WM_DESTROY()
	ON_WM_PAINT()
	ON_WM_CONTEXTMENU()
	ON_COMMAND(IDD_SAVE_IMAGE, OnSaveImage)
	ON_WM_CLOSE()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CSnapDisplayDlg

BOOL CSnapDisplayDlg::OnInitDialog() 
{
	CDialog::OnInitDialog();
	
	m_pBitmapInfoHeader = NULL;
	m_dwWidth = 0;
	m_dwHeight = 0;
	m_dwPreviewPixelFormat = 0;
	m_pbyteImageBuffer = NULL;
	m_bNotSavedFg = FALSE;
	m_hCamera = NULL;
	m_dwImageBufferSize = 0;
	m_hMutex = CreateMutex(0, FALSE, 0);
	m_bImageDataExist = FALSE;
	m_hMenu = LoadMenu((HINSTANCE)GetWindowLongPtr(this->m_hWnd,GWLP_HINSTANCE),MAKEINTRESOURCE(IDR_MENU_SNAPDISPLAY));
	m_hMenu = GetSubMenu(m_hMenu,0);
	return TRUE;
}

void CSnapDisplayDlg::OnDestroy() 
{
	CDialog::OnDestroy();

	if(m_pBitmapInfoHeader) free(m_pBitmapInfoHeader);
	if(m_pbyteImageBuffer) delete[] m_pbyteImageBuffer;	
	CloseHandle(m_hMutex);
}

void CSnapDisplayDlg::OnPaint() 
{
	CPaintDC dc(this);
	
	WaitForSingleObject(m_hMutex, INFINITE);	
	if(m_bImageDataExist)
	{
		SetDIBitsToDevice(dc,0,0,m_dwWidth,m_dwHeight,0,0,0,m_dwHeight,m_pbyteImageBuffer,(PBITMAPINFO)m_pBitmapInfoHeader,DIB_RGB_COLORS);
	}
	ReleaseMutex(m_hMutex);

}

void CSnapDisplayDlg::OnContextMenu(CWnd* pWnd, CPoint point) 
{
	if (
		(point.x == -1) && 
		(point.y == -1)
	)
	{
		RECT rectPoint;
		::GetClientRect(this->m_hWnd, &rectPoint);
		point.x = (rectPoint.right - rectPoint.left)/2;
		point.y = (rectPoint.bottom - rectPoint.top)/2;
		ClientToScreen(&point);
	}
	TrackPopupMenu(m_hMenu,TPM_RIGHTBUTTON | TPM_LEFTALIGN,point.x,point.y,0,this->m_hWnd,NULL);
}

void CSnapDisplayDlg::OnSaveImage() 
{
	bSaveImage();
}

void CSnapDisplayDlg::OnClose() 
{
	if(m_bNotSavedFg)
	{
		if(IDYES == MessageBox(TEXT("Do You Want To Save The Image?"),TEXT("Save Image"),MB_ICONQUESTION | MB_YESNO))
			bSaveImage();
	}
	
	CDialog::OnClose();
}

BOOL CSnapDisplayDlg::bSaveImage(void)
{
	BOOL bReval = FALSE;

	CFileDialog *fdlgSave = new CFileDialog(
		FALSE,
		TEXT(".bmp"),
		NULL,
		OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,
		TEXT("Bitmap(*.bmp)|*.bmp|TIFF(*.tif)|*.tif|")
		TEXT("JPEG(*.jpg)|*.jpg|PNG(*.png)|*.png|")
		TEXT("All Files(*.*)|*.*||"),
		GetParent());
	
	WaitForSingleObject(m_hMutex, INFINITE);
	if(m_bImageDataExist)
	{
		if(IDOK == fdlgSave->DoModal())
		{
			StCam_SaveImage(m_hCamera,m_dwWidth,m_dwHeight,m_dwPreviewPixelFormat,m_pbyteImageBuffer,fdlgSave->GetPathName(),0);

			m_bNotSavedFg = FALSE;
			bReval = TRUE;
		}
	}
	ReleaseMutex(m_hMutex);
	return(bReval);
}

BOOL CSnapDisplayDlg::bUpdateSnapShot(HANDLE hCamera, DWORD dwWidth, DWORD dwHeight, DWORD dwPreviewPixelFormat, PBYTE pbyteImageBuffer, DWORD dwBufferSize, PDWORD pdwLastErrorNo)
{
	BOOL bReval = TRUE;
	*pdwLastErrorNo = NO_ERROR;

	WaitForSingleObject(m_hMutex, INFINITE);

	if(m_pBitmapInfoHeader)
	{
		free(m_pBitmapInfoHeader);
		m_pBitmapInfoHeader = NULL;
	}

	if(m_pbyteImageBuffer)
	{
		delete[] m_pbyteImageBuffer;
		m_pbyteImageBuffer = NULL;
	}

	m_dwWidth = dwWidth;
	m_dwHeight = dwHeight;
	m_dwPreviewPixelFormat = dwPreviewPixelFormat;
	m_bNotSavedFg = FALSE;
	m_hCamera = hCamera;
	m_bImageDataExist = FALSE;

	//Create Buffer
	m_dwImageBufferSize = dwBufferSize;
	DWORD dwBitmapInfoHeaderSize = sizeof(BITMAPINFOHEADER);
	if(m_dwPreviewPixelFormat == STCAM_PIXEL_FORMAT_08_MONO_OR_RAW)
	{
		//For Table
		dwBitmapInfoHeaderSize += 1024;
	}

	m_pBitmapInfoHeader = (PBITMAPINFOHEADER)malloc(dwBitmapInfoHeaderSize);
	m_pbyteImageBuffer = (PBYTE)new BYTE[m_dwImageBufferSize];

	if(
		(m_pBitmapInfoHeader == NULL) ||
		(m_pbyteImageBuffer == NULL)
	)
	{
		bReval = FALSE;
		*pdwLastErrorNo = ERROR_NOT_ENOUGH_MEMORY;
	}
	else
	{
		memcpy(m_pbyteImageBuffer,pbyteImageBuffer,m_dwImageBufferSize);
		memset(m_pBitmapInfoHeader,0,dwBitmapInfoHeaderSize);

		m_pBitmapInfoHeader->biSize = sizeof(BITMAPINFOHEADER);
		m_pBitmapInfoHeader->biWidth = dwWidth;
		m_pBitmapInfoHeader->biHeight = -(INT)dwHeight;
		m_pBitmapInfoHeader->biPlanes = 1;

		switch(m_dwPreviewPixelFormat)
		{
		case(STCAM_PIXEL_FORMAT_08_MONO_OR_RAW):
			PBYTE	pbytePosBGRATable;
			BYTE	bytePos;
			pbytePosBGRATable = (PBYTE)m_pBitmapInfoHeader + sizeof(BITMAPINFOHEADER);
			bytePos = 0;
			do{
				*pbytePosBGRATable++ = bytePos;	//B
				*pbytePosBGRATable++ = bytePos;	//G
				*pbytePosBGRATable++ = bytePos;	//R
				pbytePosBGRATable++;
			}while(bytePos++ != 0xFF);
			m_pBitmapInfoHeader->biBitCount = 8;
			m_pBitmapInfoHeader->biClrUsed = 256;
			m_pBitmapInfoHeader->biClrImportant = 256;
			break;
		case(STCAM_PIXEL_FORMAT_24_BGR):
			m_pBitmapInfoHeader->biBitCount = 24;
			break;
		case(STCAM_PIXEL_FORMAT_32_BGR):
			m_pBitmapInfoHeader->biBitCount = 32;
			break;
		}

		m_bNotSavedFg = TRUE;
		m_bImageDataExist = TRUE;

		//Adjust Window Size
		RECT rcClientSize;
		DWORD dwStyle = GetWindowLong(this->m_hWnd, GWL_STYLE);
		rcClientSize.left = 0;
		rcClientSize.top = 0;
		rcClientSize.right = m_dwWidth;
		rcClientSize.bottom = m_dwHeight;
		
		AdjustWindowRect(&rcClientSize,dwStyle,FALSE);
		SetWindowPos(&wndTop,0,0,rcClientSize.right - rcClientSize.left,rcClientSize.bottom - rcClientSize.top,SWP_NOMOVE | SWP_NOZORDER);

		ShowWindow(SW_SHOW);
		Invalidate(FALSE);
	}
	ReleaseMutex(m_hMutex);
	return(bReval);
}
