/*********************************************************************************
*                                                                               *
* Copyright (c) 2008 Samsung System LSI											*
* All rights reserved.                                                          *
*                                                                               *
* This software is test sample code for MFC v5.0								*
*																				*
* Author : Jiyoung Shin 								    					*	
* Last Changed : 2008.08.05 													*
*********************************************************************************/

#include "resource.h"
#include <windows.h>
#include <commctrl.h>
#include <Commdlg.h>
#include "MfcRender.h"

#define DEBUG_RETAILMSG	1
#define ERROR_RETAILMSG 1

#define APPNAME				TEXT("SPV210 MFC DEMO")
#define APPTITLE			TEXT("SPV210 MFC DEMO")

#define MAX_LOADSTRING 100


typedef struct
{
	//HWND  hWnd;
	BOOL  fForceExit;
	MFCExeMode exeMode;

	// Adding file name variable 
	TCHAR pszFileName[MAX_PATH];

} MM_THREAD_PARAM;

typedef enum {
	START = 0,
	STOP
}ProcStart;



// Global Variables:
HINSTANCE			g_hInst;			// current instance
HWND				g_hWndMenuBar;		// menu bar handle
HWND				ghApp = 0;
HWND				ghDlgMain = 0;
HINSTANCE			ghInst;
MFCExeMode			gMode;
BOOL				gButtonEnableDS;

extern int SsbSipMfcDecoderTest(MFCExeMode exeMode, int *ForceExit);
extern int SsbSipMfcEncoderTest(MFCExeMode exeMode, int *ForceExit);
extern int SsbSipMfcDecDecTest(MFCExeMode exeMode, int *ForceExit);
extern int SsbSipMfcDecEncTest(MFCExeMode exeMode, int *ForceExit);
extern int SsbSipMfcEncEncTest(MFCExeMode exeMode, int *ForceExit);
extern int SsbSipMfcDecoderUnitTest(MFCExeMode exeMode, int *ForceExit);
extern int SsbSipMfcEncoderUnitTest(MFCExeMode exeMode, int *ForceExit);
/*
************************************************************************
Name            : _getMode
Description     : Getting current main mode
Parameter       : void
Return Value    : 	MAIN_MODE				- main dialog
					SINGLE_DECODE			- single decoding + displaying
					SINGLE_ENCODE			- single encoding
					VT_CALL					- H.263 decoding + H.263 encoding
					VT_CALL_DEC				- H.263 decoding + H.263 encoding + decoding
*************************************************************************
*/
static MFCExeMode _getMode(void)
{
	return gMode;
}

/*
************************************************************************
Name            : _setMode
Description     : Setting current main mode
Parameter       : 	MAIN_MODE				- main dialog
					SINGLE_DECODE			- single decoding + displaying
					SINGLE_ENCODE			- single encoding
					VT_CALL					- H.263 decoding + H.263 encoding
					VT_CALL_DEC				- H.263 decoding + H.263 encoding + decoding
*************************************************************************
*/
static void _setMode(MFCExeMode mode)
{
	gMode = mode;
}

/*
************************************************************************
Name            : _setButtonAllDisable
Description     : Disabling All buttons
Parameter       : hwnd     - Window handle for button
Return Value    : void
*************************************************************************
*/
static void _setButtonAllDisable(HWND hwnd)
{
	UINT i;

	for (i=IDC_SINGLE_DEC; i <= IDC_EXIT; i++)
		EnableWindow(GetDlgItem(hwnd, i), FALSE);

}

/*
************************************************************************
Name            : _setButtonAllEnable
Description     : Ensabling All buttons
Parameter       : hwnd     - Window handle for button
Return Value    : void
*************************************************************************
*/
static void _setButtonAllEnable(HWND hwnd)
{
	UINT i;

	for (i=IDC_SINGLE_DEC; i <= IDC_EXIT; i++)
		//if((i != IDC_UNIT_DEC) && (i != IDC_UNIT_ENC))
			EnableWindow(GetDlgItem(hwnd, i), TRUE);

}


static void _setButtonEnableDS(BOOL mode)
{
	gButtonEnableDS = mode;
}

static BOOL _getButtonEnableDS(void)
{
	return gButtonEnableDS;
}

/*
************************************************************************
Name            : setButtonAllEnableDS
Description     : Ensabling All buttons flag
Parameter       : void
Return Value    : void
*************************************************************************
*/
void setButtonAllEnableDS(void)
{
	_setButtonEnableDS(TRUE);
}


