/*
    Tucnak - VHF contest log
    Copyright (C) 2002-2020  Ladislav Vaiz <ok1zia@nagano.cz>

    This program is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public License
    version 2 as published by the Free Software Foundation.

*/

#include "header.h"

#include "bfu.h"
#include "chart.h"
#include "fifo.h"
#include "html.h"
#include "map.h"
#include "qsodb.h"
#include "tsdl.h"
#include "session.h"
#include "stats.h"
#include "tsdl.h"
#include "zpng.h"

#define HTML_QSO_STR(item) zg_string_eprintfa("h", gs, "<td>%s </td> ", item);
#define HTML_QSO_STR_R(item) zg_string_eprintfa("h", gs, "<td align=\"right\">%s </td> ", item);
#define HTML_QSO_INT(item) g_string_append_printf(gs, "<td align=\"right\">%d </td> ", item);
#define HTML_QSO_CALL_LINK(item) zg_string_eprintfa("h", gs, "<td><a target=\"_blank\" href=\"https://www.qrz.com/db/%s\">%s </a></td> ", item, item);
#define HTML_QSO_GRID_LINK(item) zg_string_eprintfa("h", gs, "<td><a target=\"_blank\" href=\"https://www.k7fry.com/grid/?qth=%s&from=%s&t=n\">%s </a></td> ", item, ctest->pwwlo, item);

#define HTML_HDR(item) g_string_append_printf(gs, "<th bgcolor=\"#e4b97c\"><font color=\"#800000\">%s</font></th>\n", item);

static int bandrefi = 0;
static int total_qsos = 0;
static int total_points = 0;
gchar *qh(GString *gs, gchar *s){
	char *c;

    g_string_truncate(gs,0);
    if (!s) return gs->str;
    
	for (c=s; *c!='\0'; c++) {
        switch (*c){
            case '<':
                g_string_append(gs, "&lt;");
                break;
            case '>':
                g_string_append(gs, "&gt;");
                break;
            case '"':
                g_string_append(gs, "&quot;");
                break;
            case '&':
                g_string_append(gs, "&amp;");
                break;
            case '\'':
                g_string_append(gs, "&#39;");
                break;
            default:
                g_string_append_c(gs, *c);    
        }
    }
	return gs->str;
} 
  
void html_style(GString *gs){
    g_string_append_printf(gs, 
"body {\n"
"    font-size: 12pt;\n"
/*"    font-family: Tahoma, Helvetica, Arial, sans-serif}\n"*/
"    font-family: Courier New, Courier-new, sans-serif}\n"

"a {\n"
"    font-weight: bold}\n"

"h1, h2, h3, h4 {\n"
"    font-family: Tahoma, Helvetica, Arial, sans-serif;\n"
"    color: #f8f8f8};\n"

"h2 {\n"
"    margin-top: 20;\n"
"    margin-bottom: 5;\n"
"    margin-left:10 }\n"
/*
input {                                                                        
    padding: 2px;
    margin: 2px;
    font-weight: normal; 
    font-size: 12px; 
    color: #000000; 
    font-family: sans-serif}                                                                               

li {
    margin-bottom: 20px
}

p.stress{
    font-style: italic}
      */
"table.qsos {\n"
"    border: black 2px solid;\n"
"    padding: 5px;\n"
"    background: #606060}\n"

"th {\n"
"    padding-left: 5px;\n"
"    padding-right: 5px}\n"

"td {\n"
"    padding-left: 5px;\n"
"    padding-right: 5px}\n"

"#calltest {\n"
"    font-family: Tahoma, Helvetica, Arial, sans-serif;\n"
"    font-size: 180%%;\n"
"    font-weight: bold}\n"

"#q {\n"
"   text-transform: uppercase;}\n"

);
}

void html_header(GString *gs, gchar *title, int flags, int refresh, char *bodyarg){
   

    g_string_append_printf(gs, 
"<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">\n"
"<html><head>\n"
"<meta http-equiv=\"content-type\" content=\"text/html; charset=iso-8859-2\">\n"
    );
    if (refresh)
       zg_string_eprintfa("h", gs, "<meta http-equiv=\"refresh\" content=\"%d\">\n", refresh);
    g_string_append_printf(gs, 
"<style type=\"text/css\">\n"
    );

    html_style(gs);

    g_string_append_printf(gs, "</style>");
    zg_string_eprintfa("h", gs, "<title>%s</title>\n", title);
    g_string_append_printf(gs, "</head>\n<body text=\"#ffffff\" bgcolor=\"#3f4e66\" link=\"#ddad6a\" vlink=\"#cd9d5a\" alink=\"#edbd7a\"");
	if (bodyarg) g_string_append_printf(gs, " %s", bodyarg);
    g_string_append_printf(gs, ">\n");
	if (flags & HTML_CENTER) g_string_append_printf(gs, "<center>\n");
    g_string_append_printf(gs, "<h1>");
    if (flags & HTML_ICON) g_string_append_printf(gs, "<img src=\"/tucnak64.png\" alt=\"Happy penguin\">");
    zg_string_eprintfa("h", gs, "%s</h1>\n", title);
    

}

