#include "geotrace.h"
GdkPixmap *pixmap = NULL;
GdkPixbuf *pixbuf = NULL;
GList *map_strings,*map_properties;
GtkRequisition *pix_size;
char *curmap;
// following vars for map properties calculations
int falseeast,falsenorth,projection;
float boundaries[4],alat,alon,blat,blon,radius,phione,phitwo,phinought,lambdanought;
float phionerad,phitworad,phinoughtrad,lambdanoughtrad,nalber,calber,pnought;

void set_map_from_file(char *map_file) {
	GdkPixbuf *tmp_pixbuf = NULL;
	char *tmpmap=NULL;

	tmpmap = malloc (strlen(maps_dir_path)+strlen(map_file)+1);
	strcpy (tmpmap,"");
	strcat (tmpmap,maps_dir_path);
	strcat (tmpmap,map_file);
	curmap = realloc (curmap,strlen(map_file)+1);
	strcpy (curmap,map_file);
	gtk_entry_set_text(GTK_ENTRY(map_combo_entry),curmap);

	pix_size = malloc (sizeof(GtkRequisition));
        tmp_pixbuf = gdk_pixbuf_new_from_file(tmpmap);
	free (tmpmap);

	pix_size->width = gdk_pixbuf_get_width(tmp_pixbuf);
	pix_size->height = gdk_pixbuf_get_height(tmp_pixbuf);
	get_map_boundaries(curmap);

	gdk_pixbuf_render_pixmap_and_mask(tmp_pixbuf, &pixmap, NULL, 128);
        gdk_window_set_icon(drawing_area->window,NULL,pixmap,NULL);
	gtk_widget_set_usize(drawing_area,pix_size->width,pix_size->height);
	gtk_widget_hide(drawing_area);
        gtk_widget_show(drawing_area);	
}

void expose_event() {
	gdk_draw_pixmap(drawing_area->window,
        	drawing_area->style->fg_gc[GTK_WIDGET_STATE (drawing_area)],
        	pixmap,
        	0,0,0,0,-1,-1);    
}   

void scan_maps_file () {
	FILE *map_props_file;
	char *tmpstr,*tmpstr2,*tmppath;

	map_strings = NULL;
	host_strings = NULL;
	tmpstr = malloc (512);
	tmppath = malloc (strlen(maps_dir_path)+strlen(MAP_FILE)+1);
	sprintf (tmppath,"%s%s",maps_dir_path,MAP_FILE);
	map_props_file = fopen(tmppath,"r");
	while (!feof(map_props_file)) {
		fscanf(map_props_file,"%[^\n]\n",tmpstr);
		tmpstr2 = strtok(tmpstr,":");
		tmpstr = strtok(NULL,":");
		curmap = malloc (strlen(start_map)+1);
		strcpy(curmap,start_map);
		if (strcmp("MAPS",tmpstr2) == 0) {
			tmpstr2 = strtok (tmpstr,",");
			while (tmpstr2 != NULL) {
				map_strings = g_list_insert_sorted(map_strings,strdup(tmpstr2),(GCompareFunc)strcasecmp);
				tmpstr2 = strtok(NULL,",");
			}
	gtk_combo_set_popdown_strings(GTK_COMBO(map_combo),map_strings);
		}
	}
	fclose (map_props_file);
	free (tmpstr);
	free (tmppath);
}

void get_map_boundaries(char *map_name) {
	FILE *map_props_file;
	char *tmpstr,*tmpstr2,*tmpstr3,*proj,*tmppath;
	int gna;

	projection = LINEAR;
	tmpstr = malloc (512);
	tmppath = malloc (strlen(maps_dir_path)+strlen(MAP_FILE)+1);
	sprintf (tmppath,"%s%s",maps_dir_path,MAP_FILE);
	map_props_file = fopen(tmppath,"r");
	tmpstr3 = malloc (strlen(map_name)+1);
	strcpy (tmpstr3,map_name);
	proj = malloc (6);

	fscanf(map_props_file,"%[^\n]",tmpstr);
	tmpstr2 = strtok(tmpstr,":");
	tmpstr = strtok(NULL,":");
	while (!feof(map_props_file)) {
		gna = fgetc (map_props_file);
		if (strcmp(tmpstr3,tmpstr2) == 0) {
			tmpstr2 = strtok(tmpstr,"=");
			tmpstr = strtok(NULL,"=");
			if (strcmp(tmpstr2,"BOUNDARY") == 0) {
				sscanf (tmpstr,"%f,%f,%f,%f",&boundaries[0],&boundaries[1],&boundaries[2],&boundaries[3]);
			} else if (strcmp(tmpstr2,"PROJECTION") == 0) {
				sscanf(tmpstr,"%[^,],%f,%f,%f,%f,%f,%d,%d",
					proj,&radius,&phione,&phitwo,&phinought,
					&lambdanought,&falseeast,&falsenorth);
				if (strcmp(proj,"ALBER") == 0)
					projection = ALBER;
			}
		}
		if (!feof(map_props_file)) {
			fscanf(map_props_file,"%[^\n]",tmpstr);
			tmpstr2 = strtok(tmpstr,":");
			tmpstr = strtok(NULL,":");
		}
	}
	fclose (map_props_file);
	compute_lat_lon_parameters();
	free (tmpstr);
	free (proj);
	free (tmppath);
}