static DWORD WINAPI ThreadSingleDecodeWindow(LPVOID pPARAM)
{
	MM_THREAD_PARAM    *p_mm_thread_param;

	if (pPARAM == NULL) {
		return 0x0FFFF;
	}

	p_mm_thread_param = (MM_THREAD_PARAM *) pPARAM;
	p_mm_thread_param->exeMode = _getMode();


	SsbSipMfcDecoderTest(p_mm_thread_param->exeMode,
	            &(p_mm_thread_param->fForceExit));

	return 0;
}

static DWORD WINAPI ThreadDecUnitWindow(LPVOID pPARAM)
{
	MM_THREAD_PARAM    *p_mm_thread_param;

	if (pPARAM == NULL) {
		return 0x0FFFF;
	}

	p_mm_thread_param = (MM_THREAD_PARAM *) pPARAM;
	p_mm_thread_param->exeMode = _getMode();


	SsbSipMfcDecoderUnitTest(p_mm_thread_param->exeMode,
	            &(p_mm_thread_param->fForceExit));

	return 0;
}

static DWORD WINAPI ThreadSingleEncodeWindow(LPVOID pPARAM)
{
	MM_THREAD_PARAM    *p_mm_thread_param;

	if (pPARAM == NULL) {
		return 0x0FFFF;
	}

	p_mm_thread_param = (MM_THREAD_PARAM *) pPARAM;
	p_mm_thread_param->exeMode = _getMode();

	SsbSipMfcEncoderTest(p_mm_thread_param->exeMode,
	            &(p_mm_thread_param->fForceExit));

	return 0;
}

static DWORD WINAPI ThreadEncUnitWindow(LPVOID pPARAM)
{
	MM_THREAD_PARAM    *p_mm_thread_param;

	if (pPARAM == NULL) {
		return 0x0FFFF;
	}

	p_mm_thread_param = (MM_THREAD_PARAM *) pPARAM;
	p_mm_thread_param->exeMode = _getMode();

	SsbSipMfcEncoderUnitTest(p_mm_thread_param->exeMode,
	            &(p_mm_thread_param->fForceExit));

	return 0;
}

static DWORD WINAPI ThreadDecDecWindow(LPVOID pPARAM)
{
	MM_THREAD_PARAM    *p_mm_thread_param;

	if (pPARAM == NULL) {
		return 0x0FFFF;
	}

	p_mm_thread_param = (MM_THREAD_PARAM *) pPARAM;
	p_mm_thread_param->exeMode = _getMode();

	SsbSipMfcDecDecTest(p_mm_thread_param->exeMode,
	            &(p_mm_thread_param->fForceExit));

	return 0;
}

static DWORD WINAPI ThreadDecEncWindow(LPVOID pPARAM)
{
	MM_THREAD_PARAM    *p_mm_thread_param;

	if (pPARAM == NULL) {
		return 0x0FFFF;
	}

	p_mm_thread_param = (MM_THREAD_PARAM *) pPARAM;
	p_mm_thread_param->exeMode = _getMode();

	SsbSipMfcDecEncTest(p_mm_thread_param->exeMode,
	            &(p_mm_thread_param->fForceExit));

	return 0;
}

static DWORD WINAPI ThreadEncEncWindow(LPVOID pPARAM)
{
	MM_THREAD_PARAM    *p_mm_thread_param;

	if (pPARAM == NULL) {
		return 0x0FFFF;
	}

	p_mm_thread_param = (MM_THREAD_PARAM *) pPARAM;
	p_mm_thread_param->exeMode = _getMode();

	SsbSipMfcEncEncTest(p_mm_thread_param->exeMode,
	            &(p_mm_thread_param->fForceExit));

	return 0;
}

static void ProcSingleDecodeWindow(ProcStart StartStop)
{
	static MM_THREAD_PARAM    mm_thread_param;
	static HANDLE  hThread = NULL;

	DWORD  exit_code=0;

	if ((StartStop == STOP) && (hThread != NULL)) {

		// Check if the thread exited already.
		GetExitCodeThread(hThread, &exit_code);
		if (exit_code == STILL_ACTIVE) {	// Thread is running -> Terminate thread.
			mm_thread_param.fForceExit = TRUE;
			WaitForSingleObject(hThread, 2000);
			hThread = NULL;
			// Adding show main dialog
			ShowWindow(ghApp, SW_SHOW);
			SetFocus(ghApp);
			return;
		}
	}

	if (StartStop == START)
	{
		// Start demo thread
		mm_thread_param.fForceExit    = FALSE;
		mm_thread_param.exeMode = SINGLE_DECODE;

		hThread = CreateThread(NULL, 0, 
								ThreadSingleDecodeWindow,
							   (LPVOID)&mm_thread_param,
							   0,
							   NULL);
	}
}