void html_ref_header(GString *gs){
    zg_string_eprintfa("h", gs, "<p>%s: %S</p>\n", VTEXT(T_LOCATOR), ctest->pwwlo);
    g_string_append_printf(gs, "<table class=\"qsos\">\n");
    g_string_append_printf(gs, "<tr>");
    g_string_append_printf(gs, "<th>%s</th><th>%s</th><th>%s</th><th>%s</th></tr>\n", VTEXT(T_BAND2), VTEXT(T_SW_QSOS), VTEXT(T_POINTS), VTEXT(T_AVG));
}

void html_band_ref(GString *gs, struct band *b, struct config_band *confb){
    if (bandrefi++%2)
        g_string_append_printf(gs, "<tr bgcolor=\"#505050\">\n");
    else
        g_string_append_printf(gs, "<tr bgcolor=\"#606060\">\n");
    zg_string_eprintfa("h", gs, "<td><a href=\"#%c\">%s</a></td>\n", b->bandchar, b->bandname);
    g_string_append_printf(gs, "<td align=\"right\">%d</td>\n", b->stats->nqsos);
    total_qsos += b->stats->nqsos;
    g_string_append_printf(gs, "<td align=\"right\">%d</td>\n", b->stats->ntotal);
    total_points += b->stats->ntotal;
    if (b->stats->nqsos){ // happened always
        g_string_append_printf(gs, "<td align=\"right\">%5.1f</td>\n", (double)b->stats->ntotal/(double)b->stats->nqsos);
    }
    g_string_append_printf(gs, "</tr>\n");
}
    
void html_total_sum(GString *gs, struct band *b, struct config_band *confb){
    if (bandrefi++%2)
        g_string_append_printf(gs, "<tr bgcolor=\"#505050\">\n");
    else
        g_string_append_printf(gs, "<tr bgcolor=\"#606060\">\n");
    g_string_append_printf(gs, "<td></td><td align=\"right\"><b>%d</b></td><td align=\"right\"><b>%d</b></td><td></td></tr>\n", total_qsos, total_points);
    g_string_append_printf(gs, "</tr>\n");
}

void html_ref_footer(GString *gs, struct band *b, struct config_band *confb){
    g_string_append_printf(gs, "</table>\n");
}

void html_band_header(GString *gs, struct band *b, struct config_band *confb, int flags, struct subwin *map, struct subwin *chart){
    int w, h, i;


    zg_string_eprintfa("h", gs, "<a name=\"%c\"></a><h2>%s %s</h2>\n", b->bandchar, VTEXT(T_BAND2), b->bandname);
/*    g_string_append_printf(gs, "<p>QSOs: %d<br>\n", b->stats->nqsos);
    g_string_append_printf(gs, "Points: %d<br>\n", b->stats->ntotal);
    g_string_append_printf(gs, "WWLs: %d<br>\n", g_hash_table_size(b->stats->wwls));
    g_string_append_printf(gs, "DXCCs: %d<br>\n", g_hash_table_size(b->stats->dxcs));
    if (b->stats->nqsos){
        g_string_append_printf(gs, "AVG: %5.2f pts/qso<br>\n", (double)b->stats->ntotal/(double)b->stats->nqsos);
    }
    g_string_append_printf(gs, "</p>\n");*/

	// statsfifo
	g_string_append_printf(gs, "<pre>");
	for (i = 5; i < b->statsfifo1->items->len ; i++){
		char *s = (char*)g_ptr_array_index(b->statsfifo1->items, i);
		g_string_append_printf(gs, "%s\n", s);
	}
    g_string_append_printf(gs, "</pre>\n");



#ifdef Z_HAVE_SDL
    w = 640;
    h = 480;
    if (map && map->screen) {
        w = map->screen->w;
        h = map->screen->h;
    }
    g_string_append_printf(gs, "<p><img src=\"%smap%c.png\" width=\"%d\" height=\"%d\" alt=\"Polar map for %s\"></p>\n",
            flags & HTML_IMG_ROOT ? "/" : "", z_char_lc(b->bandchar), w, h, b->bandname);
    w = 640;
    h = 480;
    if (chart && chart->screen) {
        w = chart->screen->w;
        h = chart->screen->h;
    }
    g_string_append_printf(gs, "<p><img src=\"%schart%c.png\" width=\"%d\" height=\"%d\" alt=\"Chart for %s\"></p>\n",
            flags & HTML_IMG_ROOT ? "/" : "", z_char_lc(b->bandchar), w, h, b->bandname);
#endif
	g_string_append_printf(gs, "<br><br>\n\n<table class=\"qsos\">\n");
	g_string_append_printf(gs, "<tr>\n");
    HTML_HDR("DATE");
	/*HTML_HDR("BAND");*/
	HTML_HDR("MODE");
	HTML_HDR("TIME");
	HTML_HDR("CALLSIGN");
	HTML_HDR("RSTS");
	HTML_HDR("STX");
	HTML_HDR("STX STRING");
	HTML_HDR("RSTR");
	HTML_HDR("SRX");
	HTML_HDR("SRX STRING");
	HTML_HDR("LOCATOR");
	HTML_HDR("QRB");
	HTML_HDR("OPERATOR");
	HTML_HDR("REMARK");
	g_string_append_printf(gs, "</tr>\n");
}

