
#include "osmroute.h"
#include "system.h"
#include "memoryleak.h"
#include "utf8.h"

#include <ft2build.h>
#include FT_FREETYPE_H

struct point {
	GLfloat x;
	GLfloat y;
	GLfloat s;
	GLfloat t;
};

int ft_init = 0;
FT_Library ft;


int font_init () {
	/* Initialize the FreeType2 library */
	if (FT_Init_FreeType(&ft)) {
		d_printf ("Could not init freetype library\n");
		return 0;
	}
	d_printf ("font init");
	return 1;
};


struct font* font_load(char *name) {
	int fd;
	struct font *f = NULL;
	char fname[LEN_FILENAME];
	struct stat st_buf;

	sprintf (fname, "%s/%s", cfg.appdatapath, name);
	d_printf ("font load:%s", fname);
    if ((fd = open(fname, O_RDONLY)) == 0) {
        d_printf ("File %s not found.", name);
        return NULL;
    }
	fstat (fd, &st_buf);

	/* load font file into memory */
	f = (struct font *) ml_malloc (sizeof (struct font));
    f->buffersize = st_buf.st_size;
    f->buffer = (unsigned char *) ml_malloc (f->buffersize);
	read(fd, f->buffer, f->buffersize);	
    close(fd);
	
	/* Load a font from memory */
	if (FT_New_Memory_Face(ft, f->buffer, f->buffersize, 0, &f->face)) {
		d_printf("Could not read file from memory.\n");
		exit (1);;
	}

	FT_Set_Pixel_Sizes(f->face, 0, 12);
	d_printf ("font loaded (size:%d).", f->buffersize);

	if (FT_Select_Charmap(f->face, FT_ENCODING_UNICODE))
		d_printf ("FT_Select_Charmap: error");

	return f;
}

/**
 * Render text using the currently loaded font and currently set font size.
 * Rendering starts at coordinates (x, y), z is always 0.
 * The pixel coordinates that the FreeType2 library uses are scaled by (sx, sy).
 */
void font_draw (struct font *f, char *text, float x, float y, float sx, float sy) {
	char *p;
	uint32_t u8chr;
	int i;
	GLfloat vp[8];
	GLfloat vt[8] = {0, 1,
					 1, 1,
					 1, 0,
					 0, 0};
	FT_GlyphSlot g = f->face->glyph;
	
	/* Create a texture that will be used to hold one "glyph" */
	GLuint tex;
	glGenTextures(1, &tex);
	glEnable (GL_TEXTURE_2D);
	glBindTexture(GL_TEXTURE_2D, tex);
	glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
	glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
	glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
	glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

	/* We require 1 byte alignment when uploading texture data */
	glPixelStorei(GL_UNPACK_ALIGNMENT, 1);

	glEnableClientState(GL_VERTEX_ARRAY);
	glEnableClientState(GL_TEXTURE_COORD_ARRAY);

	/* Loop through all characters */
	for (p = text; *p;) {
		u8chr = u8_decode (p, &i);
		if (i == 0) {
			p++;
			continue;
		}
		p = p + i;

		/* Try to load and render the character */
		if ((i = FT_Load_Char(f->face, u8chr, FT_LOAD_RENDER))) {
			d_printf ("error:%d", i);
			continue;
		}

		/* Upload the "bitmap", which contains an 8-bit grayscale image, as an alpha texture */
		glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, g->bitmap.width, g->bitmap.rows, 0, GL_ALPHA, GL_UNSIGNED_BYTE, g->bitmap.buffer);
		/* Calculate the vertex and texture coordinates */
//		d_printf ("char:%c  bitmap.rows:%d     bitmap_top:%d", *p, g->bitmap.rows, g->bitmap_top);

		vp[0] = x;						vp[1] = y + g->bitmap.rows - g->bitmap_top;
		vp[2] = x + g->bitmap.width;	vp[3] = y + g->bitmap.rows - g->bitmap_top;
		vp[4] = x + g->bitmap.width;	vp[5] = y - g->bitmap.rows + g->bitmap.rows - g->bitmap_top;
		vp[6] = x;						vp[7] = y - g->bitmap.rows + g->bitmap.rows - g->bitmap_top;

		glVertexPointer(2, GL_FLOAT, 0, vp);
		glTexCoordPointer(2, GL_FLOAT, 0, vt);
		glDrawArrays(GL_TRIANGLE_FAN,0,4);

//		glEnableClientState(GL_VERTEX_ARRAY);
//		glVertexPointer(2, GL_FLOAT, 0, vp);
//		glDrawArrays(GL_LINES,0,2);
// 		glDisableClientState(GL_VERTEX_ARRAY);
		
		/* Advance the cursor to the start of the next character */
		// x += (g->advance.x >> 6);
		// y -= (g->advance.y >> 6);
		if (g->bitmap.width == 0)	x += 2.0;
		else x += g->bitmap.width + 1;
	}

	glDisableClientState(GL_VERTEX_ARRAY);
	glDisableClientState(GL_TEXTURE_COORD_ARRAY);	

	glBindTexture (GL_TEXTURE_2D, 0);
	glDisable (GL_TEXTURE_2D);
	glDeleteTextures(1, &tex);
};
