/*
 * Utility functions for debugging and displaying text,
 * including build information ("About" text)
 *
 * Graham R. Cobb			13 Dec 2001
 */

#include "rex/rex.h"
#include <stdlib.h> 
#include <string.h>
#include "build_info.h"

/* Function prototypes */
extern void trace (unsigned short s, unsigned short n1, unsigned short n2);
extern void debug (char *s, unsigned short n1, unsigned short n2);
extern char *utoh (char *str, unsigned short n);
extern void wait_for_key();
extern void display_about (char *about_text);

const char *title=BUILD_TITLE " V" BUILD_FULL_VER ": " BUILD_DATE " - " BUILD_AUTHOR;

const char *about=BUILD_TITLE " by " BUILD_AUTHOR ".\nVersion " BUILD_FULL_VER " built by " \
	BUILD_BUILDER " on " BUILD_HOST " at " BUILD_TIME " " BUILD_DATE "." ;

#define LINE_LENGTH 40
#define ROW_HEIGHT 12
#define true 1

/*
 * Debug output -- overwrites top line of screen
 */
void trace (unsigned short s, unsigned short n1, unsigned short n2)
{
  char buffer[7];
  DsDisplayBlockClear(0,0,240,ROW_HEIGHT); // x, y, width, height
  DsPrintf(0,0,0,"TRACE:");
  DsPrintf(160,0,0,"Press any key");
  utoh(buffer, s); DsPrintf(40,0,0,buffer); 
  utoh(buffer, n1); DsPrintf(80,0,0,buffer); 
  utoh(buffer, n2); DsPrintf(120,0,0,buffer);
  wait_for_key();
  DsDisplayBlockClear(160,0,120,ROW_HEIGHT); // x, y, width, height
}
void debug (char *s, unsigned short n1, unsigned short n2)
{
  char buffer[7];
  DsDisplayBlockClear(0,0,240,ROW_HEIGHT); // x, y, width, height
  DsPrintf(0,0,0,"DEBUG:");
  DsPrintf(160,0,0,"Press any key");
  utoh(buffer, n1); DsPrintf(40,0,0,buffer); 
  utoh(buffer, n2); DsPrintf(80,0,0,buffer); 
  DsPrintf(120,0,0,s);
  wait_for_key();
  DsDisplayBlockClear(160,0,120,ROW_HEIGHT); // x, y, width, height
}

/*
 * Hex print 16 bit value
 */
char *utoh(char *str, unsigned short n)
{
	const char *hdigit="0123456789ABCDEF";
	str[0]='0';
	str[1]='x';
	str[2]=hdigit[(n/0x1000) & 0xf];
	str[3]=hdigit[(n/0x100) & 0xf];
	str[4]=hdigit[(n/0x10) & 0xf];
	str[5]=hdigit[(n) & 0xf];
	str[6]='\0';
	return str;
}

/*
 * Wait for a button press (actually for a button release)
 */
void wait_for_key()
{
  MSG msg;
  while(true) { // Wait for key release
	  DsEventMessageGet(msg);

	  if (msg.message == MSG_DS_CLOSE) break;
	  
	  if ((msg.message == MSG_DS_KEY_DOWN) &&
		  ((msg.sCode == KEY_TOP_C) ||
		   (msg.sCode == KEY_TOP_E) ||
		   (msg.sCode == KEY_BACK_C) ||
		   (msg.sCode == KEY_BACK_E) ||
		   (msg.sCode == KEY_ENTER_C) ||
		   (msg.sCode == KEY_ENTER_E) ||
  		   (msg.sCode == KEY_UP_C) ||
		   (msg.sCode == KEY_UP_E) ||
		   (msg.sCode == KEY_DOWN_C) ||
		   (msg.sCode == KEY_DOWN_E))
	  	) break;
  }
}

/*
 * Display an "About" string (or any other string) as a full-screen
 * message, with line breaks on \n or after LINE_LENGTH characters
 *
 * Waits for a key press before continuing.
 *
 */
void display_about (char *about_text)
{
  char tmpbuf[LINE_LENGTH+1];
  char *current_ptr;
  int num_chars, row;
  
  DsClearScreen();

  current_ptr=about_text;
  row=0;
  
  while (current_ptr[0] != '\0') {
	  
	/* Skip leading whitespace */
	current_ptr += strspn(current_ptr," \t\n\r");
	
	/* Find end of line */
  	num_chars = strcspn(current_ptr,"\n");
  	
  	/* Is the line too long? */
  	while (num_chars > LINE_LENGTH) {
		/* Try to find a space to split the line */
		for (num_chars--;num_chars>0;num_chars--) {// Work backwards from end of line
			if (current_ptr[num_chars]==' ') {
				break;
			}
		}
		if (num_chars == 0) num_chars=LINE_LENGTH; // No space found, break at line length
	}
  	
  	/* Display line */
  	strncpy(tmpbuf,current_ptr,num_chars);
  	tmpbuf[num_chars]='\0';
  	DsDisplayBlockClear(0,row,240,ROW_HEIGHT);
  	DsPrintf(0,row,0,tmpbuf);
  	
  	current_ptr += num_chars;
  	row += ROW_HEIGHT;
	}
  
  DsDisplayBlockClear(0,row,240,ROW_HEIGHT); // x, y, width, height
  DsPrintf(0,row,0,"Press any key to continue");
  wait_for_key();
  DsDisplayBlockClear(0,row,240,ROW_HEIGHT); // x, y, width, height
}

