#include <vstypes.h>
#include <lcd.h>
#include <rgb565.h>
#include "lcdstuff.h"
#include <string.h>
#include <volink.h>
#include "usemodel.h"
#include "screenlayout.h"

// Access font data in VS1005G ROM
extern const u_int32 font16a[];
extern const u_int16 font16aptrs[];

void (*StdRender)(register struct stdButtonStruct *button, register u_int16 op, register u_int16 x, register u_int16 y);
u_int16 currentScreen;

const __mem_y u_int16 lcdNumData[] = {	
	// Glyph 0
	0xFCFE, 0xFDFB, 0xF71F, 0x1F1F, 0x11FF, 0xFFFF, 0xFEFC, // stripe 1
	0xFFFF, 0xFFFF, 0xFF00, 0x0000, 0x00FF, 0xFFFF, 0xFFFF, // stripe 2
	0xFF7F, 0x7F3F, 0x1F00, 0x0000, 0x001F, 0x3F7F, 0x7FFF, // stripe 3
	0xFFFF, 0xFFFE, 0xFC00, 0x0000, 0x00FC, 0xFEFF, 0xFFFF, // stripe 4
	0xFFFF, 0xFFFF, 0xFF00, 0x0000, 0x00FF, 0xFFFF, 0xFFFF, // stripe 5
	0x3F7F, 0xBFDF, 0xEFF8, 0xF8F8, 0x88FF, 0xFFFF, 0x7F3F, // stripe 6
	
	// Glyph 1
	0x0000, 0x0000, 0x0000, 0x0000, 0x00FF, 0xFFFF, 0xFEFC, // stripe 1
	0x0000, 0x0000, 0x0000, 0x0000, 0x00FF, 0xFFFF, 0xFFFF, // stripe 2
	0x0000, 0x0000, 0x0000, 0x0000, 0x001F, 0x3F7F, 0x7FFF, // stripe 3
	0x0000, 0x0000, 0x0000, 0x0000, 0x00FC, 0xFEFF, 0xFFFF, // stripe 4
	0x0000, 0x0000, 0x0000, 0x0000, 0x00FF, 0xFFFF, 0xFFFF, // stripe 5
	0x0000, 0x0000, 0x0000, 0x0000, 0x00FF, 0xFFFF, 0x7F3F, // stripe 6
	
	// Glyph 2
	0x0000, 0x0103, 0x071F, 0x1F1F, 0x11FF, 0xFFFF, 0xFEFC, // stripe 1
	0x0000, 0x0000, 0x0000, 0x0000, 0x00FF, 0xFFFF, 0xFFFF, // stripe 2
	0x0000, 0x0080, 0xC0E0, 0xE0E0, 0xE0DF, 0xBF7F, 0x7F7F, // stripe 3
	0xFFFF, 0xFFFE, 0xFD03, 0x0303, 0x0301, 0x0000, 0x0000, // stripe 4
	0xFFFF, 0xFFFF, 0xFF00, 0x0000, 0x0000, 0x0000, 0x0000, // stripe 5
	0x3F7F, 0xBFDF, 0xEFF8, 0xF8F8, 0x0000, 0x0000, 0x0000, // stripe 6
	
	// Glyph 3
	0x0000, 0x0103, 0x071F, 0x1F1F, 0x11FF, 0xFFFF, 0xFEFC, // stripe 1
	0x0000, 0x0000, 0x0000, 0x0000, 0x00FF, 0xFFFF, 0xFFFF, // stripe 2
	0x0000, 0x0080, 0xC0E0, 0xE0E0, 0xE0DF, 0xBF7F, 0x7FFF, // stripe 3
	0x0000, 0x0000, 0x0103, 0x0303, 0x03FD, 0xFEFF, 0xFFFF, // stripe 4
	0x0000, 0x0000, 0x0000, 0x0000, 0x00FF, 0xFFFF, 0xFFFF, // stripe 5
	0x0000, 0x80C0, 0xE0F0, 0xF8F8, 0x88FF, 0xFFFF, 0x7F3F, // stripe 6
	
	// Glyph 4
	0xFCFE, 0xFCF8, 0xF000, 0x0000, 0x00FF, 0xFFFF, 0xFEFC, // stripe 1
	0xFFFF, 0xFFFF, 0xFF00, 0x0000, 0x00FF, 0xFFFF, 0xFFFF, // stripe 2
	0x7F7F, 0x7FBF, 0xDFE0, 0xE0E0, 0xE0DF, 0xBF7F, 0x7FFF, // stripe 3
	0x0000, 0x0000, 0x0103, 0x0303, 0x03FD, 0xFEFF, 0xFFFF, // stripe 4
	0x0000, 0x0000, 0x0000, 0x0000, 0x00FF, 0xFFFF, 0xFFFF, // stripe 5
	0x0000, 0x0000, 0x0000, 0x0000, 0x00FF, 0xFFFF, 0x7F3F, // stripe 6
	
	// Glyph 5
	0xFCFE, 0xFDFB, 0xF71F, 0x1F1F, 0x0000, 0x0000, 0x0000, // stripe 1
	0xFFFF, 0xFFFF, 0xFF00, 0x0000, 0x0000, 0x0000, 0x0000, // stripe 2
	0x7F7F, 0x7FBF, 0xDFE0, 0xE0E0, 0xE0C0, 0x8000, 0x0000, // stripe 3
	0x0000, 0x0000, 0x0103, 0x0303, 0x03FD, 0xFEFF, 0xFFFF, // stripe 4
	0x0000, 0x0000, 0x0000, 0x0000, 0x00FF, 0xFFFF, 0xFFFF, // stripe 5
	0x0000, 0x80C0, 0xE0F0, 0xF8F8, 0x88FF, 0xFFFF, 0x7F3F, // stripe 6
	
	// Glyph 6
	0xFCFE, 0xFDFB, 0xF71F, 0x1F1F, 0x0000, 0x0000, 0x0000, // stripe 1
	0xFFFF, 0xFFFF, 0xFF00, 0x0000, 0x0000, 0x0000, 0x0000, // stripe 2
	0xFF7F, 0x7FBF, 0xDFE0, 0xE0E0, 0xE0C0, 0x8000, 0x0000, // stripe 3
	0xFFFF, 0xFFFE, 0xFD03, 0x0303, 0x03FD, 0xFEFF, 0xFFFF, // stripe 4
	0xFFFF, 0xFFFF, 0xFF00, 0x0000, 0x00FF, 0xFFFF, 0xFFFF, // stripe 5
	0x3F7F, 0xBFDF, 0xEFF8, 0xF8F8, 0x88FF, 0xFFFF, 0x7F3F, // stripe 6
	
	// Glyph 7
	0x0000, 0x0103, 0x070F, 0x1F1F, 0x11FF, 0xFFFF, 0xFEFC, // stripe 1
	0x0000, 0x0000, 0x0000, 0x0000, 0x00FF, 0xFFFF, 0xFFFF, // stripe 2
	0x0000, 0x0000, 0x0000, 0x0000, 0x001F, 0x3F7F, 0x7FFF, // stripe 3
	0x0000, 0x0000, 0x0000, 0x0000, 0x00FC, 0xFEFF, 0xFFFF, // stripe 4
	0x0000, 0x0000, 0x0000, 0x0000, 0x00FF, 0xFFFF, 0xFFFF, // stripe 5
	0x0000, 0x0000, 0x0000, 0x0000, 0x00FF, 0xFFFF, 0x7F3F, // stripe 6
	
	// Glyph 8
	0xFCFE, 0xFDFB, 0xF71F, 0x1F1F, 0x11FF, 0xFFFF, 0xFEFC, // stripe 1
	0xFFFF, 0xFFFF, 0xFF00, 0x0000, 0x00FF, 0xFFFF, 0xFFFF, // stripe 2
	0xFF7F, 0x7FBF, 0xDFE0, 0xE0E0, 0xE0DF, 0xBF7F, 0x7FFF, // stripe 3
	0xFFFF, 0xFFFE, 0xFD03, 0x0303, 0x03FD, 0xFEFF, 0xFFFF, // stripe 4
	0xFFFF, 0xFFFF, 0xFF00, 0x0000, 0x00FF, 0xFFFF, 0xFFFF, // stripe 5
	0x3F7F, 0xBFDF, 0xEFF8, 0xF8F8, 0x88FF, 0xFFFF, 0x7F3F, // stripe 6
	
	// Glyph 9
	0xFCFE, 0xFDFB, 0xF71F, 0x1F1F, 0x11FF, 0xFFFF, 0xFEFC, // stripe 1
	0xFFFF, 0xFFFF, 0xFF00, 0x0000, 0x00FF, 0xFFFF, 0xFFFF, // stripe 2
	0x7F7F, 0x7FBF, 0xDFE0, 0xE0E0, 0xE0DF, 0xBF7F, 0x7FFF, // stripe 3
	0x0000, 0x0000, 0x0103, 0x0303, 0x03FD, 0xFEFF, 0xFFFF, // stripe 4
	0x0000, 0x0000, 0x0000, 0x0000, 0x00FF, 0xFFFF, 0xFFFF, // stripe 5
	0x0000, 0x80C0, 0xE0F0, 0xF8F8, 0x88FF, 0xFFFF, 0x7F3F, // stripe 6
};
	