void html_band_footer(GString *gs){
    g_string_append_printf(gs,"</table>\n\n");
}
    
void html_footer(GString *gs, int flags){
    g_string_append_printf(gs, "<p>Created by <a href=\"http://tucnak.nagano.cz\">Tucnak</a> ver. %s</p>\n", VERSION_STRING);

    g_string_append_printf(gs, 
"<p>\n"
"<a href=\"http://validator.w3.org/check/referer\">\n"
"<img border=\"0\" src=\"http://tucnak.nagano.cz/valid-html401.png\"\n"
"     alt=\"Valid HTML 4.01!\" height=\"31\" width=\"88\"></a>&nbsp;\n"
"\n"

"<a href=\"http://www.anybrowser.org/campaign/\">"
"<img src=\"http://tucnak.nagano.cz/bestviewed.gif\" alt=\"Viewable with any browser\"" 
"     width=\"80\" height=\"31\" border=\"0\"></a>&nbsp;"
"</p><br><br>\n");
	if (flags & HTML_CENTER) g_string_append(gs, "</center>\n");
	g_string_append_printf(gs, 
"</body></html>\n");
}

void html_qsos(GString *gs, struct band *b, struct config_band *confb){
    struct qso *q;
    GString *gs2;
    int i,j;
	char *html_modes[]={
		"?",
		"SSB",
		"CW",
		"CWs",
		"CWr",
		"AM",
		"FM",
		"RTTY",
		"SSTV",
		"ATV"
	};
		

    gs2 = g_string_new("");
    
    
    j=0;
    for (i=0; i<b->qsos->len; i++){
        char time[10];
        //gchar *c;
        
        q = get_qso(b, i); 
        if (q->error) continue;
		
		if (j++%2)
            g_string_append_printf(gs, "<tr bgcolor=\"#505050\">\n");
        else
     		g_string_append_printf(gs, "<tr bgcolor=\"#606060\">\n");

        strcpy(time, q->time_str);
        time[2]='.'; time[3]=q->time_str[2]; time[4]=q->time_str[3]; time[5]='\0';
        
		HTML_QSO_STR(q->date_str);
		HTML_QSO_STR(html_modes[abs(q->mode)%10]);
		HTML_QSO_STR(time);
		if (cfg->httpd_show_links) {
		   HTML_QSO_CALL_LINK(q->callsign);
		} else {
		   HTML_QSO_STR(q->callsign);
		}

		HTML_QSO_STR_R(q->rsts);
		HTML_QSO_STR_R(q->qsonrs);
		HTML_QSO_STR(ctest->pexch);
        
		HTML_QSO_STR_R(q->rstr);
		HTML_QSO_STR_R(q->qsonrr);
		HTML_QSO_STR(q->exc);
        
		if (cfg->httpd_show_links) {
		   HTML_QSO_GRID_LINK(q->locator);
		} else {
		   HTML_QSO_STR(q->locator);
		}
		HTML_QSO_INT((int)q->qrb);
		HTML_QSO_STR(q->operator_);
		HTML_QSO_STR(q->remark);
        
		g_string_append_printf(gs, "</tr>\n");
    }
    
    g_string_free(gs2, TRUE);
}

