// BlinkenSisters - Hunt for the Lost Pixels
//     Bringing back the fun of the 80s
//
// (C) 2005-07 Rene Schickbauer, Wolfgang Dautermann
//
// See License.txt for licensing information
//


#include "globals.h"
#include "showtext.h"
#include "blending.h"
#include "errorhandler.h"
#include "drawprimitives.h"

// Surface that contains the font
SDL_Surface *gFont;

// Offset of character data per character
Uint32 gFontOfs[256];
// Width of character data per character
Uint32 gFontWidth[256];

void initShowText()
{
	// Load the font surface
	gFont = BS_IMG_Load_DisplayFormat(configGetPath("font.bmp"),DIE_ON_FILE_ERROR);
	
	// -- Calculate Font width
	if (SDL_MUSTLOCK(gFont))
		if (SDL_LockSurface(gFont) < 0)
			return;
	
	Sint32 i, j, k;
	for (k = 0; k < gFont->h / gFont->w; k++)
	{
		gFontOfs[k] = gFont->w;
		gFontWidth[k] = 0;
		for (i = 0; i < gFont->w; i++)
		{
			for (j = 0; j < gFont->w; j++)
			{
				if (((Uint32*)gFont->pixels)[(i + k * gFont->w) *
					(gFont->pitch / 4) + j] != 0)
				{
					if (j < (Sint32)gFontOfs[k])
						gFontOfs[k] = j;
					
					if (j > (Sint32)gFontWidth[k])
						gFontWidth[k] = j;
				}
			}
		}
		gFontWidth[k] -= gFontOfs[k];
	}
	
	// Unlock if needed
	if (SDL_MUSTLOCK(gFont))
		SDL_UnlockSurface(gFont);
	
	
	
}

void drawcharacter(const Sint32 x, const Sint32 y, Uint32 character, const Sint32 blend, const SDL_Surface* dest)
{
	if (character == 32)
		return;
	
	Uint32 pitch = dest->pitch / 4;
	
	character -= 33; // our font does not have the first 33 characters.

	// -- Calculate Font width
	if (SDL_MUSTLOCK(gFont))
		if (SDL_LockSurface(gFont) < 0)
			return;
		
	Sint32 i, j;
	for (i = 0; i < gFont->w; i++) {
		Uint32 screenofs = x + (y + i) * pitch;
		Uint32 charofs = (i + character * gFont->w) *
			(gFont->pitch / 4) + gFontOfs[character];
		for (j = 0; j < (Sint32)gFontWidth[character]; j++) {
			// Validity check for position
			if((x + j) >= SCR_WIDTH || (y + i) >= SCR_HEIGHT || (x + j) < 0 || (y + i) < 0) {
				// Do Nothing
			} else {
				Uint32 pixel = ((Uint32*)gFont->pixels)[charofs];
				if (pixel != 0) {
					Uint32 oldpixel = ((Uint32*)dest->pixels)[screenofs];
					switch (blend) {
						case -1:
							pixel = blend_mul(pixel ^ 0xffffff, oldpixel);
							break;
						case 0:
							pixel = blend_avg(pixel, oldpixel);
							break;
						case 1:
							pixel = blend_add(pixel, oldpixel);
							break;
					}
					((Uint32*)dest->pixels)[screenofs] = pixel;
				}
			}
			screenofs++;
			charofs++;
		}
	}
	
	// Unlock if needed
	if (SDL_MUSTLOCK(gFont))
		SDL_UnlockSurface(gFont);
	
}

void drawstring(Sint32 x, Sint32 y, const char *s, const SDL_Surface* dest, const bool bright)
{
	if(!dest) {
		dest = gScreen;
	}
	
	while (*s != 0) {
		drawcharacter(x + 1, y + 1, *s, -1, dest);
		drawcharacter(x, y, *s, 0, dest);
		if(bright) {
    		drawcharacter(x, y, *s, 1, dest);
        }
		if (*s == 32)
			x += gFont->w / 3;
		else
			x += gFontWidth[*s - 33];
		
		// Add a little space between characters
		x += 3;
		
		s++;
	}
}

Uint32 getstringwidth(const char *s) {
    Uint32 width = 0;
	while (*s != 0) {
		if (*s == 32)
			width += gFont->w / 3;
		else
			width += gFontWidth[*s - 33];
		
		width += 3;
		
		s++;
	}
	
	return width;
}
