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

#define TESTED 12
#define TESTED_B 14
#define MAX_VOLT 2000
#define MAX_CLOCK 2000
#define LINE_GRANULARITY 25

struct pairs{
	int voltage;
	int clock;
};

//const struct pairs Pairs[TESTED] = {{800, 852}, {865, 1000}, {875, 1200}, {875, 1300}, {885, 1325}, {885, 1350}, {895, 1375}, {920, 1400}, {945, 1425}, {965, 1450}, {965, 1455}, {990, 1475}, {1010, 1500}, {1030, 1525}, {1060, 1550}, {1090, 1575}, {1115, 1600}};

const struct pairs Pairs[TESTED] = {{80000, 2675}, {91250, 3000}, {100625, 3400}, {115625, 3600}, {121250, 3800}, {125000, 3900}, {130000, 4000}, {134375, 4025}, {140625, 4050}, {140625, 4075}, {141875, 4100}, {146250, 4125}};
const struct pairs Pairs_B[TESTED_B] = {{80000, 3075}, {89375, 3400}, {97500, 3600}, {105000, 3800}, {111250, 3900}, {118750, 4000}, {120000, 4025}, {122500, 4050}, {123750, 4075}, {125000, 4100}, {127500, 4125}, {131250, 4150}, {132500, 4175}, {136250, 4200}};

