/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*-  */
/*
 * cartogram.c
 * Copyright (C) 2016 D.M. Gualtieri <gualtieri@ieee.org>
 * 
 * cartogram is free software: you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the
 * Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * cartogram is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * See the GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License along
 * with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

//State data is a tab-delimited CSV file.
//First column is two letter abbreviation (upper case)
//Second column is the data (float)
//includes just the contiguous 48 states plus DC
 
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 
 /* Prototypes */

long atol(const char *s);
size_t strlen( const char *s);
char *strcpy(char *dest, const char *src);
char *strcat( char *s1, const char *s2);
char *strncat( char *s1, const char *s2, size_t n);
char *strtok(char *str, const char *delim);
char *itoa ( int value, char * str, int base );
char *fgets(char *str, int n, FILE *stream);
void exit(int status);

/* end of prototypes */

long fctr;
int ret_value;
int field;
long size;
int stretch = 0;
float min,max;
int n;
int i,j;
int user_response;
char st_num[16];
char fn1[64];
char fn2[64];
char line[1000];
int num_images;
int num_objects;
int bear_position;
char * states[49] = {"AL", "AR", "AZ", "CA", "CO", "CT", "DC", "DE", "FL", 
"GA", "IA", "ID", "IL", "IN", "KS", "KY", "LA", "MA", "MD", "ME", "MI", "MN", 
"MO", "MS", "MT", "NC", "ND", "NE", "NH", "NJ", "NM", "NV", "NY", "OH", "OK", 
"OR", "PA", "RI", "SC", "SD", "TN", "TX", "UT", "VA", "VT", "WA", "WI", "WV", 
"WY"};
float longitude[49] ={-86.8073, -92.3809, -111.3877, -119.7462, -105.3272, 
-72.7622, -77.0262, -75.5148, -81.717, -83.6487, -93.214, -114.5103, -89.0022, 
-86.2604, -96.8005, -84.6514, -91.8749, -71.5314, -76.7902, -69.3977, -84.5603, 
-93.9196, -92.302, -89.6812, -110.3261, -79.8431, -99.793, -98.2883, -71.5653, 
-74.5089, -106.2371, -117.1219, -74.9384, -82.7755, -96.9247, -122.1269, 
-77.264, -71.5101, -80.9066, -99.4632, -86.7489, -97.6475, -111.8535, -78.2057, 
-72.7093, -121.5708, -89.6385, -80.9696, -107.2085};
float latitude[49] ={32.799, 34.9513, 33.7712, 36.17, 39.0646, 41.5834, 
38.8964, 39.3498, 27.8333, 32.9866, 42.0046, 44.2394, 40.3363, 39.8647, 
38.5111, 37.669, 31.1801, 42.2373, 39.0724, 44.6074, 43.3504, 45.7326, 
38.4623, 32.7673, 46.9048, 35.6411, 47.5362, 41.1289, 43.4108, 40.314, 
34.8375, 38.4199, 42.1497, 40.3736, 35.5376, 44.5672, 40.5773, 41.6772, 
33.8191, 44.2853, 35.7449, 31.106, 40.1135, 37.768, 44.0407, 47.3917, 
44.2563, 38.468, 42.7475};
char csv_states[49][3];
float csv_data[49];
float csv_sorted_data[49];
char *token;
FILE *indata;
FILE *outdata;

//Draws a circle at (xx,yy) with radius r
const char* circle(int xx, int yy, int r, unsigned int color) 
{
	
static char circle_string[256] = "";

strcpy(circle_string, "\0");

//example: <circle cx="40" cy="40" r="24" style="stroke:#006600; fill:#00cc00"/>
//sprintf(circle_string, "<circle cx=\"%d\"  cy=\"%d\" r=\"%d\" style=\"stroke:#000000; fill:#%06x\"/>\n",xx,yy,r,(unsigned int)0x000000);
sprintf(circle_string, "<circle cx=\"%d\"  cy=\"%d\" r=\"%d\" style=\"stroke:#000000; fill:#%06x\"/>\n",xx,yy,r,color);

return circle_string;
}

//Puts text at (xx,yy)
const char* text(int xx, int yy,  char st_text[]) 
{
	
static char text_string[256] = "";

strcpy(text_string, "\0");
sprintf(text_string, "<text x=\"%d\"  y=\"%d\" style=\"font-family: Arial; font-size: 22; stroke:#000000; fill:#ffffff;\">%s</text>\n",xx,yy,st_text);

return text_string;
}


