#ifndef TEST
#include <nds.h>
#else
typedef unsigned char u8;
typedef unsigned short u16;
typedef unsigned long u32;
#endif

#include <stdio.h>
#include <string.h>
#include <ctype.h>

typedef struct Icon_s {
  u16 Version;
  u16 CRC;
  u8  Reserved[28];
  u8  Bitmap[4][4][8][4];
  u16 Palette[16];
  u16 Title[6][128];
} Icon_t;

void NDSIconDetile(u16 *image, u8 *buffer) {
	int row, col, x, y;
	Icon_t *Icon =  (Icon_t*)buffer;
	
	for(row = 0; row<4; row++) {
		for(col = 0; col<4; col++) {
			for(y = 0; y < 8; y++ ) {
				for(x = 0; x < 8; x+=2 ) {
					int c;
					c = Icon->Bitmap[row][col][y][x/2] & 0xf;
					image[((row*8)+y)*32+col*8+x] = Icon->Palette[c];
					c = (Icon->Bitmap[row][col][y][x/2]>>4) & 0xf;
					image[((row*8)+y)*32+col*8+x+1] = Icon->Palette[c];
				}
			}
		}
	}
}

int GetNDSIcon(u16 *image, char *ndsname) {
	u32 Icon_title_offset;
	u8 Icon_title_buffer[0x240];
	FILE *ndsfd;

	if(image==NULL) return 0;

	ndsfd = fopen(ndsname, "r");
	
	if(ndsfd == NULL) return 0;
	
	fseek(ndsfd, 0x68, SEEK_SET);
	fread(&Icon_title_offset, 4, 1, ndsfd);
	
	if(Icon_title_offset <= 0x8000) {
		fclose(ndsfd);
		return 0;
	}
	
	fseek(ndsfd, Icon_title_offset, SEEK_SET);
	fread(Icon_title_buffer, 0x240, 1, ndsfd);
	fclose(ndsfd);

	if( *(u16*)Icon_title_buffer != 0x0001 )
		return 0;

	NDSIconDetile(image, Icon_title_buffer + 0x20);
	
	return 1;
}

#ifdef TEST
char basetmp[256];
char * basename(char *filepath) {
	int i, len, s_pos=0;
	len = strlen(filepath);

	for(i=0; i<len; i++) {
		if(filepath[i] == '/' && filepath[i+1] != 0) s_pos = i+1;
		if(i>255) break;
	}

	for(i=0; i<256; i++) basetmp[i]=0;

	for(i=0; i<len; i++) {
		if(filepath[i+s_pos]=='.') break;
		if(i>255) break;
		basetmp[i] = filepath[i+s_pos];
	}

	return basetmp;
}

int main(int argc, char **argv) {
	int i;
	u16 image[32*32];

	for(i=1; i<argc; i++) {
		memset(image, 0, 32*32);
		if(GetNDSIcon(image, argv[i])) {
			char ofn[256];
			FILE *ofd;
			sprintf(ofn, "%s.raw", basename(argv[i]));
			
			ofd = fopen(ofn, "wb");
			if(ofd!=NULL) {
				u8 pixel[3];
				
				for(i=0; i<(32*32); i++) {
					pixel[0] = (image[i] << 3) & 0xf8;
					pixel[1] = (image[i] >> 2) & 0xf8;
					pixel[2] = (image[i] >> 7) & 0xf8;
					fwrite(pixel, 3, 1, ofd);
				}
				
				fclose(ofd);
			}
		}
	}
	
	return 0;
}
#endif
