/*
    Output only format for Human Readable formats.

    Copyright (C) 2004 Scott Brynen, scott (at) brynen.com
    Copyright (C) 2002 Robert Lipe, robertlipe@usa.net

    This program 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 2 of the License, or
    (at your option) any later version.

    This program 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, write to the Free Software
    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA
*/


#include "defs.h"
#include "jeeps/gpsmath.h"
#include <ctype.h>

static gbfile *file_out;
static short_handle mkshort_handle;

static char *stylesheet = NULL;
static char *html_encrypt = NULL;
static char *includelogs = NULL;
static char *degformat = NULL;
static char *altunits = NULL;

#define MYNAME "HTML"

static
arglist_t html_args[] = {
	{ "stylesheet", &stylesheet, 
		"Path to HTML style sheet", NULL, ARGTYPE_STRING, ARG_NOMINMAX },
	{ "encrypt", &html_encrypt,
		"Encrypt hints using ROT13", NULL, ARGTYPE_BOOL, ARG_NOMINMAX },
	{ "logs", &includelogs, 
		"Include groundspeak logs if present", NULL, ARGTYPE_BOOL, ARG_NOMINMAX },
        { "degformat", &degformat, 
        	"Degrees output as 'ddd', 'dmm'(default) or 'dms'", "dmm", ARGTYPE_STRING, ARG_NOMINMAX },
	{ "altunits", &altunits,
		"Units for altitude (f)eet or (m)etres", "m", ARGTYPE_STRING, ARG_NOMINMAX },
	ARG_TERMINATOR
};



static void
wr_init(const char *fname)
{
	file_out = gbfopen(fname, "w", MYNAME);
	mkshort_handle = mkshort_new_handle();
}

static void
wr_deinit(void)
{
	gbfclose(file_out);
	mkshort_del_handle(&mkshort_handle);
}

static void
html_disp(const waypoint *wpt)
{
	char tbuf[1024];
	char *cout;
	time_t tm = wpt->creation_time;
	gbint32 utmz;
	double utme, utmn;
	char utmzc;
	fs_xml *fs_gpx = NULL;
	

	GPS_Math_WGS84_To_UTM_EN(wpt->latitude, wpt->longitude, 
		&utme, &utmn, &utmz, &utmzc);

	if (tm == 0) 
		tm = time(NULL);
	strftime(tbuf, sizeof(tbuf), "%d-%b-%Y", localtime(&tm));


	gbfprintf(file_out, "\n<a name=\"%s\"><hr></a>\n", wpt->shortname);
	gbfprintf(file_out, "<table width=\"100%%\">\n");
	gbfprintf(file_out, "<tr><td><p class=\"gpsbabelwaypoint\">%s - ",(global_opts.synthesize_shortnames) ? mkshort_from_wpt(mkshort_handle, wpt) : wpt->shortname);
	cout = pretty_deg_format(wpt->latitude, wpt->longitude, degformat[2], " ", 1);
	gbfprintf(file_out, "%s (%d%c %6.0f %7.0f)", cout, utmz, utmzc, utme, utmn);
	xfree (cout);
	if (wpt->altitude != unknown_alt)
		gbfprintf (file_out, " alt:%d", (int) ( (altunits[0]=='f')?METERS_TO_FEET(wpt->altitude):wpt->altitude) );
	gbfprintf (file_out, "<br>\n");
	if (strcmp(wpt->description, wpt->shortname)) {
		if (wpt->url) {
			char *d = html_entitize(wpt->description);
			gbfprintf(file_out, "<a href=\"%s\">%s</a>", wpt->url, d);
			xfree(d);
		}
		else {
			gbfprintf(file_out, "%s", wpt->description);
		}
		if (wpt->gc_data.placer) { 
			gbfprintf(file_out, " by %s", wpt->gc_data.placer);
		}		
	}
	gbfprintf(file_out, "</p></td>\n");

	gbfprintf (file_out, "<td align=\"right\">");
	if (wpt->gc_data.terr) {
		gbfprintf (file_out, "<p class=\"gpsbabelcacheinfo\">%d%s / %d%s<br>\n", 
			(int)(wpt->gc_data.diff / 10), (wpt->gc_data.diff%10)?"&frac12;":"", 
			(int)(wpt->gc_data.terr / 10), (wpt->gc_data.terr%10)?"&frac12;":""  ); 
		gbfprintf(file_out, "%s / %s</p>", 
			gs_get_cachetype(wpt->gc_data.type),
			gs_get_container(wpt->gc_data.container));
	}
	gbfprintf(file_out, "</td></tr>\n");
	

	gbfprintf(file_out, "<tr><td colspan=\"2\">");
	if (wpt->gc_data.desc_short.utfstring) {
		char *tmpstr = strip_nastyhtml(wpt->gc_data.desc_short.utfstring);
		gbfprintf (file_out, "<p class=\"gpsbabeldescshort\">%s</p>\n", tmpstr );
		xfree( tmpstr );
       	}
	if (wpt->gc_data.desc_long.utfstring) {
		char *tmpstr = strip_nastyhtml(wpt->gc_data.desc_long.utfstring);
		gbfprintf (file_out, "<p class=\"gpsbabeldesclong\">%s</p>\n", tmpstr );
		xfree( tmpstr );
       	}
	if (wpt->gc_data.hint) {
		char *hint = NULL;
		if ( html_encrypt )
			hint = rot13( wpt->gc_data.hint );
		else 
			hint = xstrdup( wpt->gc_data.hint );
		gbfprintf (file_out, "<p class=\"gpsbabelhint\"><strong>Hint:</strong> %s</p>\n", hint);
		xfree( hint );
	}
	else if (wpt->notes && (!wpt->description || strcmp(wpt->notes,wpt->description))) {
		gbfprintf (file_out, "<p class=\"gpsbabelnotes\">%s</p>\n", wpt->notes);
	}
	
        fs_gpx = NULL;
        if ( includelogs ) {
		fs_gpx = (fs_xml *)fs_chain_find( wpt->fs, FS_GPX);
	}

        if ( fs_gpx && fs_gpx->tag ) {
	        xml_tag *root = fs_gpx->tag;
		xml_tag *curlog = NULL;
		xml_tag *logpart = NULL;
		curlog = xml_findfirst( root, "groundspeak:log" );
		while ( curlog ) {
			time_t logtime = 0;
			struct tm *logtm = NULL;
			gbfprintf( file_out, "<p class=\"gpsbabellog\">\n" );
			
			logpart = xml_findfirst( curlog, "groundspeak:type" );
			if ( logpart ) {
				gbfprintf( file_out, "<span class=\"gpsbabellogtype\">%s</span> by ", logpart->cdata );
			}
			
			logpart = xml_findfirst( curlog, "groundspeak:finder" );
			if ( logpart ) {
				char *f = html_entitize( logpart->cdata );
				gbfprintf( file_out, "<span class=\"gpsbabellogfinder\">%s</span> on ", f );
				xfree( f );
			}
			
			logpart = xml_findfirst( curlog, "groundspeak:date" );
			if ( logpart ) {
				logtime = xml_parse_time( logpart->cdata, NULL);
				logtm = localtime( &logtime );
				if ( logtm ) {
					gbfprintf( file_out, 
						"<span class=\"gpsbabellogdate\">%04d-%02d-%02d</span><br>\n",
						logtm->tm_year+1900,
						logtm->tm_mon+1,
						logtm->tm_mday );
				}
			}
			
			logpart = xml_findfirst( curlog, "groundspeak:log_wpt" );
			if ( logpart ) {
				char *coordstr = NULL;
				float lat = 0;
				float lon = 0;
				coordstr = xml_attribute( logpart, "lat" );
				if ( coordstr ) {
					lat = atof( coordstr );
				}
			        coordstr = xml_attribute( logpart, "lon" );
				if ( coordstr ) {
					lon = atof( coordstr );
				}
				coordstr = pretty_deg_format(lat, lon, degformat[2], " ", 1);
				gbfprintf( file_out,
					"<span class=\"gpsbabellogcoords\">%s</span><br>\n",
					coordstr );
				xfree(coordstr);
			}
			
			logpart = xml_findfirst( curlog, "groundspeak:text" );
			if ( logpart ) {
				char *encstr = NULL;
				char *s = NULL;
				char *t = NULL;
				int encoded = 0;
				encstr = xml_attribute( logpart, "encoded" );
				encoded = (encstr[0] != 'F');
				
				if ( html_encrypt && encoded ) {
					s = rot13( logpart->cdata );
				}
				else {
					s = xstrdup( logpart->cdata );
				}
					
				t = html_entitize( s );
				gbfprintf( file_out, "%s", t ); 
				xfree( t );
				xfree( s );
			}

			gbfprintf( file_out, "</p>\n" );
			curlog = xml_findnext( root, curlog, "groundspeak:log" );
		}
	}
	gbfprintf(file_out, "</td></tr></table>\n");
}

