/* $Id$ */
/* 
 * Copyright (C)2003-2008 Benny Prijono <benny@prijono.org>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
 */
#include "test.h"

#include <pj/string.h>
#include <pj/unicode.h>
#include <pj/sock.h>
#include <pj/log.h>

#define WIN32_LEAN_AND_MEAN
#define NONAMELESSUNION
#include <windows.h>
#include <commctrl.h>
#include <tchar.h>

#define MAX_LOADSTRING	    100
#define THIS_FILE	    "main_win32.c"

#define IDC_HELLO_WINCE	    3
#define ID_LOGWINDOW	    104


ATOM			    MyRegisterClass	(HINSTANCE, LPTSTR);
BOOL			    InitInstance	(HINSTANCE, int);
LRESULT CALLBACK	    WndProc		(HWND, UINT, WPARAM, LPARAM);


extern int		    param_log_decor;	// in test.c

static HINSTANCE	    hInst;
static HWND		    hwndLog;
static HFONT		    hFixedFont;


static void write_log(int level, const char *data, int len)
{
    PJ_DECL_UNICODE_TEMP_BUF(wdata,256);

    PJ_UNUSED_ARG(level);
    PJ_UNUSED_ARG(len);
    SendMessage(hwndLog, EM_REPLACESEL, FALSE, 
		(LPARAM)PJ_STRING_TO_NATIVE(data,wdata,256));
}


int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, 
		   LPTSTR lpCmdLine, int nCmdShow)
{
    MSG msg;
    
    PJ_UNUSED_ARG(lpCmdLine);
    PJ_UNUSED_ARG(hPrevInstance);

    
    if (!InitInstance (hInstance, nCmdShow))
	return FALSE;
    
    pj_log_set_log_func( &write_log );
    param_log_decor = PJ_LOG_HAS_NEWLINE | PJ_LOG_HAS_CR;

    // Run the test!
    test_main();

    PJ_LOG(3,(THIS_FILE,""));
    PJ_LOG(3,(THIS_FILE,"Press ESC to quit"));

    // Message loop, waiting to quit.
    while (GetMessage(&msg, NULL, 0, 0)) {
	TranslateMessage(&msg);
	DispatchMessage(&msg);
    }
    
    DeleteObject(hFixedFont);
    return msg.wParam;
}


#ifdef _CONSOLE
int main()
{
    return WinMain(GetModuleHandle(NULL), NULL, NULL, SW_SHOW);
}
#endif


ATOM MyRegisterClass(HINSTANCE hInstance, LPTSTR szWindowClass)
{
    WNDCLASS	wc;
    
    wc.style		= CS_HREDRAW | CS_VREDRAW;
    wc.lpfnWndProc	= (WNDPROC) WndProc;
    wc.cbClsExtra	= 0;
    wc.cbWndExtra	= 0;
    wc.hInstance	= hInstance;
    ///wc.hIcon		= LoadIcon(hInstance, MAKEINTRESOURCE(IDI_HELLO_WINCE));
    wc.hIcon		= NULL;
    wc.hCursor		= 0;
    wc.hbrBackground	= (HBRUSH) GetStockObject(WHITE_BRUSH);
    wc.lpszMenuName	= 0;
    wc.lpszClassName	= szWindowClass;
    
    return RegisterClass(&wc);
}


BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
    HWND	hWnd;
    TCHAR	*szTitle = _T("PJSIP Test");
    TCHAR	*szWindowClass = _T("PJSIP_TEST");
    LOGFONT	lf;


    memset(&lf, 0, sizeof(lf));
    lf.lfHeight = 13;
#if PJ_NATIVE_STRING_IS_UNICODE
    wcscpy(lf.lfFaceName, _T("Courier New"));
#else
    strcpy(lf.lfFaceName, "Lucida Console");
#endif

    hFixedFont = CreateFontIndirect(&lf);
    if (!hFixedFont)
	return FALSE;

    hInst = hInstance;
    
    MyRegisterClass(hInstance, szWindowClass);
    
    hWnd = CreateWindow(szWindowClass, szTitle, WS_VISIBLE,
		        CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, 
			CW_USEDEFAULT, NULL, NULL, hInstance, NULL);
    
    if (!hWnd)
	return FALSE;
    
    ShowWindow(hWnd, nCmdShow);
    UpdateWindow(hWnd);

    if (hwndLog) {
	SendMessage(hwndLog, WM_SETFONT, (WPARAM) hFixedFont, (LPARAM) 0);  
	ShowWindow(hwndLog, TRUE);
    }

    return TRUE;
}


LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    RECT rt;
    DWORD dwStyle;
    
    switch (message) 
    {
    case WM_CREATE:
	// Create text control.
	GetClientRect(hWnd, &rt);
	dwStyle = WS_CHILD | WS_VISIBLE | WS_HSCROLL | WS_VSCROLL | 
		  WS_BORDER | ES_LEFT | ES_MULTILINE | ES_NOHIDESEL |
		  ES_AUTOHSCROLL | ES_AUTOVSCROLL | ES_READONLY; 
	hwndLog = CreateWindow( TEXT("edit"),	    // class
				NULL,		    // window text
				dwStyle,	    // style
				0,		    // x-left
				0,		    // y-top
				rt.right-rt.left,   // w
				rt.bottom-rt.top,   // h
				hWnd,		    // parent
				(HMENU)ID_LOGWINDOW,// id
				hInst,		    // instance
				NULL);		    // NULL for control.
	break;
    case WM_ACTIVATE:
	if (LOWORD(wParam) == WA_INACTIVE)
	    DestroyWindow(hWnd);
	break;
    case WM_CHAR:
	if (wParam == 27) {
	    DestroyWindow(hWnd);
	}
	break;
    case WM_CLOSE:
	DestroyWindow(hWnd);
	break;
    case WM_DESTROY:
	PostQuitMessage(0);
	break;
    default:
	return DefWindowProc(hWnd, message, wParam, lParam);
    }
    return 0;
}

