//	bfe2 - instruction history file
//	Copyright (c) 1999-2003 Brand Huntsman and Lee Salzman
//


#include "common.h"
#include "functions.h"


//////////////////////////////////////////////////////////////////////////

// global

// local
GtkCList *h_list;
FILE *h_logfile;
uint h_repeat, h_length;
uint32 h_last_address;

#define H_COLUMN_TITLES 4
gchar *h_column_titles[] = { "Physical", "Virtual", "Bytes", "Instruction" };

//////////////////////////////////////////////////////////////////////////


void open_history( ){
	h_last_address = 0;
	h_repeat = 0;
	h_length = 0;

	if((h_logfile = fopen(HISTORY_PATH, "w")) == NULL)
		g_print("BFE: Unable to access history log file, logging disabled.\n");
}


//////////////////////////////////////////////////////////////////////////


void historyInit( GtkWidget *vbox ){
	open_history();

	h_list = new_list(vbox, H_COLUMN_TITLES, h_column_titles);
	gtk_clist_column_titles_show(h_list);
	gtk_clist_set_column_justification(h_list, 0, GTK_JUSTIFY_CENTER);
	gtk_clist_set_column_justification(h_list, 1, GTK_JUSTIFY_CENTER);
	gtk_clist_set_column_justification(h_list, 2, GTK_JUSTIFY_LEFT);
	gtk_clist_set_column_justification(h_list, 3, GTK_JUSTIFY_LEFT);
}


void historyReset( ){
	h_last_address = 0;
	h_repeat = 0;
}


void historyClose( ){
	historyRepeat();
	if(h_logfile != NULL) fclose(h_logfile);
}


void historyClear( GtkWidget *widget, gpointer data ){
	gtk_clist_clear(h_list);

	historyClose();
	open_history();
}


void historyUpdate( ){
	char address[LEN_ADDRESS], virtual[LEN_ADDRESS], *row[H_COLUMN_TITLES];

	if(h_last_address != i_physical_address){
		h_last_address = i_physical_address;

		historyRepeat();

		snprintf(address, LEN_ADDRESS, "%.8X", i_physical_address);
		snprintf(virtual, LEN_ADDRESS, "%.4X:%.8X", i_virtual_segment, i_virtual_offset);
		row[0] = address;
		row[1] = virtual;
		row[2] = i_bytes;
		row[3] = i_description;
		gtk_clist_append(h_list, row);
		h_length++;

		if(h_logfile != NULL) fprintf(h_logfile, "%s  %s  [%s]  %s\n",
			address, virtual, i_bytes, i_description);

		historyClip();

		gtk_clist_moveto(h_list, h_length-1, 0, 1.0, 0.0);
		gtk_clist_select_row(h_list, h_length-1, 0);
	} else h_repeat++;
}


#define LEN_TEMP 32
void historyRepeat( ){
	char temp[LEN_TEMP];

	if(h_repeat){
		snprintf(temp, LEN_TEMP, "repeated %u times", h_repeat);
		h_repeat = 0;
		historyWrite(temp);
	}
}


void historyWrite( char *message ){
	char *row[H_COLUMN_TITLES];

	if(h_repeat) historyRepeat();

	row[0] = NULL;
	row[1] = NULL;
	row[2] = NULL;
	row[3] = message;
	gtk_clist_append(h_list, row);
	h_length++;

	if(h_logfile != NULL)
		fprintf(h_logfile, ": %s\n", message);

	historyClip();

	// only instructions are selected
	gtk_clist_moveto(h_list, h_length-1, 0, 1.0, 0.0);
}


void historyClip( ){
	while(h_maxlen < h_length){
		gtk_clist_remove(h_list, 0);
		h_length--;
	}
}
