/*
	WinSTon

	Memory Tab Control
*/

#include "..\includes\winston.h"
#include "..\includes\debug.h"
#include "..\includes\debugger.h"
#include "..\includes\debuggertab.h"
#include "..\includes\decode.h"
#include "..\includes\dialog.h"
#include "..\includes\stmemory.h"

#ifdef USE_DEBUGGER

#define BYTES_PER_LINE				16
#define LINES_IN_MEMORY_LISTVIEW	10

int MemoryListView_Address_Tabs[] = { 0 };
int MemoryListView_Hex_Tabs[] = { 0,16,32,48,64,80,96,112, 138,154,170,186,202,218,234,250 };
int MemoryListView_Ascii_Tabs[] = { 0,7,14,21,28,35,42,49, 56,63,70,77,84,91,98,105 };

//-----------------------------------------------------------------------
/*
	Init Memory Tab Control
*/
void Debugger_TabMemory_Init(HWND hWnd)
{
	HWND hItem;
	char szString[256];

	// Set to select full-row
	hItem = GetDlgItem(DebughWnd,IDC_TABMEMORY_LISTVIEW);
	ListView_SetExtendedListViewStyle(hItem,LVS_EX_FULLROWSELECT|LVS_EX_SUBITEMIMAGES);

	// Add Columns
	Dialog_AddListViewColumn(DebughWnd,IDC_TABMEMORY_LISTVIEW,0,"Address",100);
	Dialog_AddListViewColumn(DebughWnd,IDC_TABMEMORY_LISTVIEW,1,"Hex",280);
	Dialog_AddListViewColumn(DebughWnd,IDC_TABMEMORY_LISTVIEW,2,"Ascii",150);

	// 0...0xFFFFFF, 16 bytes per line
	ListView_SetItemCountEx(hItem,0x1000000/BYTES_PER_LINE,LVSICF_NOSCROLL);

	// Set default address
	sprintf(szString,"%X",0);
	SetDlgItemText(DebughWnd,IDC_TABMEMORY_EDIT,szString);
}

//-----------------------------------------------------------------------
/*
	Show Memory Tab Control
*/
void Debugger_TabMemory_ShowPage(HWND hWnd,BOOL bShow)
{
	// NOTE : Control IDs must be consecutive in resource editor! Ie hand-edited
	Dialog_ShowItemRange(hWnd,IDC_TABMEMORY_EDIT,IDC_TABMEMORY_LISTVIEW,bShow ? SW_SHOW:SW_HIDE);
}

//-----------------------------------------------------------------------
/*
	Build strings for ListView
*/
void Debugger_TabMemory_BuildLine(unsigned long Address, char *pszAddressString, char *pszHexString, char *pszAsciiString)
{
	unsigned char Bytes[BYTES_PER_LINE],Chars[BYTES_PER_LINE];
	unsigned char *pSTChars;
	int i;

	// Mask address to 24-bit
	Address = Address&0xffffff;

	// Copy bytes
	pSTChars = (unsigned char *)((unsigned long)STRam+Address);
	for(i=0; i<BYTES_PER_LINE; i++) {
		Bytes[i] = Chars[i] = *pSTChars++;
		// Is char valid? If not, show a space
		if ( (Chars[i]<32) || (Chars[i]==127) )
			Chars[i] = ' ';
	}

	// Create string to write to listbox 'addr:hex data:chars'
	sprintf(pszAddressString,"%8.8X",Address);
	sprintf(pszHexString,"%2.2X\t%2.2X\t%2.2X\t%2.2X\t%2.2X\t%2.2X\t%2.2X\t%2.2X\t%2.2X\t%2.2X\t%2.2X\t%2.2X\t%2.2X\t%2.2X\t%2.2X\t%2.2X"
	 ,Bytes[0],Bytes[1],Bytes[2],Bytes[3],Bytes[4],Bytes[5],Bytes[6],Bytes[7]
	 ,Bytes[8],Bytes[9],Bytes[10],Bytes[11],Bytes[12],Bytes[13],Bytes[14],Bytes[15]);
	sprintf(pszAsciiString,"%c\t%c\t%c\t%c\t%c\t%c\t%c\t%c\t%c\t%c\t%c\t%c\t%c\t%c\t%c\t%c"
	 ,Chars[0],Chars[1],Chars[2],Chars[3],Chars[4],Chars[5],Chars[6],Chars[7]
	 ,Chars[8],Chars[9],Chars[10],Chars[11],Chars[12],Chars[13],Chars[14],Chars[15] );
}

//-----------------------------------------------------------------------
/*
	Update Memory Tab Control
*/
void Debugger_TabMemory_UpdateDisplay(HWND hWnd)
{
	HWND hItem;
	int Address;

	// Update all items in list view
	hItem = GetDlgItem(DebughWnd,IDC_TABMEMORY_LISTVIEW);
	Address = GetScrollPos(hItem,SB_VERT);
	ListView_RedrawItems(hItem,Address,Address+LINES_IN_MEMORY_LISTVIEW);
	UpdateWindow(hItem);
}

//-----------------------------------------------------------------------
/*
	Draw Memory Tab Control
*/
void Debugger_TabMemory_Draw(DRAWITEMSTRUCT *pDrawItem)
{
	char szStrings[3][256];
	char *pszStrings[3] = { szStrings[0],szStrings[1],szStrings[2] };
	int *pszTabs[3] = { MemoryListView_Address_Tabs,MemoryListView_Hex_Tabs,MemoryListView_Ascii_Tabs };
	unsigned long Address;
	int i;

	// Draw each line in list view
	Address = GetScrollPos(pDrawItem->hwndItem,SB_VERT) * BYTES_PER_LINE;
	for(i=0; i<LINES_IN_MEMORY_LISTVIEW; i++) {
		// Draw text
		Debugger_TabMemory_BuildLine(Address,pszStrings[0],pszStrings[1],pszStrings[2]);
		Debugger_Tab_DrawListViewStrings(pDrawItem,pszStrings,pszTabs,3,i);

		Address+=16;
	}
}

//-----------------------------------------------------------------------
/*
	Set Memory Tab view to address
*/
void Debugger_TabMemory_SetAddress(unsigned long Address)
{
	HWND hItem;

	// Limit to 24-bit
	Address &= 0x00ffffff;
	Address /= BYTES_PER_LINE;

	// Scroll to item
	hItem = GetDlgItem(DebughWnd,IDC_TABMEMORY_LISTVIEW);
	ListView_Scroll(hItem,0,-GetScrollPos(hItem,SB_VERT)*LISTVIEW_ITEMHEIGHT);
	ListView_Scroll(hItem,0,Address*LISTVIEW_ITEMHEIGHT);
}
#endif	//USE_DEBUGGER