static void ProcDecUnitWindow(ProcStart StartStop)
{
	static MM_THREAD_PARAM    mm_thread_param;
	static HANDLE  hThread = NULL;

	DWORD  exit_code=0;

	if ((StartStop == STOP) && (hThread != NULL)) {

		// Check if the thread exited already.
		GetExitCodeThread(hThread, &exit_code);
		if (exit_code == STILL_ACTIVE) {	// Thread is running -> Terminate thread.
			mm_thread_param.fForceExit = TRUE;
			WaitForSingleObject(hThread, 2000);
			hThread = NULL;
			// Adding show main dialog
			ShowWindow(ghApp, SW_SHOW);
			SetFocus(ghApp);
			return;
		}
	}

	if (StartStop == START)
	{
		// Start demo thread
		mm_thread_param.fForceExit    = FALSE;
		mm_thread_param.exeMode = DEC_UNIT;

		hThread = CreateThread(NULL, 0, 
								ThreadDecUnitWindow,
							   (LPVOID)&mm_thread_param,
							   0,
							   NULL);
	}
}

static void ProcSingleEncodeWindow(ProcStart StartStop)
{
	static MM_THREAD_PARAM    mm_thread_param;
	static HANDLE  hThread = NULL;

	DWORD  exit_code=0;

	if ((StartStop == STOP) && (hThread != NULL)) {
		// Check if the thread exited already.
		GetExitCodeThread(hThread, &exit_code);
		if (exit_code == STILL_ACTIVE) {	// Thread is running -> Terminate thread.
			mm_thread_param.fForceExit = TRUE;
			WaitForSingleObject(hThread, 2000);
			hThread = NULL;
			// Adding show main dialog
			ShowWindow(ghApp, SW_SHOW);
			SetFocus(ghApp);
			return;
		}
	}

	if (StartStop == START)
	{
		// Start demo thread
		mm_thread_param.fForceExit    = FALSE;
		mm_thread_param.exeMode = DEC_UNIT;

		hThread = CreateThread(NULL, 0, 
								ThreadSingleEncodeWindow,
							   (LPVOID)&mm_thread_param,
							   0,
							   NULL);
	}
}

static void ProcEncUnitWindow(ProcStart StartStop)
{
	static MM_THREAD_PARAM    mm_thread_param;
	static HANDLE  hThread = NULL;

	DWORD  exit_code=0;

	if ((StartStop == STOP) && (hThread != NULL)) {
		// Check if the thread exited already.
		GetExitCodeThread(hThread, &exit_code);
		if (exit_code == STILL_ACTIVE) {	// Thread is running -> Terminate thread.
			mm_thread_param.fForceExit = TRUE;
			WaitForSingleObject(hThread, 2000);
			hThread = NULL;
			// Adding show main dialog
			ShowWindow(ghApp, SW_SHOW);
			SetFocus(ghApp);
			return;
		}
	}

	if (StartStop == START)
	{
		// Start demo thread
		mm_thread_param.fForceExit    = FALSE;
		mm_thread_param.exeMode = ENC_UNIT;

		hThread = CreateThread(NULL, 0, 
								ThreadEncUnitWindow,
							   (LPVOID)&mm_thread_param,
							   0,
							   NULL);
	}
}

static void ProcDecDecWindow(ProcStart StartStop)
{
	static MM_THREAD_PARAM    mm_thread_param;
	static HANDLE  hThread = NULL;

	DWORD  exit_code=0;

	if ((StartStop == STOP) && (hThread != NULL)) {
		// Check if the thread exited already.
		GetExitCodeThread(hThread, &exit_code);
		if (exit_code == STILL_ACTIVE) {	// Thread is running -> Terminate thread.
			mm_thread_param.fForceExit = TRUE;
			WaitForSingleObject(hThread, 2000);
			hThread = NULL;
			// Adding show main dialog
			ShowWindow(ghApp, SW_SHOW);
			SetFocus(ghApp);
			return;
		}
	}

	if (StartStop == START)
	{
		// Start demo thread
		mm_thread_param.fForceExit    = FALSE;
		mm_thread_param.exeMode = DEC_DEC;

		hThread = CreateThread(NULL, 0, 
								ThreadDecDecWindow,
							   (LPVOID)&mm_thread_param,
							   0,
							   NULL);
	}
}