u_int16 screenX, screenY;
#define screenc0  COLOR_BLACK
#define screenc1  __RGB565RGB(0x4f,0xff,0x4f)
//u_int16 screenc0 = __RGB565RGB(0x70,0x70,0x70);
//u_int16 screenc1 = COLOR_BLACK;
u_int16 digits[6];


void ScreenPutData(register u_int16 d) {
	u_int16 buf[16];
	int i;
	u_int16 *p = buf;
	memset(buf,screenc0,sizeof(buf));
	for (i=0; i<8; i++) {
		if (d & (0x0100<<i)) {
			*p = screenc1;
		}
		p++;
		if (d & (0x0001<<i)) {
			*p = screenc1;
		}
		p++;
	}
	LcdFilledRectangle(screenX,screenY,screenX+1,screenY+7,buf,0);
	screenX += 2;
}

void LcdPutLcdNum(u_int16 n) {
	u_int16 x, y;
	u_int16 *p = &lcdNumData[n*6*7];
	for (y=0;y<6;y++) {
		for (x=0; x<3; x++) {
			ScreenPutData(*p++);
		}
		for (x=0; x<3; x++) {
			ScreenPutData(*p);
		}
		p++;
		for (x=0; x<3; x++) {
			ScreenPutData(*p++);
		}
		screenY += 8;
		screenX -= 18;
	}
	screenX += 20;
	screenY -= 48;
}

