#include <windows.h>
#include <commctrl.h>
#include <commdlg.h>
#include <richedit.h>
#include <stdio.h>

#include "header.h"
#include "operands.h"
#include "opcodes.h"
#include <ctype.h>
extern HINSTANCE hInstance ;
extern HWND hwndClient,hwndStatus,hwndFrame ;
extern PROCESS DebugProcess ;
extern enum DebugState uState;


HWND hwndDump ;

static char szDumpClassName[] = "xccMemoryClass" ;

static LOGFONT fontdata = {
	16,0,0,0,FW_NORMAL,FALSE,FALSE,FALSE,ANSI_CHARSET,OUT_DEFAULT_PRECIS,
	CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, FIXED_PITCH | FF_DONTCARE,
	"Courier New"
} ;
static HFONT DumpFont ;
static int DumpAddress ;
void DumpDoPaint(HWND hwnd)
{
	int i ;
		char buf[256],*p ;
		unsigned char chars[17] ;
		PAINTSTRUCT ps ;
		CONTEXT context ;
		HDC dc ;
		HFONT oldFont ;
		RECT rect ;
		int lines ;
		chars[16] = 0 ;
		GetClientRect(hwnd,&rect) ;
		lines = rect.bottom / 16 ;
		dc = BeginPaint(hwnd, &ps) ;
		SelectObject(dc,DumpFont) ;
		for (i=0; i < lines; i++)  {
			int j ;
			sprintf(buf,"%08X: ",DumpAddress + i * 16) ;
			p = buf + strlen(buf) ;
			for (j=0; j < 16; j++) { 
				if (ReadProcessMemory(DebugProcess.hProcess,(LPVOID)(DumpAddress +i*16+j),(LPVOID)(chars +j), 1, 0) ) {
					sprintf(p,"%02X ",chars[j]) ;
				} else {
					strcpy(p,"?? ") ;
					chars[j] = ' ' ;
				}
				if (chars[j] < 32 || chars [j] > 126)
					chars[j] = '.' ;
				p += strlen(p) ;
			}
			strcpy(p,chars) ;
			TextOut(dc,0,i*16,buf,strlen(buf)) ;
		}
		
		SelectObject(dc,oldFont) ;

		EndPaint(hwnd, &ps) ;
}
LRESULT  CALLBACK _export DumpProc( HWND hwnd, UINT iMessage, WPARAM wParam,
																		LPARAM lParam)
{
	static int charwidth ;
	int i,lines ;
	HDC dc ;
	TEXTMETRIC metric ;
	DEBUG_EVENT *xc ;
	HFONT oldFont ;
	LOGBRUSH brushstr ;
	RECT r ;
	switch(iMessage) {
		case WM_SYSCOMMAND :
			if (wParam == SC_CLOSE)
				SendMessage(hwnd,WM_CLOSE,0,0) ;
			break ;
		case WM_COMMAND:
			switch(LOWORD(wParam)) {
				case IDM_GOTO:
					DumpAddress = lParam ;
					InvalidateRect(hwnd,0,0) ;
					break ;
				default:
					return DefMDIChildProc(hwnd,iMessage,wParam,lParam) ;
			}
			break ;
		case WM_PAINT:
			DumpDoPaint(hwnd) ;
			return 0 ;
		case WM_SETFOCUS:
			SendMessage(hwndFrame,WM_REDRAWTOOLBAR,0,0) ;
			break ;
		case WM_KILLFOCUS:
			break ;
		case WM_LBUTTONDOWN:
			break ;
		case WM_CREATE:
			hwndDump = hwnd ;
			DumpFont = CreateFontIndirect(&fontdata) ;
			SetScrollRange(hwnd,SB_VERT,0,64000,FALSE );
			SetScrollPos(hwnd,SB_VERT,32000,TRUE) ;
         break ;
				
		case WM_CLOSE:
			break ;
		case WM_DESTROY:
			hwndDump = 0 ;
			DeleteObject(DumpFont) ;
			break ;
		case WM_SIZE:       
			break ;
		case WM_INITMENUPOPUP:
			return 0 ;
		case WM_VSCROLL:
			GetClientRect(hwnd,&r) ;
			lines = r.bottom/16 ;
			switch(LOWORD(wParam)) {
				case SB_BOTTOM:
					DumpAddress = -(lines * 16) ;
					break ;
				case SB_TOP:
					DumpAddress = 0 ;
					break ;
				case SB_ENDSCROLL:
					return 0 ;
				case SB_LINEDOWN:
					DumpAddress += 16 ;
					break ;
				case SB_LINEUP:
					DumpAddress -= 16 ;
					break ;
				case SB_PAGEDOWN:
					DumpAddress += 16 * ( lines-1) ;
					break ;
				case SB_PAGEUP:
					DumpAddress -= 16 * (lines-1) ;
					break ;
				case SB_THUMBPOSITION:
					DumpAddress += (HIWORD(wParam) - 32000) * 16 ;
					break ;
				case SB_THUMBTRACK :
					return 0 ;
//					return DefMDIChildProc(hwnd,iMessage,wParam,lParam) ;
			}
			InvalidateRect(hwnd,0,0) ;
//			SetScrollPos(hwnd,SB_VERT, 32000,TRUE) ;
			return 0 ;
		default: 
			break ;
	}
	return DefMDIChildProc(hwnd,iMessage,wParam,lParam) ;
}
void RegisterDumpWindow(void)
{
		WNDCLASS wc ;
		wc.style = CS_HREDRAW + CS_VREDRAW ;
		wc.lpfnWndProc = &DumpProc ;
		wc.cbClsExtra = 0;
		wc.cbWndExtra = 0;
		wc.hInstance = hInstance ;
		wc.hIcon = LoadIcon(0,IDI_APPLICATION) ;
		wc.hCursor = LoadCursor(0,IDC_ARROW) ;
		wc.hbrBackground = GetStockObject(WHITE_BRUSH) ;
		wc.lpszMenuName = 0 ;
		wc.lpszClassName = szDumpClassName ;
		RegisterClass(&wc) ;
}
HWND CreateDumpWindow(void)
{
	MDICREATESTRUCT mc ;
	HWND rv ;
	RECT r ;
	if (hwndDump) {
		SendMessage(hwndDump,WM_SETFOCUS,0,0) ;
		return hwndDump ;
	}
	GetClientRect(hwndClient,&r) ;
	mc.szClass = szDumpClassName ;
	mc.szTitle = "Memory Window" ;
	mc.hOwner = hInstance ;
	mc.x =  CW_USEDEFAULT;
	mc.y =  CW_USEDEFAULT;
	mc.cx = 80*8;
	mc.cy = 19*8;
	mc.style = WS_VSCROLL ;
	mc.lParam = 0 ;
	rv = (HWND) SendMessage(hwndClient,WM_MDICREATE,0,(LPARAM)&mc) ;
	return rv ;
}