/*
 * draw_gps.c
 * Copyright (C) Steffen Pohle 2011 <steffen@gulpe.de>
 * 
 * main.c 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.
 * 
 * main.c 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/>.
 */

#include <sys/time.h>
#include <math.h>

#include "osmroute.h"
#include "draw.h"
#include "map.h"
#include "gps.h"


/*
 * drawgps_ variables needed for drawing gps stuff..
 */
struct gps_data drawgps_data;
unsigned long long int drawgps_on_way_id = 0;
unsigned short int drawgps_on_way_sid = 0;
char drawgps_on_way_name[MAP_W_NAMELEN] = "\0";


void drawgps_set_pos (struct gps_data *gpsdata) {
	static char _gpspos_to = 0;
	struct map_pos p, p1;
	fPoint fp;
	float f1;

	memcpy (drawgps_data.sat, gpsdata->sat, 32*sizeof (struct gps_satelite));
	drawgps_data.hdop = gpsdata->hdop;
	drawgps_data.numofsatelites = gpsdata->numofsatelites;
	drawgps_data.quality = gpsdata->quality;
		
	if (gpsdata->valid) {
		draw_set_flag (DRAW_GPS);
		drawgps_data.lon = gpsdata->lon;
		drawgps_data.lat = gpsdata->lat;
		if (view_flags & DRAW_GPSFOLLOW && mousebtn == 0) {
			iPoint ip = 	draw_geo2screen (view_lon, view_lat, drawgps_data.lon, drawgps_data.lat);
			if (ip.x < (gfx_screensize.x / 4) || ip.x > (gfx_screensize.x - (gfx_screensize.x/4)) ||
			   (ip.y < (gfx_screensize.y / 4) || ip.y > (gfx_screensize.y - (gfx_screensize.y/4)))) {
					view_lon = drawgps_data.lon;
					view_lat = drawgps_data.lat;

				    /* recalc position */
				    if (gpsdata->speed > 20.0) {
						/* speed factor */
						f1 = (gpsdata->speed-20.0)/70.0;
						if (f1 > 1.0) f1 = 1.0;
				   
						/* screen factor */
						fp.x = sin (M_PI*gpsdata->direction/180.0) * f1 * gfx_screensize.x * 0.3 + gfx_screensize.x/2.0;
						fp.y = -cos (M_PI*gpsdata->direction/180.0) * f1 * gfx_screensize.y * 0.3 + gfx_screensize.y/2.0;
						draw_screen2geo (fp.x, fp.y, &p.lon, &p.lat);
						view_lon = p.lon;
						view_lat = p.lat;
					}
				}
		}

		if (gpsdata->valid) {
			drawgps_data.time = gpsdata->time;
			drawgps_data.speed = gpsdata->speed;
			drawgps_data.valid = gpsdata->valid;
			drawgps_data.direction = gpsdata->direction;
			drawgps_data.height = gpsdata->height; 
						
			/* find closest way */
			p.lon = drawgps_data.lon;
			p.lat = drawgps_data.lat;
		
			/* routing? */
			map_way_findclosest (&p, &p1, 0, drawgps_on_way_name, MAP_W_NAMELEN, &drawgps_on_way_id, &drawgps_on_way_sid);
		}
	}
	
	if (gpsdata->quality != 0 || ((view_flags & DRAW_DEBUG) && ((_gpspos_to--) < 0))) {
		draw ();
		_gpspos_to = 100;
	}
};


/*****************************************************************************
 * draw gps position and information
 */