void PutDigits() {

	u_int16 t = model.decodeTimeSeconds;
	u_int16 sec = t % 60;
	t = t / 60;
	digits[5] = sec % 10;
	digits[4] = sec / 10;
	digits[3] = t % 10;
	t /= 10;
	digits[2] = t % 10;
	
	t = model.currentSongNumber;
	digits[1] = t % 10;
	digits[0] = (t / 10) % 10;


	screenX = PANEL_LEFT + 3;
	screenY = 30;
	LcdPutLcdNum(digits[0]);
	LcdPutLcdNum(digits[1]);
	screenX += 20;
	LcdPutLcdNum(digits[2]);
	LcdPutLcdNum(digits[3]);
	screenX += 7;
	LcdPutLcdNum(digits[4]);
	LcdPutLcdNum(digits[5]);
	//fprintf(stderr,"%d,%d %d,%d\n",screenX, screenY+10, screenX+4, screenY+14, NULL, screenc1);
	//LcdFilledRectangle(screenX, screenY+10, screenX+4, screenY+14, NULL, screenc1);
	//LcdFilledRectangle(screenX, screenY+32, screenX+4, screenY+36, NULL, screenc1);
	LcdFilledRectangle(114, 40, 118, 44, NULL, __RGB565RGB(0x4f,0xff,0x4f));
	LcdFilledRectangle(114, 62, 118, 66, NULL, __RGB565RGB(0x4f,0xff,0x4f));
	//fprintf(stderr,"%d,%d %d,%d\n",screenX, screenY+32, screenX+4, screenY+36, NULL, screenc1);
}