int main(int argc, char *argv[])
{

printf("Stretch Eastern States? (Y/N):");
scanf("%c", &user_response);
if ((user_response == 'Y')||(user_response == 'y'))
{
stretch = 1;
}

//Scale longitude and latitude

for (n=0;n<49;n++)
{
longitude[n] = 18.0*(130+longitude[n]);
//Implement stretch
if((stretch!=0)&&(longitude[n]>900))
{
longitude[n] = 900 + 2.5*(longitude[n]-900);
}
latitude[n] = 34.0*(52-latitude[n]);
//printf("%f\t%f\n", longitude[n],latitude[n]);
}


strcpy(fn1,argv[1]);
printf("\nInput file selected = %s\n",fn1);

if ((indata = fopen(fn1,"rb"))==NULL)
	{printf ("\nInput file cannot be opened.\n");
	exit (1);}

// Get input file size
   fseek(indata, 0, SEEK_END);
   size = ftell(indata);
   rewind(indata);
   
   printf("Filename = %s\n",fn1);
   printf("file size = %ld\n",size);


//Read CSV file data lines

for (n=0;n<49;n++)
{
fgets ( line, sizeof line, indata);

// get the first token
strcpy(&csv_states[n][0], strtok(line, "\t"));

//get the second token
token = strtok(NULL, "\t");
sscanf (token, "%f", &csv_data[n]);

}

//find max/min of data
max = 0;
min = 1E32;

for (n=0;n<49;n++)
{
if(csv_data[n]>max)
{
max=csv_data[n];
}
if(csv_data[n]<min)
{
min=csv_data[n];
}
}

printf("min = %f\tmax = %f\n",min,max);

//scale data
for (n=0;n<49;n++)
{
csv_data[n] = 5 + 45*(csv_data[n]/max);
}

//sort data into proper order
for(i=0;i<49;i++)
{
for(j=0;j<49;j++)
{
if (strcmp(states[i],csv_states[j])==0)
{
csv_sorted_data[i]=csv_data[j];
}
}
}

strcpy(fn2, "output.svg");

if ((outdata = fopen(fn2,"w"))==NULL)
	{printf ("\nOutput file cannot be opened.\n");
	exit (1);}
	
// Print svg header
fprintf(outdata,"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n");
fprintf(outdata,"<svg xmlns=\"http://www.w3.org/2000/svg\"\n");
fprintf(outdata,"xmlns:xlink=\"http://www.w3.org/1999/xlink\"\n");
fprintf(outdata,"xmlns:ev=\"http://www.w3.org/2001/xml-events\"\n");
if (stretch==0)
{
fprintf(outdata,"width=\"1250\" height=\"900\">\n");
}
else
{
fprintf(outdata,"width=\"1500\" height=\"900\">\n");
}

//Set background color by adding a filled rectangle_angle
//printf("<rect width=\"1250\" height=\"900\" style=\"fill:#000000;stroke-width:3;stroke:#000000\" />\n");
if(stretch==0)
{
fprintf(outdata,"<rect width=\"1250\" height=\"900\" style=\"fill:#ffffff;stroke-width:3;stroke:#ffffff\" />\n");
}
else
{
fprintf(outdata,"<rect width=\"1500\" height=\"900\" style=\"fill:#ffffff;stroke-width:3;stroke:#ffffff\" />\n");
}

//draw circles

for (n=0;n<49;n++)
{
fprintf(outdata, "%s\n",circle(longitude[n], latitude[n], 3*csv_sorted_data[n], 0x6ec3ff));
fprintf(outdata, "%s\n",text(longitude[n]-18, latitude[n]+10, states[n]));
}

//redraw smaller circles
for (n=0;n<49;n++)
{
if(csv_data[n]<20)
{
fprintf(outdata, "%s\n",circle(longitude[n], latitude[n], 3*csv_sorted_data[n], 0x6ec3ff));
fprintf(outdata, "%s\n",text(longitude[n]-18, latitude[n]+10, states[n]));
}
}


// Print svg footer
fprintf(outdata,"</svg>");


printf("Done.\n");

fclose(outdata);

	return (0);
}
