#include <stdio.h>
#include <stdlib.h>
#include <gd.h>
#include "gdfonts.h"
#include "gdfontt.h"
#include "gdfontl.h"
#include "gdfontl.h"
#include "gdfontmb.h"
#include <math.h>
#include <stdint.h>
#include <string.h>

int main(int argc, char **argv){
	gdImagePtr im;
	FILE *in;
	FILE *out;
	int width = 800;
	int height = 600;
	int box_h = 10;
	int box_w = 10;
	int x1, y1, x2, y2;
	int num1 = 1;
	int num2 = 0;
	int num3 = 0;
	int size_max = 64;
	int size_step = 1;
	int cycle_max = 500;
	int cycle_step = 25;
	int stagger = 0;
	int readprev = 0;
	int readcur = 0;
	int step_h = 0;
	int step_v = 0;
	uint32_t read_buffer_size = 64;
	char *read_buffer = (char *)malloc(read_buffer_size + 1);
	(void)memset( (void *)read_buffer, '\0', read_buffer_size + 1);
	im = gdImageCreate(width, height);

	//byte_loop loop unrolled_loop rep_byte rep_4byte rep_8byte vector_loop libcall
	//int colors[8];
	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 green = gdImageColorAllocate(im, 0, 255, 0);
        int yellow = gdImageColorAllocate(im, 255, 255, 0);
        int orange = gdImageColorAllocate(im, 255, 128, 0);
        int purple = gdImageColorAllocate(im, 255, 0, 255);
        int brown = gdImageColorAllocate(im, 128, 64, 0);
        int grey = gdImageColorAllocate(im, 128, 128, 128);

	int colors[8] = {red, blue, green, yellow, orange, purple, brown, grey};

        int styleDashed[8];
        styleDashed[0] = gdTransparent;
        styleDashed[1] = black;
        styleDashed[2] = gdTransparent;
        styleDashed[3] = black;
        styleDashed[4] = gdTransparent;
        styleDashed[5] = black;
        styleDashed[6] = gdTransparent;
        styleDashed[7] = black;

        gdImageSetStyle(im, styleDashed, 8);

        char *token;
        char *line;
        char *search = " ";
	char labelstr[32];

        gdImageLine(im, 100, 10, 100, height-100, black);
        gdImageLine(im, 100, height-100, width-100, height-100, black);
        gdImageString(im, gdFontMediumBold, 5, 5, (unsigned char *)"cycles", black);
	gdImageString(im, gdFontMediumBold, width/2, height-25, (unsigned char *)"size", black);
        //gdImageString(im, gdFontMediumBold,   1530   ,  100        , "Swap Usage" , black);
        //gdImageString(im, gdFontMediumBold,   50   ,   140    , "Hours" , black);


//	x1 = width-200;
//	y1 = box_h*2;
//	x2 = width-100;
//	y2 = box_h*2+box_h;
	gdImageString(im, gdFontMediumBold, width-80, box_h, (unsigned char *)"byte_loop", black);
	gdImageFilledRectangle(im, width-100, box_h, width-90, box_h*2, red);
	gdImageString(im, gdFontMediumBold, width-80, box_h*3, (unsigned char *)"loop", black);
	gdImageFilledRectangle(im, width-100, box_h*3, width-90, box_h*4, blue);
	gdImageString(im, gdFontSmall, width-80, box_h*5, (unsigned char *)"unrolled_loop", black);
	gdImageFilledRectangle(im, width-100, box_h*5, width-90, box_h*6, green);
	gdImageString(im, gdFontMediumBold, width-80, box_h*7, (unsigned char *)"rep_byte", black);
	gdImageFilledRectangle(im, width-100, box_h*7, width-90, box_h*8, yellow);
	gdImageString(im, gdFontMediumBold, width-80, box_h*9, (unsigned char *)"rep_4byte", black);
	gdImageFilledRectangle(im, width-100, box_h*9, width-90, box_h*10, orange);
	gdImageString(im, gdFontMediumBold, width-80, box_h*11, (unsigned char *)"rep_8byte", black);
	gdImageFilledRectangle(im, width-100, box_h*11, width-90, box_h*12, purple);
	gdImageString(im, gdFontMediumBold, width-80, box_h*13, (unsigned char *)"vector_loop", black);
	gdImageFilledRectangle(im, width-100, box_h*13, width-90, box_h*14, brown);
	gdImageString(im, gdFontMediumBold, width-80, box_h*15, (unsigned char *)"libcall", black);
	gdImageFilledRectangle(im, width-100, box_h*15, width-90, box_h*16, grey);

	num2 = (width-200)/size_max/size_step;
	
	for(num1=0; num1<size_max; num1+=size_step){

		(void)sprintf(labelstr, "%d", num1+1);
		gdImageString(im, gdFontSmall, num2*(num1+1)+100, height-75+stagger, (unsigned char *)labelstr, black);
		gdImageLine(im, num2*(num1+1)+100, height-75+stagger, num2*(num1+1)+100, height-100, black);
		gdImageLine(im, num2*(num1+1)+100, height-100, num2*(num1+1)+100, 10, gdStyled);
		if(stagger == 25)
			stagger = 0;
		else
			stagger = 25;

		//stagger ^= 1;
	}
	//gdImageLine(im, 0, 0, width, 0, black);
	//num2 = (height-120)/cycle_max/cycle_step;
	num2 = 0;

	for(num1=0; num1<cycle_max; num1+=cycle_step){
		(void)sprintf(labelstr, "%d", num1);
		gdImageString(im, gdFontSmall, 50, height-100-25*num2, (unsigned char *)labelstr, black);
		gdImageLine(im, 50, height-100-25*num2, 100, height-100-25*num2, black);
		gdImageLine(im, 100, height-100-25*num2, width-100, height-100-25*num2, gdStyled);
		num2++;
	}

	step_h = (width-200)/size_max/size_step;
	step_v = 25;
	for(num1=1; num1<9; num1++){
		(void)sprintf(labelstr, "results/r%d.txt", num1);
		in = fopen(labelstr, "r");
		num2 = 0;
		readprev = 0;
		(void)memset( (void *)read_buffer, '\0', read_buffer_size + 1);
		while( fgets(read_buffer, read_buffer_size, in) != NULL){
			//printf("line %d\n", num2);
			if(num2 == 64)
				break;
			readcur = atoi(read_buffer);
			if(readcur > 475)
				readcur = 475;

			gdImageLine(im, num2*step_h+100, height-100-readprev, (num2+1)*step_h+100, height-100-readcur, colors[num1-1]);

			num2++;
			readprev = readcur;
		}
		
		fclose(in);
	}

	out = fopen("graph.png", "w");
	gdImageInterlace(im, 1);
	gdImagePng(im, out);
	fclose(out);
	//fclose(in);
	free(read_buffer);
	gdImageDestroy(im);



	return 0;
}