const u_int16 greenText[] = {
	__RGB565RGB(0,0,0),
	__RGB565RGB(0x40/2,0x40,0x40/2),
	__RGB565RGB(0x80/2,0x80,0x80/2),
	__RGB565RGB(0xff/2,0xff,0xff/2),
};
	
const u_int16 greyText[4] = {COLOR_WINDOW,__RGB565RGB(0x60,0x60,0x60),__RGB565RGB(0x50,0x50,0x50),__RGB565RGB(0x40,0x40,0x40)};
const u_int16 blackText[4] = {COLOR_WINDOW,__RGB565RGB(0x50,0x50,0x50),__RGB565RGB(0x30,0x30,0x30),__RGB565RGB(0x00,0x00,0x00)};
//const u_int16 blueOnWhite[4] = {COLOR_WHITE,__RGB565RGB(0xC0,0xC0,0xF0),__RGB565RGB(0x60,0x60,0x90),__RGB565RGB(0x00,0x00,0x50)};
const u_int16 blueOnWhite[4] = {COLOR_WHITE,__RGB565RGB(0xD0,0xD0,0xD0),__RGB565RGB(0x90,0x90,0xA0),__RGB565RGB(0x40,0x40,0x80)};
const u_int16 loweredText[4] = {__RGB565RGB(80,80,80),__RGB565RGB(0x50,0x50,0x50),__RGB565RGB(0x30,0x30,0x30),__RGB565RGB(0x00,0x00,0x00)};

u_int16 raised[3] = {COLOR_WHITE, COLOR_DARK, COLOR_WINDOW};
u_int16 lowered[3] = {COLOR_DARK, COLOR_WHITE, COLOR_WINDOW};
u_int16 lowered_dark[3] = {COLOR_DARK, COLOR_WHITE, __RGB565RGB(0x20,0x20,0x20)};
u_int16 lowered_text[3] = {COLOR_DARK, COLOR_WHITE, COLOR_BLACK};

auto void DrawBevel(u_int16 __a1 x1, u_int16 __a0 y1, u_int16 __b1 x2,u_int16 __b0 y2, u_int16 *bevelColor) {	
	LcdFilledRectangle(x1,y1,x2,y2,0,bevelColor[2]);
	LcdFilledRectangle(x1,y1,x2,y1,0,bevelColor[0]);
	LcdFilledRectangle(x1,y1,x1,y2,0,bevelColor[0]);
	LcdFilledRectangle(x1,y2,x2,y2,0,bevelColor[1]);
	LcdFilledRectangle(x2,y1,x2,y2,0,bevelColor[1]);
}



u_int16 LcdTextOutXY16 (u_int16 x1, u_int16 y1, u_int16 x2, u_int16 *klut, char *s) {
	u_int16 buff[16];
	while (*s) { //Foreach character *s do:
		u_int16 w = font16aptrs[*s];
		u_int32 *p = &font16a[w];
		w = font16aptrs[*s+1] - w;
		while (w--) {
			u_int16 *bp = buff;
			u_int32 k = *p++;
			u_int16 y;
			for (y=0; y<16; y++) {
				*bp = klut[k&3];
				bp++;
				k >>= 2;
			}
			if (x1>x2) return x1;
			LcdFilledRectangle(x1,y1,x1,y1+15,buff,0);
			x1++;
		}
		LcdFilledRectangle(x1,y1,x1,y1+15,0,klut[0]);
		x1++;
		s++;
	}
	return x1;
}


u_int16 TextWidth16 (char *s) {
	u_int16 ww = 0;
	while (*s) { //Foreach character *s do:
		u_int16 w = font16aptrs[*s];
		w = font16aptrs[*s+1] - w;
		w++;
		ww += w;
		s++;
	}
	return ww-3;	
}

