#include <stdlib.h>
#include <stdio.h>
#include <gd.h>
#include <string.h>
#include <stdint.h>
#include <wchar.h>
#include <unistd.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>



int main(int argc, char **argv){
	FILE *image_out;
	gdImagePtr im;
	int black;
	int white;
	int brect[8];
	int x, y;
	char *err;
	int no_fontconfig;
	int row_spacing_pixels = 20;
	int col_spacing_pixels = 20;
	wchar_t space = ' ';
	wchar_t tab = '\t';
	wchar_t newline = '\n';
	wchar_t null = '\0';
	int image_width;
	int image_height;
//	char *s = "0123 Hello.\n4567 World."; /* String to draw. */
//	char *locale = setlocale(LC_ALL, "en_US.utf8");
	wint_t c;
	uint64_t total_chars_to_print = 0;
	uint32_t total_rows = 0;
	uint32_t total_cols = 0;

//    while ((c = fgetwc(in)) != WEOF)
//        putwchar(c);
//    fclose(in);

//char *s = "Y";

char *s;
wchar_t test[2];


wchar_t *sa = "             !       \"       #       $       %       &       '       (       )       *       +       ,       -       .       /  \n\
     0       1       2       3       4       5       6       7       8       9       :       ;       <       =       >       ?  \n\
     @       A       B       C       D       E       F       G       H       I       J       K       L       M       N       O  \n\
     P       Q       R       S       T       U       V       W       X       Y       Z       [       \\       ]       ^       _  \n\
     `       a       b       c       d       e       f       g       h       i       j       k       l       m       n       o  \n\
     p       q       r       s       t       u       v       w       x       y       z       {       |       }       ~  \n";


char *sd = "      ̀        ́        ̂        ̃        ̄        ̅        ̆        ̇        ̈        ̉        ̊        ̋        ̌        ̍        ̎   \n\
     ̏        ̐        ̑        ̒        ̓        ̔        ̕        ̖        ̗        ̘        ̙        ̚        ̛        ̜        ̝        ̞   \n\
     ̟        ̠        ̡        ̢        ̣        ̤        ̥        ̦        ̧        ̨        ̩        ̪        ̫        ̬        ̭        ̮   \n\
     ̯        ̰        ̱        ̲        ̳        ̴        ̵        ̶        ̷        ̸        ̹        ̺        ̻        ̼        ̽        ̾   \n\
     ̿        ̀        ́        ͂        ̓        ̈́        ͅ        ͆        ͇        ͈        ͉        ͊        ͋        ͌        ͍        ͎   \n\
     ͏        ͐        ͑        ͒        ͓        ͔        ͕        ͖        ͗        ͘        ͙        ͚        ͜        ͝        ͞        ͟   \n\
     ͠        ͡        ͢        ͣ        ͤ        ͥ        ͦ        ͧ        ͨ        ͩ        ͪ        ͫ        ͬ        ͭ        ͮ        ͯ   \n\
                                        \n";

//strtoul("FA", NULL, 16);

//	double sz = 12*96/187;
	double pixel_pt_size = 1.0;
	//char *f = "/usr/share/fonts/TTF/iosevka-slab.ttc";  /* User supplied font */
	char *input_ttf = "/mnt/sdb1/pub/test/gdfont/iosevka-fixed-slab-extended.ttf";
	//char *f = "Iosevka Fixed Slab Extended";

//        int white = gdImageColorAllocate(im, 255, 255, 255);
//        int black = gdImageColorAllocate(im, 0, 0, 0);
//        int red = gdImageColorAllocate(im, 255, 0, 0);
//        int blue = gdImageColorAllocate(im, 0, 0, 255);
	int aa_disable; //= gdImageColorAllocate(im, -1, -1, -1);

/* Signal that all freetype font calls in this program will receive
  fontconfig patterns rather than filenames of font files */

/*
no_fontconfig = gdFTUseFontConfig(1);

if(!no_fontconfig){ //{fprintf(stderr,no_fontconfig); return 1;}
	printf("no fontconfig: %d!\n", no_fontconfig);
	exit(1);
}
*/


/*
typedef struct {
       //logical OR of gdFTEX_ values
       int flags;
       //fine tune line spacing for '\n'
       double linespacing;
       //Preferred character mapping
       int charmap;
       //Rendering resolution
       int hdpi;
       int vdpi;
       char *xshow;
       char *fontpath;
} gdFTStringExtra, *gdFTStringExtraPtr;
*/

        int input_hex;
        struct stat buffer;
        int status;
uint32_t file_bytes;
wchar_t *mem_file;



input_hex = open("input.txt", O_RDONLY);
        if(input_hex == -1){
                fprintf( stderr, "Error opening input.txt\n");
                exit( 1 );
        }
	status = fstat(input_hex, &buffer);
        file_bytes=buffer.st_size;
        if(file_bytes < 1){
                printf("Error: file is too small!\n");
                exit(1);
        }
//      	mem_file=(wchar_t *)mmap(NULL, file_bytes, PROT_READ, MAP_SHARED, input, 0);
//        if (mem_file == MAP_FAILED) {
//                close(input);
//                perror("Error mmapping the file");
//                exit(EXIT_FAILURE);
//        }
printf("input: input.txt\n");

/*
	//determine colum/row counts for image sizing
    while ((c = fgetwc(input)) != WEOF){
		
total_chars_to_print
total_rows
total_cols
	}
        //putwchar(c);
    //fclose(in);
	if(fseek(input, 0, SEEK_SET) != 0){
		printf("fseek Error\n");
		exit(EXIT_FAILURE);
	}

*/
	
	gdFTStringExtra Strex = {0,0,0,0,0,NULL,NULL};
	gdFTStringExtraPtr strex = &Strex;

	//strex->flags = 0;

strex->flags |= gdFTEX_LINESPACE;
//strex->flags |= gdFTEX_CHARMAP;
strex->flags |= gdFTEX_RESOLUTION;
strex->flags |= gdFTEX_DISABLE_KERNING;
strex->flags |= gdFTEX_XSHOW;
strex->flags |= gdFTEX_RETURNFONTPATHNAME;
//strex->flags |= gdFTEX_FONTPATHNAME;
//strex->flags |= gdFTEX_FONTCONFIG;
//strex->flags |= gdFTEX_FONTPATHNAME;


strex->linespacing = 2.00;
strex->charmap = gdFTEX_Unicode;
strex->hdpi=1350;
strex->vdpi=1950;
//strex.xshow
//strex.fontpath


//0 to 10FFFF
//Determine size of single character string box


	/* obtain brect so that we can size the image */
//	err = gdImageStringFT(NULL,&brect[0],0,f,sz,0.,0,0,s);
//	err = gdImageStringFTEx(NULL,&brect[0],0,f,sz,0.,0,0,s,strex);
//char *gdImageStringFT(gdImagePtr im, int *brect, int fg, char *fontname, double ptsize, double angle, int x, int y, char *string)
//char *gdImageStringFTEx(gdImagePtr im, int *brect, int fg, char *fontname, double ptsize, double angle, int x, int y, char *string, gdFTStringExtraPtr strex)
//	if (err) {fprintf(stderr,err); return 1;}

printf("here 1\n");
//printf("%s\n", strex.fontpath);
//gdFree((void *)strex->xshow);
//gdFree((void *)strex->fontpath);
	/* create an image big enough for the string plus a little whitespace */
//	x = brect[2]-brect[6] + 9;
//	y = brect[3]-brect[7] + 19;

//printf("character width: %d height: %d\n", brect[2]-brect[6], brect[3]-brect[7]);

x = 4000;
y = 4000;

//



printf("here 2\n");





//create image
	im = gdImageCreate(x,y);
//aa_disable = gdImageColorAllocate(im, -1, -1, -1);
	/* Background color (first allocated) */
	white = gdImageColorResolve(im, 0, 0, 0);
	black = gdImageColorResolve(im, 0, 255, 0);

	/* render the string, offset origin to center string*/
	/* note that we use top-left coordinate for adjustment
	 * since gd origin is in top-left with y increasing downwards. */
	//x = 0;
	//y = 0;

x=20;
y=20;

test[1] = '\0';
for(test[0]=0; test[0]<16000; test[0]++){

//if(test[0] == tab || test[0] == newline)
//	continue;



s = test;
//	x = 0 - brect[6];
//	y = 0 - brect[7];


//	err = gdImageStringFT(im,&brect[0],black,f,sz,0.0,x,y,s);
	err = gdImageStringFTEx(im,&brect[0],black,input_ttf,pixel_pt_size,0.0,x,y,s,strex);
//char *gdImageStringFTEx(gdImagePtr im, int *brect, int fg, char *fontname, double ptsize, double angle, int x, int y, char *string, gdFTStringExtraPtr strex)
	if (err) {fprintf(stderr,err); return 1;}
//printf("%s\n", (const char *)strex->xshow);
//printf("%s\n", (const char *)strex->fontpath);
gdFree((void *)strex->xshow);
gdFree((void *)strex->fontpath);
x+=20;
if(test[0] % 164 == 0){
	y+=40;
	x=20;
}

}

printf("here 3\n");

	/* Write img to stdout */
	//gdImagePng(im, stdout);


        image_out = fopen("test01.png", "w");

        gdImageInterlace(im, 1);
        gdImagePng(im, image_out);
        fclose(image_out);
        gdImageDestroy(im);

 //      if(munmap(mem_file, file_bytes) == -1) {
 //               perror("Error un-mmapping the file");
 //       }

close(input_hex);

	/* Destroy it */
	//gdImageDestroy(im);

	return 0;
}