void compute_lat_lon_parameters() {
	if (projection == LINEAR) {
		blon = boundaries[0];
		blat = boundaries[1];
		alon = (boundaries[2] - boundaries[0]) / pix_size->width;
		alat = (boundaries[3] - boundaries[1]) / pix_size->height;
	} else if (projection == ALBER) {
		phionerad = (phione*M_PI)/180;
		phitworad = (phitwo*M_PI)/180;
		phinoughtrad = (phinought*M_PI)/180;
		lambdanoughtrad = (lambdanought*M_PI)/180;

		nalber = (sin(phionerad)+sin(phitworad))/2;
		calber = pow(cos(phionerad),2) + 2*nalber*sin(phionerad);
		pnought = radius*sqrt(calber-2*nalber*sin(phinoughtrad))/nalber;
	}
}

float get_lat (int x,int y) {
	float x2,y2,p,retval;

	if (projection == LINEAR)
		return (alat*y + blat);
	else if (projection == ALBER) {
		x2 = x-falseeast;
		y2 = falsenorth-y;
		p = sqrt(pow(x2,2) + pow(pnought-y2,2));
		retval = asin((calber-pow(p*nalber/radius,2))/(2*nalber))*180/M_PI;
		return (retval);
	} else
		return 0;
}

float get_lon (int x,int y) {
	float x2,y2,theta,retval;

	if (projection == LINEAR)
		return (alon*x + blon);
	else if (projection == ALBER) {
		x2 = x-falseeast;
		y2 = falsenorth-y;
		theta = atan(x2 / (pnought-y2));
		retval = (lambdanoughtrad+theta/nalber)*180/M_PI;
		return (retval);
	} else 
		return 0;
}

char *point_to_lat_lon (int x,int y) {
	return format_lat_lon (get_lat(x,y),get_lon(x,y));
}

char *format_lat_lon (float lat,float lon) {
	char *retval,north,west;

	retval = malloc (20);
	if (lon > 180)
		lon -= 360;
	if (lat < 0)
		north = 'S';
	else	
		north = 'N';
	if (lon < 0)
		west = 'W';
	else	
		west = 'E';
	sprintf (retval,"%5.2f%c, %5.2f%c",fabs(lat),north,fabs(lon),west);
	return retval;
}

int lat_lon_to_y (float lat,float lon) {

	if (projection == LINEAR) 
		return (int)((lat-blat)/alat+0.5);
	else if (projection == ALBER) {
		return (lat_lon_to_x_y(lat,lon,0));
	} else
		return (0);
}

int lat_lon_to_x (float lat,float lon) {

	if (projection == LINEAR) 
		return (int)((lon-blon)/alon+0.5);
	else if (projection == ALBER) {
		return (lat_lon_to_x_y(lat,lon,1));
	} else
		return (0);
}

// which: 0 for y, 1 for x
int lat_lon_to_x_y (float lat,float lon,int which) {
	float phi2,lambda2,p,theta;
	int x,y;

	phi2 = lat*M_PI/180;
	lambda2 = lon*M_PI/180;
	p = radius*sqrt(calber-2*nalber*sin(phi2))/nalber;
	theta = nalber*(lambda2-lambdanoughtrad);
	x = falseeast+(int)(p*sin(theta));
	y = falsenorth-(int)(pnought-p*cos(theta));

	if (which)
		return (x);
	else
		return (y);
}


syntax highlighted by Code2HTML, v. 0.9.1