#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <complex.h>
#include <string.h>
#include <math.h>
#include <time.h>
#include <gd.h>
#include "gdfonts.h"
#include "gdfontmb.h"
#include "dates.h"

void Usage(void){
	printf("Usage: ./apy <start principal> <apy> <months> <monthly contribution>\n");
	printf("\n");
}

int main(int argc, char **argv){
	double interest = 0; //"Interest" is the total dollar amount of interest earned on the Principal for the term of the account.
	double principal = 1000;
	double apy = .05;
	double Total_Interest_Payed = 0;
	//double rate = 1.35;
	double days_in_term = 365/4;  //compounded quarterly
	int i;
	int pixel_space = 5;
printf("%d\n", argc);
	if(argc != 5){
		Usage();
		return 0;
	}
	FILE *out;
	int width = 2000;
	int height = 600;
	gdImagePtr im = gdImageCreate(width,height);
	int white = gdImageColorAllocate(im, 255, 255, 255);
	int black = gdImageColorAllocate(im, 0,   0,   0);
	int red   = gdImageColorAllocate(im, 200, 0,   0);
	int blue  = gdImageColorAllocate(im, 0,   0,   220);
	int green = gdImageColorAllocate(im, 0,   220, 0);
	
printf("here a\n");
	struct Date Cur_Date;
	//set Cur_Date to today
	struct tm *my_date;
    time_t t;
	t = time(NULL); //asctime(local)
    my_date = localtime(&t);

	Cur_Date.day   = my_date->tm_mday;
	Cur_Date.month = my_date->tm_mon + 1;
	Cur_Date.year  = my_date->tm_year + 1900;

	principal               = atof( argv[1] );
	apy                     = atof( argv[2] );
	unsigned int total_months        = atof( argv[3] );
	double monthly_contrib           = atof( argv[4] );
	double Initial_Deposit = principal;
printf("start: %lf apy: %lf monthly: %lf total_months: %u\n", principal, apy, monthly_contrib, total_months);
	char labels_a[100];
	char labels_b[5];
	char months[] = "JFMAMJJASOND";
	double dollar_highest;
	double dollar_tenth;
	unsigned int pix_per_month;
	//setup chart bounds/labels
	gdImageLine(im, 60, 10, 60 , height-60, black);
	gdImageLine(im, 60, height-60, width-60 , height-60, black);

	pix_per_month = (width - 130) / (total_months + 1);
	//determin highest dollar amount
	double tmp_p = principal;
	double tmp_i = interest; //0
	unsigned int month_count = Cur_Date.month - 1;
	for(i=0; i<total_months+1; i++){
		if(i != 0){
			tmp_p += monthly_contrib;
			if(i % 3 == 0){
				// roughly accurate for 1 quarter
				tmp_i = tmp_p * ( cpow(  ( apy / 100 ) + 1, days_in_term / 365)  - 1 );
				tmp_p += tmp_i;
			}
		}
		
		
	}

	dollar_highest = ceil(tmp_p);
	dollar_tenth   = tmp_p / 10;
	double Total_Contrib = 0;
	double dollar_pix_tenth = (height-70)/10; 
printf("here 2\n");
	//draw dollar labels
	for(tmp_p = 0; tmp_p < 11; tmp_p++){
		(void)sprintf(labels_a, "$%.02lf", tmp_p*dollar_tenth);
		gdImageString(im, gdFontMediumBold,   10,   height-60-(tmp_p*dollar_pix_tenth), (unsigned char *)labels_a, red);
	}
printf("here 3\n");
	double top_p, top_c, top_i;
	//double 
	for(i=0; i<total_months; i++){
		if(i != 0){
			//principal += monthly_contrib;
			//Total_Contrib += monthly_contrib;
			if(i % 3 == 0){
				interest = principal * ( cpow(  ( apy / 100 ) + 1, days_in_term / 365)  - 1 );
				//principal += interest;
			}
		}
		//principal
		top_p = (principal/dollar_highest)*(height-70);
		top_p = (height-60) - top_p;
		gdImageFilledRectangle(im, 70+i*pix_per_month, height-60, 70+pix_per_month+(i*pix_per_month)-pixel_space, top_p, black);

		if(i != 0){
			//contributions
			top_c = ((principal+monthly_contrib)/dollar_highest)*(height-70);
			top_c = (height-60) - top_c;
			gdImageFilledRectangle(im, 70+i*pix_per_month, top_p, 70+pix_per_month+(i*pix_per_month)-pixel_space, top_c, blue);

			if(i % 3 == 0){
				//interest
				top_i = ((principal+monthly_contrib+interest)/dollar_highest)*(height-70);
				top_i = (height-60) - top_i;
				gdImageFilledRectangle(im, 70+i*pix_per_month, top_c, 70+pix_per_month+(i*pix_per_month)-pixel_space, top_i, green);
				printf("%lf\n", interest);
				Total_Interest_Payed += interest;
			}
		}
		//draw month label
		memset(labels_b, '\0', 5);
		labels_b[0] = months[month_count];
		gdImageString(im, gdFontMediumBold,   70+i*pix_per_month,   height-50, (unsigned char *)labels_b, red);
		if(month_count != 11){
			month_count++;
		}else{
			month_count = 0;
		}
		if(i % 3 == 0){
			if(i != 0)
				principal += interest;
		}
		if(i != (total_months-1) && i != 0){
			principal += monthly_contrib;
			Total_Contrib += monthly_contrib;
		}
	}
printf("here 4\n");

            top_i = ((principal+monthly_contrib+interest)/dollar_highest)*(height-70);
            top_i = (height-60) - top_i;

	memset(labels_a, '\0', 100);
	(void)sprintf(labels_a, "Total:");
	gdImageString(im, gdFontMediumBold,   70+i*pix_per_month+5,   top_i, (unsigned char *)labels_a, red);
	memset(labels_a, '\0', 100);
	(void)sprintf(labels_a, "$%.02lf", principal);
	gdImageString(im, gdFontMediumBold,   70+i*pix_per_month+5,   top_i+20, (unsigned char *)labels_a, red);

	memset(labels_a, '\0', 100);
	(void)sprintf(labels_a, "Total Contributions:");
	gdImageString(im, gdFontMediumBold,   70+i*pix_per_month+5,   top_i+40, (unsigned char *)labels_a, blue);
	memset(labels_a, '\0', 100);
	(void)sprintf(labels_a, "$%.02lf", Total_Contrib);
	gdImageString(im, gdFontMediumBold,   70+i*pix_per_month+5,   top_i+60, (unsigned char *)labels_a, blue);

	memset(labels_a, '\0', 100);
	(void)sprintf(labels_a, "Total Interest:");
	gdImageString(im, gdFontMediumBold,   70+i*pix_per_month+5,   top_i+80, (unsigned char *)labels_a, green);
	memset(labels_a, '\0', 100);
	(void)sprintf(labels_a, "$%.02lf", Total_Interest_Payed);
	gdImageString(im, gdFontMediumBold,   70+i*pix_per_month+5,   top_i+100, (unsigned char *)labels_a, green);

	memset(labels_a, '\0', 100);
	(void)sprintf(labels_a, "Initial Deposit:");
	gdImageString(im, gdFontMediumBold,   70+i*pix_per_month+5,   top_i+120, (unsigned char *)labels_a, black);
	memset(labels_a, '\0', 100);
	(void)sprintf(labels_a, "$%.02lf", Initial_Deposit);
	gdImageString(im, gdFontMediumBold,   70+i*pix_per_month+5,   top_i+140, (unsigned char *)labels_a, black);

	memset(labels_a, '\0', 100);
	(void)sprintf(labels_a, "%lf%% APY", apy);
	gdImageString(im, gdFontMediumBold,   70+i*pix_per_month+5,   top_i+160, (unsigned char *)labels_a, green);
	
	memset(labels_a, '\0', 100);
	(void)sprintf(labels_a, "Monthly Contrib:");
	gdImageString(im, gdFontMediumBold,   70+i*pix_per_month+5,   top_i+180, (unsigned char *)labels_a, blue);
	memset(labels_a, '\0', 100);
	(void)sprintf(labels_a, "$%.02lf", monthly_contrib);
	gdImageString(im, gdFontMediumBold,   70+i*pix_per_month+5,   top_i+200, (unsigned char *)labels_a, blue);


	memset(labels_a, '\0', 100);
	(void)sprintf(labels_a, "%u Months", total_months);
	gdImageString(im, gdFontMediumBold,   70+i*pix_per_month+5,   top_i+220, (unsigned char *)labels_a, black);

	

	//Total_Interest_Payed

	//write out image
	out = fopen("APY.png", "w");
	gdImageInterlace(im, 1);
	gdImagePng(im, out);
	fclose(out); 
	gdImageDestroy(im);

	return 0;
}
