#include <gd.h>
#include "gdfontl.h"
#include <string.h>
#include <unistd.h>
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <sys/time.h>
#include "dates.h"
#include "cores.h"
//#include "doubletoint.h"
#include "gdfonts.h"
#include "gdfontt.h"
#include "gdfontl.h"
//gdfontt.h", "gdfonts.h", "gdfontmb.h", "gdfontl.h" and "gdfontg.h"


//int error()
//{
//	printf("Error, out of bounds exception!");
//}


//int memarray1[9];

int main() {
	gdImagePtr im; 
	FILE *out; 
	int black,white,red,blue,green,yellow,orange,purple,brown,grey;
	FILE* lscpulog;  

	im = gdImageCreate(1620,955); 

	white = gdImageColorAllocate(im, 255, 255, 255);
	black = gdImageColorAllocate(im, 0, 0, 0); 
	//white = gdImageColorAllocate(im, 255, 255, 255);	
	red = gdImageColorAllocate(im, 255, 0, 0);
	blue = gdImageColorAllocate(im, 0, 0, 255);
	green = gdImageColorAllocate(im, 0, 255, 0);
	yellow = gdImageColorAllocate(im, 255, 255, 0);
	orange = gdImageColorAllocate(im, 255, 128, 0);
	purple = gdImageColorAllocate(im, 255, 0, 255);
	brown = gdImageColorAllocate(im, 128, 64, 0);
	grey = gdImageColorAllocate(im, 128, 128, 128);


	////declare variables

        char *token;
        char *line;
        char *search = " ";
	
	//char *token2;
	//char *line2;
	//char *search2 = "+";

	char linestring[1000];
	char copystr[1000];
	//char copystr2[1000];

	char temp[30];
	char labeldate2[30];
	char labelstring[30];
	char labelstring2[30];
	char datestrcurrent[30];	

	int i;
	int lastline;
	int isam;
	int minsince;
	int minsince2;
	//int minsince3;
	int lastminsince;
	
	int hour, min, sec;
	int labeldate1;
	int counter, counter2, counter3, counter4, counter5, count4;
	int modulo4;
	int coordinate = 60;
	int emptyvarstr;
        int difference = 0;
        int lastdate = 0;  
        int stagger = 230; 
	int y10, x10, ylines, boxes, thecorenumber;	
	int plotnums, lowest, highest;

	double processhgt = 100;
	double tenth;
	double processhgt2;
	double num3 = 210; 
	double num4, num5;
	double user, nice, system, idle, iowait, irq, softirq, totalcycles, processes, processx;	
	double procnum1, procnum2, procnum3, procnum4, procnum5, procnum6;

	//coordinate
	double downnum = 210;
	//points
	int num6 = 0;
	int coresfound = coresdetected();
	//meminfo(1,memarray1);
	
	
        struct tm *local;
        time_t t;

	//memsize = memarray1[1] / 1024;

	//int tenth = memsize / 10; 

	//////////////


///// search the last 1440 entries and find the highest processes occurance
	//i == 1440
        if( ( lscpulog = fopen( "/usr/lib/lsnet/lscpu.log", "r" ) ) == NULL ) {
                fprintf( stderr, "Error opening /usr/lib/lsnet/lscpu.log\n" );
                exit( 1 );
        }
        while( fgets(linestring, sizeof(linestring), lscpulog) != NULL)
        {
                        strcpy(copystr, linestring);
                        minsince = dates(copystr);
                        //if (i == 1440)
                        //{
                        //        lastminsince = minsince;
                        //}
                        if (minsince >= minsince2 - 1440)
                        { 
                                if (i >= 0)
                                {
                                        strcpy(copystr, linestring);
                                        token = strtok(copystr, search);
                                        token = strtok(NULL, search);
                                        token = strtok(NULL, search);
                                        token = strtok(NULL, search);
                                        token = strtok(NULL, search);
                                        token = strtok(NULL, search);
                                        processhgt2 = atof(token);
					if (processhgt2 > processhgt)
					{
						processhgt = processhgt2;
					}



				}
			}
	}

	fclose(lscpulog);
//printf("closed file\n");

	tenth = processhgt / 10;
	tenth = ceil(tenth);


	counter4 = 110;
	counter5 = tenth;
//printf("tenth: %lf counter4: %d counter5: %d\n", tenth, counter4, counter5);
	emptyvarstr = sprintf( labelstring, "%d", counter5);
	while (counter5 <= processhgt)
	{
        	counter4 = counter4 - 10;
        	//$im->string(gdSmallFont,25,counter4,counter5,black);
                gdImageString(im, gdFontSmall,   25   ,   counter4    , labelstring , black);
		gdImageLine(im, 35, counter4, 1500, counter4, black);
        	counter5 = counter5 + tenth;
		
		emptyvarstr = sprintf( labelstring, "%d", counter5);
	}

//printf("passed sprintf\n");

	//###########

	ylines = 800 / coresfound;
	boxes = 800 / ylines;

	y10 = ylines + 110;
	x10 = 110;

	tenth = ylines / 10;
 

	gdImageLine(im, 50, 110, 1500, 110, black);
	gdImageLine(im, 50, 10, 50, 910, black);
	gdImageLine(im, 50, 910, 1500, 910, black);
//printf("made first image writ\n");
        
	//#######drawl horizontal lines and % usage labels


	for (i = 1; i <= coresfound; i++ )
	{
        	counter4 = 10;  
        	counter5 = 310 + (200 * (i - 1));
		emptyvarstr = sprintf( labelstring2, "%d%%", counter4);
        	while (counter4 <= 100)
        	{  
			//printf("counter5: %d\n", counter5);
                	counter5 = counter5 - tenth;
                	if (counter4 == 50)
                	{
                        	thecorenumber = i - 1;
				emptyvarstr = sprintf( labelstring, "CORE%d", thecorenumber);
				gdImageString(im, gdFontLarge, 5, counter5 , labelstring , black);
                	}else{
				gdImageString(im, gdFontLarge, 20 , counter5 , labelstring2 , black);
                	}

                	//if (counter4 == 100)
                	//{
			gdImageLine(im, 30, counter5, 1500 , counter5 , black);
			//printf("Counter5: %d\n", counter5);
                	//}else{
			
                  	//      $im->dashedLine(30,counter5,1500,counter5,gdStyled);
                	//}
                	counter4 = counter4 + 10;
			emptyvarstr = sprintf( labelstring2, "%d%%", counter4);
        	}
	}


        	coordinate = 60;
        	
        	difference = 0;
        	
        	i = 1;
        	stagger = 930;

        	//#####determine lowest pixel for this core's box
        	//lowest = 110 + (ylines * plotnums);
        	//highest = lowest - ylines;

        	if( ( lscpulog = fopen( "/usr/lib/lsnet/lscpu.log", "r" ) ) == NULL ) {
                	fprintf( stderr, "Error opening /usr/lib/lsnet/lscpu.log\n" );
                	exit( 1 );
        	}

        	t = time(NULL);
        	local = localtime(&t);
        	strcat(datestrcurrent, asctime(local));
        	datestrcurrent[strlen(datestrcurrent)-1]='\0';
		minsince2 = dates(datestrcurrent);
		//printf("minsince2: %d\n", minsince2);
		//lastminsince = minsince;
		i = 1440;
		//Wed Feb 25 17:06:45 2009 128 0.750195 98.949744 0.283394 0.000000 0.000000 0.016667 0.000000+0.083333 82.550000 17.350000 0.000000 0.000000 0.000000 0.016667+
		//0.733278 99.000089 0.233311 0.033322 0.000000 0.000000 0.000000+0.750000 98.966667 0.250000 0.000000 0.000000 0.000000 0.033333

        	while( fgets(linestring, sizeof(linestring), lscpulog) != NULL)
        	{
				//printf("opened file, linestring: %s\n", linestring);
				strcpy(copystr, linestring);
				//printf("copied string\n");		
				minsince = dates(copystr);
				//printf("minsince: %d\n", minsince);
				if (i == 1440)
				{
					lastminsince = minsince;
				}
				if (minsince >= (minsince2 - 1439) && coordinate <= 1500)
				{ 
					///cores loop goes here
					//for (plotnums = 1; plotnums <= coresfound; plotnums++)
					//{
					if (i >= 0)
					{
						for (plotnums = 1; plotnums <= coresfound; plotnums++)
						{
							if(plotnums == 1)
							{

								//printf("started loops\n");
								//user, nice, system, idle, iowait, irq, softirq
								strcpy(copystr, linestring);
								token = strtok(copystr, search);
								token = strtok(NULL, search);
								token = strtok(NULL, search);
								token = strtok(NULL, search);
					
								temp[0]=token[0];
								temp[1]=token[1];
								temp[2]=0;
								hour = atoi(&temp);

								temp[0]=token[3];
								temp[1]=token[4];
								temp[2]=0;
                        					min = atoi(&temp);
							//Wed Feb 25 17:06:45 2009 128 0.750195 98.949744 0.283394 0.000000 0.000000 0.016667 0.000000+
								temp[0]=token[6];
								temp[1]=token[7];
								temp[2]=0;
                        					sec = atoi(&temp);

								token = strtok(NULL, search);
								token = strtok(NULL, search);
								processes = atof(token);
								//printf("Processes: %lf\n", processes);
								token = strtok(NULL, search);
								user = atof(token);
								token = strtok(NULL, search);
								nice = atof(token);
								token = strtok(NULL, search);
								system = atof(token);
								token = strtok(NULL, search);
								idle = atof(token);
								token = strtok(NULL, search);
								iowait = atof(token);
								token = strtok(NULL, search);
								irq = atof(token);
								token = strtok(NULL, search);
								///take only the first 8 elements(might have to fix later for sizeof(double)
								temp[0]=token[0];
								temp[1]=token[1];
								temp[2]=token[2];
								temp[3]=token[3];
								temp[4]=token[4];
								temp[5]=token[5];
								temp[6]=token[6];
								temp[7]=token[7];
								temp[8]=0;
								softirq = atof(&temp);
                                                        	processx = 110 - ((100 / processes) * 100);
                                                        	//$im->line($coordinate,$processx,$coordinate,110,$black);
                                                        	gdImageLine(im, coordinate, processx, coordinate , 110 , black);
                                                        	if (difference >= 2)
                                                        	{
                                                                	//difference = lastminsince - minsince;
                                                                	difference = ceil(difference);
                                                                	//#leave a blank line for each 1min lost
                                                                	for (counter3 = 1; counter3 < difference; counter3++)
                                                                	{
                                                                        	coordinate++;
                                                                	}
                                                        	}

                                                		//if multiple of 60 drawl date labels
                                                		modulo4 = coordinate % 60;
                                                		if (modulo4 == 0)
                                                		{
                                                        		labeldate1 = hourhash(hour);
                                                        		isam = ampm(hour);
                                                        		if (isam == 1)
                                                        		{
                                                                		emptyvarstr = sprintf( labeldate2, "%d:%d:%d AM", labeldate1, min, sec);
                                                        		}else{
                                                                		emptyvarstr = sprintf( labeldate2, "%d:%d:%d PM", labeldate1, min, sec);
                                                        		}
                                                        		if (stagger == 930)
                                                        		{
                                                                		stagger = 920;
                                                        		}else{
                                                                		stagger = 930;
                                                        		}
                                                        		gdImageString(im, gdFontSmall,   coordinate - 30   ,  stagger  , labeldate2 , black);
                                                        		gdImageLine(im, coordinate, 210, coordinate , stagger, black);
                                                		}
								counter5 = 2;
							}else{
								//+0.750000 98.966667 0.250000 0.000000 0.000000 0.000000 0.033333

								//token = strtok(copystr, search);
								///take only the last 8 elements (might have to fix later for sizeof(double)
								temp[0]=token[9];
								temp[1]=token[10];
								temp[2]=token[11];
								temp[3]=token[12];
								temp[4]=token[13];
								temp[5]=token[14];
								temp[6]=token[15];
								temp[7]=token[16];
								temp[8]=0;
								user = atof(&temp);
								token = strtok(NULL, search);
								nice = atof(token);
								token = strtok(NULL, search);
								system = atof(token);
								token = strtok(NULL, search);
								idle = atof(token);
								token = strtok(NULL, search);
								iowait = atof(token);
								token = strtok(NULL, search);
								irq = atof(token);
								token = strtok(NULL, search);
								///grab only the first 8 elements
								temp[0]=token[0];
								temp[1]=token[1];
								temp[2]=token[2];
								temp[3]=token[3];
								temp[4]=token[4];
								temp[5]=token[5];
								temp[6]=token[6];
								temp[7]=token[7];
								temp[8]=0;
								softirq = atof(&temp);
								//printf("Hour: %d Min:%d Sec:%d\n",hour, min, sec);
						}
							//printf("Core: %lf user:%lf nice:%lf system: %lf idle: %lf iowait: %lf irq: %lf softirq: %lf\n",plotnums, user, nice, system, idle, iowait, irq, softirq);						
                                        		difference = minsince - lastminsince;  
                                			//printf("Difference: %d Minsince: %d Lastminsince: %d\n", difference, minsince, lastminsince);

					                lowest = 110 + (ylines * plotnums);
                					highest = lowest - ylines;



                                			procnum1 = ((ylines * plotnums) + 110);
                                			procnum1 = procnum1 - ((softirq / 100) * ylines);
                                        
                                			//#irq purple,
                                			procnum2 = procnum1;
                                			procnum2 = procnum2 - ((irq / 100) * ylines);
                                        
                                			//#$iowait orange
                                			procnum3 = procnum2;
                                			procnum3 = procnum3 - ((iowait / 100) * ylines);
                                        
                                			//#$system red
                                			procnum4 = procnum3;
                                			procnum4 = procnum4 - ((system / 100) * ylines);
                                        
                                			//#$user blue
                                			procnum5 = procnum4;
                                			procnum5 = procnum5 - ((user / 100) * ylines);
                                        
                                			//#$nice grey
                                			procnum6 = procnum5;
                                			procnum6 = procnum6 - ((nice / 100) * ylines);

                                                	//#total, what's not overwritten will show idle green
							gdImageLine(im, coordinate, lowest, coordinate , highest, green);
                                                	//#softirq brown
							gdImageLine(im, coordinate, procnum1, coordinate , lowest, brown);
                                                	//#irq purple
							gdImageLine(im, coordinate, procnum2, coordinate , procnum1, purple);
                                                	//#$iowait orange
							gdImageLine(im, coordinate, procnum3, coordinate , procnum2, orange);
                                                	//#$system red
							gdImageLine(im, coordinate, procnum4, coordinate , procnum3, red);
                                                	//#$user blue
							gdImageLine(im, coordinate, procnum5, coordinate , procnum4, blue);
                                                	//#$nice grey
							gdImageLine(im, coordinate, procnum6, coordinate , procnum5, grey);
						}
						coordinate++;
						//lastminsince = minsince;
						i--;
			
					}	
					lastminsince = minsince;
					//coordinate++;
				}
	}
	gdImageFilledRectangle(im, 1520, 65, 1540, 85, black); 
	gdImageString(im, gdFontSmall,   1545   ,   85  , "Processes" , black); 
	gdImageFilledRectangle(im, 1520, 165, 1540, 185, green); 
	gdImageString(im, gdFontSmall,   1545   ,   185  , "Idle" , green);
	gdImageFilledRectangle(im, 1520, 205, 1540, 225, red); 
	gdImageString(im, gdFontSmall,   1545   ,   225  , "System" , red);
	gdImageFilledRectangle(im, 1520, 245, 1540, 265, blue);
	gdImageString(im, gdFontSmall,   1545   ,   265  , "User" , blue); 
	gdImageFilledRectangle(im, 1520, 285, 1540, 305, grey); 
	gdImageString(im, gdFontSmall,   1545   ,   305  , "Nice" , grey);
	gdImageFilledRectangle(im, 1520, 325, 1540, 345, orange);
	gdImageString(im, gdFontSmall,   1545   ,   345  , "IOWait" , orange);
	gdImageFilledRectangle(im, 1520, 365, 1540, 385, purple);
	gdImageString(im, gdFontSmall,   1545   ,   385  , "Irq" , purple);
	gdImageFilledRectangle(im, 1520, 405, 1540, 425, brown);
	gdImageString(im, gdFontSmall,   1545   ,  425  , "SoftIrq" , brown); 

	out = fopen("/var/www/htdocs/lsnet/cpu.jpg", "w"); 
	gdImageJpeg(im, out, -1); //write the image to thefile using the default quality setting

	fclose(lscpulog);
	fclose(out); 
	gdImageDestroy(im);
	return (0);
}