void draw_gui_gps () {
	struct line_style tmplinestyle;
	iPoint p1, p2, center = {gfx_screensize.x/2, gfx_screensize.y/2};
	int i;
	char text[64];
	struct gps_data *gpsdata;

	/*
	 * gpsroute 
	 */
 	if (gps_isrunning() == 0 && gpsroute) {
		if (gpsroute->cnt > 1) {
			tmplinestyle.width = 1.0;
			tmplinestyle.c = tmplinestyle.borderc = color[COLOR_red][3];

			p1 = draw_geo2screen (view_lon, view_lat, gpsroute->data[0].lon, gpsroute->data[0].lat);
			p1.x += center.x;
			p1.y += center.y;
			for (i = 1; i < gpsroute->cnt; i++) {
				p2 = draw_geo2screen (view_lon, view_lat, gpsroute->data[i].lon, gpsroute->data[i].lat);
				p2.x += center.x;
				p2.y += center.y;
				if ((p1.x >= 0 && p1.x < gfx_screensize.x && p1.y >= 0 && p1.y < gfx_screensize.y) || 
				    (p2.x >= 0 && p2.x < gfx_screensize.x && p2.y >= 0 && p2.y < gfx_screensize.y))
					draw_line (NULL, p1.x, p1.y, p2.x, p2.y, tmplinestyle);
				p1 = p2;
			}
		}
		
		if (gpsroute->pcnt > 0) {
			tmplinestyle.width = 1.0;
			tmplinestyle.c = tmplinestyle.borderc = color[COLOR_red][1];

			for (i = 0; i < gpsroute->pcnt; i++) {
				p1 = draw_geo2screen (view_lon, view_lat, gpsroute->pdata[i].lon, gpsroute->pdata[i].lat);
				p1.x += center.x;
				p1.y += center.y;
				draw_line (NULL, p1.x-5, p1.y-5, p1.x+5, p1.y+5, tmplinestyle);
				draw_line (NULL, p1.x+5, p1.y-5, p1.x-5, p1.y+5, tmplinestyle);
				gfx_draw_text (NULL, p1.x-10, p1.y+5, gpsroute->pdata[i].name, &color[COLOR_redgray][3]);
			}
		}
	}

	/*
	 * basic gps information 
	 */
	if (view_flags & DRAW_GPS) {
		iPoint p3, p;
		p = draw_geo2screen (view_lon, view_lat, drawgps_data.lon, drawgps_data.lat);
		p.x += center.x;
		p.y += center.y;

		tmplinestyle.width = 1.0;
		tmplinestyle.c = tmplinestyle.borderc = color[COLOR_bluegray][3];
		for (i = 1; i < 10; i++) {
			p1.x = sin (M_PI*drawgps_data.direction/180.0) * 12 + p.x;
			p1.y = -cos (M_PI*drawgps_data.direction/180.0) * 12 + p.y;

			p2.x = sin (M_PI*(drawgps_data.direction-120.0)/180.0) * i + p.x;
			p2.y = -cos (M_PI*(drawgps_data.direction-120.0)/180.0) * i + p.y;

			p3.x = sin (M_PI*(drawgps_data.direction+120.0)/180.0) * i + p.x;
			p3.y = -cos (M_PI*(drawgps_data.direction+120.0)/180.0) * i + p.y;

			draw_line (NULL, p1.x, p1.y, p2.x, p2.y, tmplinestyle);
			draw_line (NULL, p1.x, p1.y, p3.x, p3.y, tmplinestyle);
			draw_line (NULL, p3.x, p3.y, p2.x, p2.y, tmplinestyle);
		}
		i = 6;
		p1.x = sin (M_PI*drawgps_data.direction/180.0) * 8 + p.x;
		p1.y = -cos (M_PI*drawgps_data.direction/180.0) * 8 + p.y;

		p2.x = sin (M_PI*(drawgps_data.direction-120.0)/180.0) * 5 + p.x;
		p2.y = -cos (M_PI*(drawgps_data.direction-120.0)/180.0) * 5 + p.y;

		p3.x = sin (M_PI*(drawgps_data.direction+120.0)/180.0) * 5 + p.x;
		p3.y = -cos (M_PI*(drawgps_data.direction+120.0)/180.0) * 5 + p.y;
	
		tmplinestyle.width = 1.0;
		tmplinestyle.c = tmplinestyle.borderc = color[COLOR_white][3];
		draw_line (NULL, p1.x, p1.y, p2.x, p2.y, tmplinestyle);
		draw_line (NULL, p1.x, p1.y, p3.x, p3.y, tmplinestyle);
		draw_line (NULL, p2.x, p2.y, p3.x, p3.y, tmplinestyle);
	}

	if (view_flags & DRAW_DEBUG) if (gps_isrunning()) {
		gpsdata = gps_getposition ();
		/* draw sat satus */
		tmplinestyle.width = 1.0;
		tmplinestyle.c = tmplinestyle.borderc = color[COLOR_white][2];
		p1.x = 5;
		p1.y = 60;
		p2.x = 5 + 99;
		p2.y = 60 + 32 * 3;
		for (i = 0; i < 2; i++) 
			draw_line (NULL, p1.x+i*25, p1.y, p1.x+i*25, p2.y, tmplinestyle);
		tmplinestyle.c = tmplinestyle.borderc = color[COLOR_white][3];
		for (i = 0; i < 32; i++) {
			p1.x = 5;
			p1.y = 60 + i * 3;
			p2.x = 5 + gpsdata->sat[i].quality;
			p2.y = 60 + i * 3;
			draw_line (NULL, p1.x, p1.y, p2.x, p2.y, tmplinestyle);
		}
		sprintf (text, "Lon:%7.3f Lat:%7.3f Height:%4.0f", gpsdata->lon, gpsdata->lat, gpsdata->height);
		gfx_draw_text (NULL, 0, 150, text, &color[COLOR_green][3]);
		sprintf (text, "Sats:%d Quality:%d HDOP:%5.2f", gpsdata->numofsatelites, gpsdata->quality, gpsdata->hdop);
		gfx_draw_text (NULL, 0, 162, text, &color[COLOR_green][3]);
		sprintf (text, "GPS Signal");
		gfx_draw_text (NULL, 0, 40, text, &color[COLOR_white][3]);
	}

	if (view_flags & DRAW_GPS) {
		sprintf (text, "%3.0f km/h :%s", drawgps_data.speed, drawgps_on_way_name);
		gfx_draw_text (NULL, 0, gfx_screensize.y-16, text, &color[COLOR_green][2]);
	}
};