int main(int argc, char **argv){
	gdImagePtr im;// = NULL;
	FILE *out;
	//int width               = 1650;
	int width               = 3400;
	int height              = 2850;
	int line_num;
	int x1, y1, x2, y2;
	//int pixels_per_day      = 1;
	//int pixels_whitespace   = 1;
	//double starting_balance = 0;
	char buf[32];
	const char *output_file = "1800x-scaling.png";
	im = gdImageCreate(width, height);
	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 orange = gdImageColorAllocate(im, 255, 128, 0);
	int styleDashed[9] = {blue, blue, blue, green, green, green, red, red, red};
/*	styleDashed[0] = blue;
	styleDashed[1] = blue;
	styleDashed[2] = blue;
	styleDashed[3] = green;
	styleDashed[4] = green;
	styleDashed[5] = green;
	styleDashed[6] = red;
	styleDashed[7] = red;
	styleDashed[8] = red;*/
	gdImageSetStyle(im, styleDashed, 9);

	//char chart_label_a[32];

	//double balance_tenth = ceil(max_balance) / 10;
	//double height_tenth = (height-200)/10;

	//int emptyvarstr;
	//int downnum = height-100;
	//int overnum = 0;
	int stagger = 25;
	double tmp1;

double sz = 20.0;
char *f = "/usr/share/fonts/TTF/LiberationSans-Regular.ttf";  /* User supplied font */
int brect[8];
char *err;
	printf("output_file: %s\n", output_file);

	//draw chart boundaries/labels on image
	gdImageLine(im, 100, 100, 100, height-100, black);
	gdImageLine(im, 100, height-100, width-100, height-100, black);

//	gdImageString(im, gdFontMediumBold,   width-85   ,   height-85        , (unsigned char *)"Clock" , black);
//	gdImageString(im, gdFontMediumBold,   0   ,   10        , (unsigned char *)"Voltage" , black);


err = gdImageStringFT(im,&brect[0],black,f,sz,0.0,width-200,height-30,(char *)"Clock");
err = gdImageStringFT(im,&brect[0],black,f,sz,0.0,10,30,(char *)"Voltage");

err = gdImageStringFT(im,&brect[0],blue,f,sz,0.0,1400,30,(char *)"1800x");
err = gdImageStringFT(im,&brect[0],black,f,sz,0.0,1550,30,(char *)"vs");
err = gdImageStringFT(im,&brect[0],green,f,sz,0.0,1670,30,(char *)"2700x");
err = gdImageStringFT(im,&brect[0],black,f,sz,0.0,1820,30,(char *)"standard llc, bios set voltages, Noctua NH-D15, Conductonaut");

	tmp1 = Pairs[0].voltage;
	for(line_num=0; line_num<height-175; line_num+=25){
		if(line_num%100 == 0){
			//tmp1 = Pairs[0].voltage;// + line_num;
			//tmp1 = (double)Pairs[0].voltage/100000;
			//tmp1 /= 25;
			//tmp1 /= 100000;
			//tmp1 += line_num/1000;
			(void)memset(buf, '\0', sizeof(char)*32);
			(void)sprintf(buf, "%.03lf", tmp1/100000);
//			gdImageString(im, gdFontGiant,   10,   height-100-line_num, (unsigned char *)buf, black);
err = gdImageStringFT(im,&brect[0],black,f,sz,0.0,10,height-100-line_num,(char *)buf);
			gdImageLine(im, 75, height-100-line_num, width-50, height-100-line_num, black);
		}else{
			gdImageLine(im, 100, height-100-line_num, width-50, height-100-line_num, gdStyled);
		}
		tmp1+=625;
	}


	for(line_num=100; line_num<width; line_num+=125){
		(void)memset(buf, '\0', sizeof(char)*32);
		tmp1 = 2575+line_num;
		tmp1 /= 1000;
		(void)sprintf(buf, "%.03lf", tmp1);
//		gdImageString(im, gdFontGiant,  line_num+line_num-100, height-stagger, (unsigned char *)buf, black);
err = gdImageStringFT(im,&brect[0],black,f,sz,0.0,line_num+line_num-100,height-stagger,(char *)buf);
		gdImageLine(im, line_num+line_num-100, height-stagger, line_num+line_num-100, 100, black);
		if(stagger == 50)
			stagger = 25;
		else
			stagger = 50;
	}
	//x1 = 100;
	//y1 = height-100;
	line_num = 0;
	x1 = 100+Pairs[line_num].clock-2675;
	x1 += x1-100;
	y1 = height-100;
	y1 -= Pairs[line_num].voltage/25-80000/25;
	gdImageLine(im, 100, height-100, x1, y1, red);
	stagger = 0;
	for(line_num=1; line_num<TESTED; line_num++){
		x2 = 100+Pairs[line_num].clock-2675;
		x2 += x2-100;
		y2 = height-100;
		y2 -= Pairs[line_num].voltage/25-80000/25;
		if(stagger == 0){
			gdImageLine(im, x1, y1, x2, y2, blue);
			stagger = 1;
		}else{
			gdImageLine(im, x1, y1, x2, y2, blue);
			stagger = 0;
		}
		gdImageFilledRectangle(im, x1-5, y1-5, x1+5, y1+5, red);

		x1 = x2;
		y1 = y2;
	}
	gdImageFilledRectangle(im, x1-5, y1-5, x1+5, y1+5, red);


        line_num = 0;
        x1 = 100+Pairs_B[line_num].clock-2675;
        x1 += x1-100;
        y1 = height-100;
        y1 -= Pairs_B[line_num].voltage/25-80000/25;
//        gdImageLine(im, 100, height-100, x1, y1, orange);

        stagger = 0;
        for(line_num=1; line_num<TESTED_B; line_num++){
                x2 = 100+Pairs_B[line_num].clock-2675;
                x2 += x2-100;
                y2 = height-100;
                y2 -= Pairs_B[line_num].voltage/25-80000/25;
                if(stagger == 0){
                        gdImageLine(im, x1, y1, x2, y2, green);
                        stagger = 1;
                }else{
                      	gdImageLine(im, x1, y1, x2, y2, green);
                        stagger = 0;
                }
                gdImageFilledRectangle(im, x1-5, y1-5, x1+5, y1+5, orange);

                x1 = x2;
                y1 = y2;
        }
	gdImageFilledRectangle(im, x1-5, y1-5, x1+5, y1+5, orange);




/*
	for(line_num=0; line_num<11; line_num++){
		gdImageLine(im, 50, downnum, width-85, downnum, gdStyled);
		emptyvarstr = sprintf(chart_label_a, "$%.02lf", current_balance);
		gdImageString(im, gdFontMediumBold, 5, downnum, chart_label_a , black);
		downnum -= LINE_GRANULARITY;
		overnum += LINE_GRANULARITY;
	}


	//plot data from transactions/days on image
	unsigned int day_count;
	unsigned int days_cur_month;
	unsigned int start_pixel_month;
	unsigned int end_pixel_month;
	unsigned int start_pixel_year;
	unsigned int end_pixel_year;
	int x1, y1, x2, y2;
	unsigned int days_from_start;
	//date_start
	char months[] = "JFMAMJJASOND";
	char tmp_char[2];
	//char *months[]={"J", "F", "M", "A", "M", "J", "J", "A", "S", "O", "N", "D"};
	unsigned int last_year = 0;
	unsigned int last_month = 0;
	unsigned int last_m_X = 100;

	y1 = height - 100;
	for(day_count=0; day_count<total_days; day_count++){
		date_tmp.day    = transactions[day_count].date.day;

		date_tmp.month  = transactions[day_count].date.month;

		date_tmp.year   = transactions[day_count].date.year;
		days_from_start = Total_Days(&date_start, &date_tmp);
		x1 = 100 + days_from_start * (pixels_per_day+pixels_whitespace);
		x2 = x1 - pixels_per_day;
		y2 = y1 - (height-200)*transactions[day_count].balance/max_balance;

		gdImageFilledRectangle(im, x1, y1, x2, y2, green);
		if(last_month != date_tmp.month){
			gdImageLine(im, x1, y1, x1, height-75, red);
			last_month = date_tmp.month;
			tmp_char[0] = months[last_month-1];
			tmp_char[1] = '\0';
			gdImageString(im, gdFontMediumBold,   x1,   height-75, tmp_char, red);
		}
		if(last_year != date_tmp.year){
			gdImageLine(im, x1, height-75, x1, height-50, blue);
			last_year = date_tmp.year;
			emptyvarstr = sprintf(chart_label_a, "%d", last_year);
			gdImageString(im, gdFontMediumBold,   x1,   height-50, chart_label_a, blue);
		}
	}



	days_cur_month = Days_In_Month(&date_start) - date_start.date.day;
	for(day_count=0; day_count<days_cur_month; day_count++){

		//allocate labels on chart for each month/year

		//plot each day on chart


	for(day_count=0; day_count<total_days; day_count++){
		days

	}

*/
	//write out image
	out = fopen(output_file, "w");
	gdImageInterlace(im, 1);
	gdImagePng(im, out);
	fclose(out); 
	gdImageDestroy(im);
	//free(input_file);
	//free(output_file);
	//free(transactions);

	return 0;
}