static void ProcDecEncWindow(ProcStart StartStop)
{
	static MM_THREAD_PARAM    mm_thread_param;
	static HANDLE  hThread = NULL;

	DWORD  exit_code=0;

	if ((StartStop == STOP) && (hThread != NULL)) {
		// Check if the thread exited already.
		GetExitCodeThread(hThread, &exit_code);
		if (exit_code == STILL_ACTIVE) {	// Thread is running -> Terminate thread.
			mm_thread_param.fForceExit = TRUE;
			WaitForSingleObject(hThread, 2000);
			hThread = NULL;
			// Adding show main dialog
			ShowWindow(ghApp, SW_SHOW);
			SetFocus(ghApp);
			return;
		}
	}

	if (StartStop == START)
	{
		// Start demo thread
		mm_thread_param.fForceExit    = FALSE;
		mm_thread_param.exeMode = DEC_ENC;

		hThread = CreateThread(NULL, 0, 
								ThreadDecEncWindow,
							   (LPVOID)&mm_thread_param,
							   0,
							   NULL);
	}
}

static void ProcEncEncWindow(ProcStart StartStop)
{
	static MM_THREAD_PARAM    mm_thread_param;
	static HANDLE  hThread = NULL;

	DWORD  exit_code=0;

	if ((StartStop == STOP) && (hThread != NULL)) {
		// Check if the thread exited already.
		GetExitCodeThread(hThread, &exit_code);
		if (exit_code == STILL_ACTIVE) {	// Thread is running -> Terminate thread.
			mm_thread_param.fForceExit = TRUE;
			WaitForSingleObject(hThread, 2000);
			hThread = NULL;
			// Adding show main dialog
			ShowWindow(ghApp, SW_SHOW);
			SetFocus(ghApp);
			return;
		}
	}

	if (StartStop == START)
	{
		// Start demo thread
		mm_thread_param.fForceExit    = FALSE;
		mm_thread_param.exeMode = ENC_ENC;

		hThread = CreateThread(NULL, 0, 
								ThreadEncEncWindow,
							   (LPVOID)&mm_thread_param,
							   0,
							   NULL);
	}
}
//-----------------------------------------------------------------------------
// Name: MainDlgProc()
// Desc: The Main Dialog Procedure
//-----------------------------------------------------------------------------
BOOL CALLBACK MainDlgProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	HDC hdc;
	PAINTSTRUCT ps;
	static int overlayAlpha = 50;
	BITMAP      bm_bkg;
	HDC         hdc_mem_bkg;
	HBITMAP MyBitmap, OldBitmap;
	static HANDLE  hThread = NULL;
	DWORD  exit_code=0;
	TCHAR szFilename[MAX_PATH];
	//static MM_THREAD_PARAM mm_thread_param;


	switch (message)
	{
		RETAILMSG(DEBUG_RETAILMSG, (L"MainDlgProc\n"));
		
		case WM_INITDIALOG:
			break;
		case WM_DESTROY:
			//Sending WM_DESTROY to main window for exiting this application 
			RETAILMSG(DEBUG_RETAILMSG, (L"WM_DESTROY.....\n"));
			SendMessage(ghApp, WM_DESTROY, 0, 0);
			break;

		// Destroying the below thread.
		case WM_LBUTTONDOWN:
			switch (_getMode())
			{
				case SINGLE_DECODE :
					RETAILMSG(DEBUG_RETAILMSG, (L"Exit SINGLE_DECODE.....\n"));
					ProcSingleDecodeWindow(STOP);
					break;
				case SINGLE_ENCODE :
					RETAILMSG(DEBUG_RETAILMSG, (L"Exit SINGLE_ENCODE.....\n"));
					ProcSingleEncodeWindow(STOP);
					break;
				case DEC_DEC :
					ProcDecDecWindow(STOP);
					RETAILMSG(DEBUG_RETAILMSG, (L"Exit DEC_DEC.....\n"));
					break;
				case DEC_ENC :
					ProcDecEncWindow(STOP);
					RETAILMSG(DEBUG_RETAILMSG, (L"Exit DEC_ENC.....\n"));
					break;
				case ENC_ENC :
					ProcEncEncWindow(STOP);
					RETAILMSG(DEBUG_RETAILMSG, (L"Exit ENC_ENC.....\n"));
					break;
				case DEC_UNIT :
					ProcDecUnitWindow(STOP);
					RETAILMSG(DEBUG_RETAILMSG, (L"Exit DEC_UNIT.....\n"));
					break;
				case ENC_UNIT :
					ProcEncUnitWindow(STOP);
					RETAILMSG(DEBUG_RETAILMSG, (L"Exit ENC_UNIT.....\n"));
					break;

				default :
					break;
			} // end of switch (_getMode())
			
			_setMode(MAIN_MODE);
			_setButtonAllEnable(hwnd);


			break;

		case WM_PAINT:

			hdc = BeginPaint(hwnd, &ps);
			
			//hdc_mem_bkg = CreateCompatibleDC(hdc);

			//DeleteDC(hdc_mem_bkg);
			
			EndPaint(hwnd, &ps);

			
			if (_getButtonEnableDS())
			{
				_setButtonAllEnable(hwnd);
				_setButtonEnableDS(FALSE);
			}

			break;

		case WM_NOTIFY:
			break;

		// Showing alpha demo with changing alpha blending value.
		case WM_TIMER:
			break;

		// Executing the handler invoked by user
		case WM_COMMAND:
			TCHAR szFilename[MAX_PATH];

			switch (wParam)
			{	
				case IDOK:
					break;

				case IDCANCEL:
					PostMessage(hwnd, WM_DESTROY, 0, 0);
					break;

				// Opening the video clip and playing it with MFC API
				case IDC_SINGLE_DEC:

					_setMode(SINGLE_DECODE);
					RETAILMSG(DEBUG_RETAILMSG, (L"Start SINGLE_DECODE\n"));

					ProcSingleDecodeWindow(START);
					_setButtonAllDisable(hwnd);
					break;

				// Executing multi-decoding
				case IDC_SINGLE_ENC:
					_setMode(SINGLE_ENCODE);
					RETAILMSG(DEBUG_RETAILMSG, (L"Start SINGLE_ENCODE\n"));

					ProcSingleEncodeWindow(START);
					_setButtonAllDisable(hwnd);
					break;

				// Opening the JPEG file and playing it.
				case IDC_DEC_DEC:
					_setMode(DEC_DEC);
					RETAILMSG(DEBUG_RETAILMSG, (L"Start DEC_DEC\n"));

					ProcDecDecWindow(START);
					_setButtonAllDisable(hwnd);
					break;

				// Opening the MP3 file and playing it.
				case IDC_DEC_ENC:
					_setMode(DEC_ENC);
					RETAILMSG(DEBUG_RETAILMSG, (L"Start DEC_ENC\n"));

					ProcDecEncWindow(START);
					_setButtonAllDisable(hwnd);
					break;

				// Opening the MP3 file and playing it.
				case IDC_ENC_ENC:
					_setMode(ENC_ENC);
					RETAILMSG(DEBUG_RETAILMSG, (L"Start ENC_ENC\n"));

					ProcEncEncWindow(START);
					_setButtonAllDisable(hwnd);
					break;

				case IDC_UNIT_DEC:
					_setMode(DEC_UNIT);
					RETAILMSG(DEBUG_RETAILMSG, (L"Start DEC_UNIT\n"));

					ProcDecUnitWindow(START);
					_setButtonAllDisable(hwnd);
					break;

				case IDC_UNIT_ENC:
					_setMode(ENC_UNIT);
					RETAILMSG(DEBUG_RETAILMSG, (L"Start ENC_UNIT\n"));

					ProcEncUnitWindow(START);
					_setButtonAllDisable(hwnd);
					break;

				case IDC_EXIT:
					PostMessage(hwnd, WM_DESTROY, 0, 0);

					break;

			}   // end of switch (wParam)
			break;  // case : WM_COMMAND
		default:
			return FALSE;
	}
	return TRUE;
}