static void
html_index(const waypoint *wpt)
{
	char *sn = html_entitize(wpt->shortname);
	char *d = html_entitize(wpt->description);

	gbfprintf(file_out, "<a href=\"#%s\">%s - %s</a><br>\n", sn, sn, d);

	xfree(sn);
	xfree(d);
}

static void
data_write(void)
{
	setshort_length(mkshort_handle, 6);

	gbfprintf(file_out, "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\">\n");
	gbfprintf(file_out, "<html>\n");
	gbfprintf(file_out, "<head>\n");
	gbfprintf(file_out, " <meta http-equiv=\"Content-Type\" content=\"text/html;charset=utf-8\">\n");
	gbfprintf(file_out, " <meta name=\"Generator\" content=\"GPSBabel %s\">\n", gpsbabel_version);
	gbfprintf(file_out, " <title>GPSBabel HTML Output</title>\n");
	if (stylesheet) 
		gbfprintf(file_out, " <link rel=\"stylesheet\" type=\"text/css\" href=\"%s\">\n", stylesheet);
	else {
		gbfprintf(file_out, " <style>\n");
		gbfprintf(file_out, "  p.gpsbabelwaypoint { font-size: 120%%; font-weight: bold }\n");
		gbfprintf(file_out, " </style>\n");
	}	
	gbfprintf(file_out, "</head>\n");
	gbfprintf(file_out, "<body>\n");

	gbfprintf(file_out, "<p class=\"index\">\n");
	waypt_disp_all(html_index);
	gbfprintf(file_out, "</p>\n");
	
	waypt_disp_all(html_disp);

	gbfprintf(file_out, "</body>");
	gbfprintf(file_out, "</html>");

}


ff_vecs_t html_vecs = {
	ff_type_file,
	{ ff_cap_write, ff_cap_none, ff_cap_none },
	NULL,
	wr_init,
	NULL,
	wr_deinit,
	NULL,
	data_write,
	NULL, 
	html_args,
	CET_CHARSET_UTF8, 0	/* CET-REVIEW */
};