void html_complete(GString *gs, int flags){
    struct band *band = NULL;
    struct config_band *confb = NULL;
    int i;
    GString *gs2, *title;
    int header_saved=0;
    struct subwin *map = NULL;
    struct subwin *chart = NULL;
	int oldaa;

#ifdef Z_HAVE_SDL
	oldaa = zsdl->antialiasing;
	if (zsdl->antialiasing_supported) zsdl->antialiasing = 1;
#endif

    gs2 = g_string_sized_new(100);
    title = g_string_sized_new(100);
    
	map = sw_raise_or_new(SWT_MAP);
	chart = sw_raise_or_new(SWT_CHART);

	bandrefi = 0;
	total_qsos = total_points = 0;
    for (i=0; i<ctest->bands->len; i++){
        band = (struct band*)g_ptr_array_index(ctest->bands, i);
        confb = (struct config_band*)get_config_band_by_bandchar(band->bandchar);

        stats_thread_join(band);
        if (band->stats->nqsos <=0) continue;
#if defined(Z_HAVE_SDL) && defined(Z_HAVE_LIBPNG)
		if (sdl && map && (flags & HTML_MAP)){
			char *filename;
            map->gdirty = 1;
            map_for_photo(map, band, 0);
			map_recalc_gst(map, band);
			sw_map_redraw(map, band, HTML_FOR_PHOTO);
			filename = g_strdup_printf("%s/map%c.png", ctest->directory, tolower(band->bandchar));
			zpng_save(map->screen, filename, NULL);

			/*SDL_BlitSurface(map->screen, NULL, sdl->screen, NULL);
			SDL_UpdateRect(sdl->screen, -1, -1, -1, -1);
			sleep(1);*/

			g_free(filename);
		}
		if (sdl && chart && (flags & HTML_CHART)){
			char *filename;
            chart->gdirty = 1;
            sw_chart_recalc_extremes(chart, band);
			sw_chart_redraw(chart, band, HTML_FOR_PHOTO);
			filename = g_strdup_printf("%s/chart%c.png", ctest->directory, tolower(band->bandchar));
			zpng_save(chart->screen, filename, NULL);
			g_free(filename);

			/*SDL_BlitSurface(chart->screen, NULL, sdl->screen, NULL);
			SDL_UpdateRect(sdl->screen, -1, -1, -1, -1);
			sleep(1);-*/

		}
#endif

        if (!header_saved){
            g_string_printf(title, "%s", ctest->pcall);
            z_str_uc(title->str);
            g_string_append_printf(title, " - %s", ctest->tname);
            html_header(gs, title->str, 0, cfg->httpd_refresh, NULL);
            html_ref_header(gs);
            header_saved=1;
        }

        html_band_ref(gs, band, confb);
    }

	if (band != NULL && confb != NULL){
		html_total_sum(gs, band, confb);
		html_ref_footer(gs, band, confb);
	}

    for (i=0; i<ctest->bands->len; i++){
        band = (struct band*)g_ptr_array_index(ctest->bands, i);
        confb = (struct config_band*)get_config_band_by_bandchar(band->bandchar);

        if (band->stats->nqsos <=0) continue;

        html_band_header(gs, band, confb, flags, map, chart);
        html_qsos  (gs, band, confb);
        html_band_footer(gs);
    }
    html_footer(gs, 0);

#ifdef Z_HAVE_SDL
	if (map) map_recalc_gst(map, aband);
	zsdl->antialiasing = oldaa;
#endif
	if (chart) sw_chart_recalc_extremes(chart, aband);
    
    g_string_free(gs2, 1);
    g_string_free(title, 1);
}

int export_all_bands_html(void){
    gchar *filename;
    FILE *f;
    char callbuf[20];
    GString *gs;
    
    if (!ctest) return -1;
    
    dbg("export_all_bands_html()\n");
	progress(VTEXT(T_EXPORTING));

	
    gs = g_string_sized_new(300000);
	html_complete(gs, HTML_MAP | HTML_CHART);
    filename = g_strdup_printf("%s/%s_%s.html",
					ctest->directory,
					ctest->cdate,
					z_get_raw_call(callbuf,ctest->pcall));

	z_wokna(filename);
	f=fopen(filename,"wt");
	if (!f) {
		errbox(VTEXT(T_CANT_WRITE), errno);
		g_free(filename);
        g_string_free(gs, 1);
		progress(NULL);
		return -1;
	}

    if (fprintf(f, "%s", gs->str) <= 0){
		errbox(VTEXT(T_CANT_WRITE), 0); 
        g_free(filename);
        g_string_free(gs, 1);
		return -1;
	}
	fclose(f);

	log_addf(VTEXT(T_SAVED_S), filename);
	g_free(filename);
    g_string_free(gs, 1);
	progress(NULL);
    return 0;
}