//-----------------------------------------------------------------------------
// Name: WindowProc()
// Desc: The Main Window Procedure
//-----------------------------------------------------------------------------
long FAR PASCAL
WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	PAINTSTRUCT ps;
	HDC         hdc;

	switch (message)
	{
		case WM_CREATE:
			_setMode(MAIN_MODE);
			break;

		case WM_DESTROY:
			PostQuitMessage(0);
			return 0L;

		case WM_LBUTTONDOWN:
			break;

		case WM_PAINT:
			hdc = BeginPaint(hWnd, &ps);

     		EndPaint(hWnd, &ps);
			break;

		case WM_COMMAND:
			switch (wParam)
			{
				case IDD_DIALOG_MAIN:
					ShowWindow(ghDlgMain, SW_SHOW);
					break;

			}

			break;
	}

	return DefWindowProc(hWnd, message, wParam, lParam);
}

//-----------------------------------------------------------------------------
// Name: InitApp()
// Desc: Do work required for every instance of the application:
//          Create the window, initialize data
//-----------------------------------------------------------------------------
static HWND
InitApp(HINSTANCE hInstance, int nCmdShow)
{
	HWND                        hWnd;
	WNDCLASS                    wc;

    // Initialize COM
    if(FAILED(CoInitializeEx(NULL, COINIT_MULTITHREADED)))
    {
        RETAILMSG(ERROR_RETAILMSG, (TEXT("CoInitialize Failed!\r\n")));
        exit(1);
    }
	
	// Set up and register window class
	wc.style = CS_HREDRAW | CS_VREDRAW;
	wc.lpfnWndProc = WindowProc;
	wc.cbClsExtra = 0;
	wc.cbWndExtra = 0;
	wc.hInstance = hInstance;
	wc.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_MFCTESTAPP_ICON));
	wc.hCursor = LoadCursor(NULL, IDC_ARROW);
	wc.hbrBackground = (HBRUSH )GetStockObject(BLACK_BRUSH);
	wc.lpszMenuName = NULL;
	wc.lpszClassName = APPNAME;
	RegisterClass(&wc);

	ghInst = hInstance;

	// Create a window
	ghApp = hWnd = CreateWindow(
						APPNAME,
	                    APPTITLE,
	                    WS_POPUP|WS_OVERLAPPED|WS_CAPTION|WS_SYSMENU|WS_THICKFRAME,
	                    0,
	                    0,
	                    GetSystemMetrics(SM_CXSCREEN),
	                    GetSystemMetrics(SM_CYSCREEN),
	                    NULL,
	                    NULL,
	                    hInstance,
	                    NULL);
	if (!hWnd)
	{
		CoUninitialize();
		return NULL;
	}

	// For using slider control, spin control
	INITCOMMONCONTROLSEX icex;
	icex.dwSize = sizeof(INITCOMMONCONTROLSEX);
	icex.dwICC = ICC_BAR_CLASSES;
	InitCommonControlsEx(&icex);	
	

	// Creating Main Dialog Box
	ghDlgMain = CreateDialog(hInstance, MAKEINTRESOURCE(IDD_DIALOG_MAIN), ghApp, (DLGPROC)MainDlgProc);
	
	if (NULL == ghDlgMain)
	{
		RETAILMSG(1, (L"Cannot create main dialog!\n"));
		return NULL;
	}

	ShowWindow(hWnd, SW_SHOWNORMAL /*nCmdShow*/);

	SetForegroundWindow(hWnd);
	PostMessage(hWnd, WM_COMMAND, IDD_DIALOG_MAIN, 0);
	
	return hWnd;
}



int WINAPI WinMain(HINSTANCE hInstance,
                   HINSTANCE hPrevInstance,
                   LPTSTR    lpCmdLine,
                   int       nCmdShow)
{
	HWND     hWnd;
	MSG      msg;
	MM_THREAD_PARAM    *p_mm_thread_param;

#if 1
	// Load the bitmap image which will be on the main window.
	hWnd = InitApp(hInstance, nCmdShow);
	if (hWnd == NULL)
		return FALSE;

	while (GetMessage(&msg, NULL, 0, 0)) {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }

	CoUninitialize();

	DestroyWindow(ghDlgMain);
#else
	p_mm_thread_param = (MM_THREAD_PARAM *)malloc(sizeof(MM_THREAD_PARAM));
	p_mm_thread_param->exeMode = SINGLE_DECODE;


	//SsbSipMfcDecoderTest(p_mm_thread_param->exeMode,
	//            &(p_mm_thread_param->fForceExit));

	SsbSipMfcEncoderTest(p_mm_thread_param->exeMode, 
				  &(p_mm_thread_param->fForceExit));
#endif

    return msg.wParam;
}

