/*
 * gfio - gui front end for fio - the flexible io tester
 *
 * Copyright (C) 2012 Stephen M. Cameron <stephenmcameron@gmail.com> 
 *
 * The license below covers all files distributed with fio unless otherwise
 * noted in the file itself.
 *
 *  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.
 *
 *  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-1307  USA
 *
 */
#include <string.h>
#include <malloc.h>
#include <math.h>
#include <assert.h>
#include <stdlib.h>

#include <cairo.h>
#include <gtk/gtk.h>

#include "tickmarks.h"
#include "graph.h"

struct xyvalue {
	double x, y;
	int gx, gy;
};

struct graph_value {
	struct graph_value *next;
	char *tooltip;
	void *value;
};

struct graph_label {
	char *label;
	struct graph_value *tail;
	struct graph_value *values;
	struct graph_label *next;
	double r, g, b;
	int value_count;
	unsigned int tooltip_count;
	struct graph *parent;
};

struct graph {
	char *title;
	char *xtitle;
	char *ytitle;
	unsigned int xdim, ydim;
	double xoffset, yoffset;
	struct graph_label *labels;
	struct graph_label *tail;
	int per_label_limit;
	const char *font;
	graph_axis_unit_change_callback x_axis_unit_change_callback;
	graph_axis_unit_change_callback y_axis_unit_change_callback;
	unsigned int base_offset;
	double left_extra;	
	double right_extra;	
	double top_extra;	
	double bottom_extra;	
};

void graph_set_size(struct graph *g, unsigned int xdim, unsigned int ydim)
{
	g->xdim = xdim;
	g->ydim = ydim;
}

void graph_set_position(struct graph *g, double xoffset, double yoffset)
{
	g->xoffset = xoffset;
	g->yoffset = yoffset;
}

struct graph *graph_new(unsigned int xdim, unsigned int ydim, const char *font)
{
	struct graph *g;

	g = calloc(1, sizeof(*g));
	graph_set_size(g, xdim, ydim);
	g->per_label_limit = -1;
	g->font = font;
	if (!g->font)
		g->font = "Sans";
	return g;
}

void graph_x_axis_unit_change_notify(struct graph *g, graph_axis_unit_change_callback f)
{
	g->x_axis_unit_change_callback = f;
}

void graph_y_axis_unit_change_notify(struct graph *g, graph_axis_unit_change_callback f)
{
	g->y_axis_unit_change_callback = f;
}

static int count_labels(struct graph_label *labels)
{
	int count = 0;
	struct graph_label *i;

	for (i = labels; i; i = i->next)
		count++;
	return count;
}

static int count_values(struct graph_value *values)
{
	int count = 0;
	struct graph_value *i;

	for (i = values; i; i = i->next)
		count++;
	return count;
}

typedef double (*double_comparator)(double a, double b);

static double mindouble(double a, double b)
{
	return a < b ? a : b;
}

static double maxdouble(double a, double b)
{
	return a < b ? b : a;
}

static double find_double_values(struct graph_value *values, double_comparator cmp)
{
	struct graph_value *i;
	int first = 1;
	double answer, tmp;

	assert(values != NULL);
	answer = 0.0; /* shut the compiler up, might need to think harder though. */
	for (i = values; i; i = i->next) {
		tmp = *(double *) i->value; 
		if (first) {
			answer = tmp;
			first = 0;
		} else {
			answer = cmp(answer, tmp);
		}
	}
	return answer;
}

static double find_double_data(struct graph_label *labels, double_comparator cmp)
{
	struct graph_label *i;
	int first = 1;
	double answer, tmp;

	assert(labels != NULL);
	answer = 0.0; /* shut the compiler up, might need to think harder though. */
	for (i = labels; i; i = i->next) {
		tmp = find_double_values(i->values, cmp);
		if (first) {
			answer = tmp;
			first = 0;
		} else {
			answer = cmp(tmp, answer);
		}
	}
	return answer;
}

static double find_min_data(struct graph_label *labels)
{
	return find_double_data(labels, mindouble);
}

static double find_max_data(struct graph_label *labels)
{
	return find_double_data(labels, maxdouble);
}

static void draw_bars(struct graph *bg, cairo_t *cr, struct graph_label *lb,
			double label_offset, double bar_width,
			double mindata, double maxdata)
{
	struct graph_value *i;
	double x1, y1, x2, y2;
	int bar_num = 0;
	double domain, range, v;

	domain = (maxdata - mindata);
	range = (double) bg->ydim * 0.80; /* FIXME */
	cairo_stroke(cr);
	for (i = lb->values; i; i = i->next) {

		x1 = label_offset + (double) bar_num * bar_width + (bar_width * 0.05);
		x2 = x1 + bar_width * 0.90;
		y2 = bg->ydim * 0.90;
		v = *(double *) i->value;
		y1 = y2 - (((v - mindata) / domain) * range);
		cairo_move_to(cr, x1, y1);
		cairo_line_to(cr, x1, y2);
		cairo_line_to(cr, x2, y2);
		cairo_line_to(cr, x2, y1);
		cairo_close_path(cr);
		cairo_fill(cr);
		cairo_stroke(cr);
		bar_num++;	
	}
}

static void draw_aligned_text(struct graph *g, cairo_t *cr, double x, double y,
			       double fontsize, const char *text, int alignment)
{
#define CENTERED 0
#define LEFT_JUSTIFIED 1
#define RIGHT_JUSTIFIED 2

	double factor, direction;
	cairo_text_extents_t extents;

	switch(alignment) {
		case CENTERED:
			direction = -1.0;
			factor = 0.5;
			break;
		case RIGHT_JUSTIFIED:
			direction = -1.0;
			factor = 1.0;
			break;
		case LEFT_JUSTIFIED:
		default:
			direction = 1.0;
			factor = 1.0;
			break;
	}
	cairo_select_font_face (cr, g->font, CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL);

	cairo_set_font_size(cr, fontsize);
	cairo_text_extents(cr, text, &extents);
	x = x + direction * (factor * extents.width  + extents.x_bearing);
	y = y - (extents.height / 2 + extents.y_bearing);

	cairo_move_to(cr, x, y);
	cairo_show_text(cr, text);
}

static inline void draw_centered_text(struct graph *g, cairo_t *cr, double x, double y,
			       double fontsize, const char *text)
{
	draw_aligned_text(g, cr, x, y, fontsize, text, CENTERED);
}

static inline void draw_right_justified_text(struct graph *g, cairo_t *cr,
				double x, double y,
				double fontsize, const char *text)
{
	draw_aligned_text(g, cr, x, y, fontsize, text, RIGHT_JUSTIFIED);
}

static inline void draw_left_justified_text(struct graph *g, cairo_t *cr,
				double x, double y,
				double fontsize, const char *text)
{
	draw_aligned_text(g, cr, x, y, fontsize, text, LEFT_JUSTIFIED);
}

static void draw_vertical_centered_text(struct graph *g, cairo_t *cr, double x,
					double y, double fontsize,
					const char *text)
{
	double sx, sy;
	cairo_text_extents_t extents;

	cairo_select_font_face(cr, g->font, CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL);

	cairo_set_font_size(cr, fontsize);
	cairo_text_extents(cr, text, &extents);
	sx = x;
	sy = y;
	y = y + (extents.width / 2.0 + extents.x_bearing);
	x = x - (extents.height / 2.0 + extents.y_bearing);

	cairo_move_to(cr, x, y);
	cairo_save(cr);
	cairo_translate(cr, -sx, -sy);
	cairo_rotate(cr, -90.0 * M_PI / 180.0);
	cairo_translate(cr, sx, sy);
	cairo_show_text(cr, text);
	cairo_restore(cr);
}

static void graph_draw_common(struct graph *g, cairo_t *cr,
	double *x1, double *y1, double *x2, double *y2)
{
        cairo_set_source_rgb(cr, 0, 0, 0);
        cairo_set_line_width (cr, 0.8);

	*x1 = 0.10 * g->xdim;	
	*x2 = 0.95 * g->xdim;
	*y1 = 0.10 * g->ydim;	
	*y2 = 0.90 * g->ydim;

	cairo_move_to(cr, *x1, *y1);
	cairo_line_to(cr, *x1, *y2);
	cairo_line_to(cr, *x2, *y2);
	cairo_line_to(cr, *x2, *y1);
	cairo_line_to(cr, *x1, *y1);
	cairo_stroke(cr);

	draw_centered_text(g, cr, g->xdim / 2, g->ydim / 20, 20.0, g->title);
	draw_centered_text(g, cr, g->xdim / 2, g->ydim * 0.97, 14.0, g->xtitle);
	draw_vertical_centered_text(g, cr, g->xdim * 0.02, g->ydim / 2, 14.0, g->ytitle);
	cairo_stroke(cr);
}

static void graph_draw_x_ticks(struct graph *g, cairo_t *cr,
	double x1, double y1, double x2, double y2,
	double minx, double maxx, int nticks, int add_tm_text)
{
	struct tickmark *tm;
	double tx;
	int i, power_of_ten;
	static double dash[] = { 1.0, 2.0 };

	nticks = calc_tickmarks(minx, maxx, nticks, &tm, &power_of_ten,
		g->x_axis_unit_change_callback == NULL, g->base_offset);
	if (g->x_axis_unit_change_callback)
		g->x_axis_unit_change_callback(g, power_of_ten);

	for (i = 0; i < nticks; i++) {
		tx = (((tm[i].value) - minx) / (maxx - minx)) * (x2 - x1) + x1;

		/* really tx < yx || tx > x2, but protect against rounding */
		if (x1 - tx > 0.01 || tx - x2 > 0.01)
			continue;

		/* Draw tick mark */
		cairo_set_line_width(cr, 0.8);
		cairo_move_to(cr, tx, y2);
		cairo_line_to(cr, tx, y2 + (y2 - y1) * 0.03);
		cairo_stroke(cr);

		/* draw grid lines */
		cairo_save(cr);
		cairo_set_dash(cr, dash, 2, 2.0);
		cairo_set_line_width(cr, 0.5);
		cairo_move_to(cr, tx, y1);
		cairo_line_to(cr, tx, y2);
		cairo_stroke(cr);
		cairo_restore(cr);

		if (!add_tm_text)
			continue;

		/* draw tickmark label */
		draw_centered_text(g, cr, tx, y2 * 1.04, 12.0, tm[i].string);
		cairo_stroke(cr);
		
	}
}

static double graph_draw_y_ticks(struct graph *g, cairo_t *cr,
	double x1, double y1, double x2, double y2,
	double miny, double maxy, int nticks, int add_tm_text)
{
	struct tickmark *tm;
	double ty;
	int i, power_of_ten;
	static double dash[] = { 2.0, 2.0 };

	nticks = calc_tickmarks(miny, maxy, nticks, &tm, &power_of_ten,
		g->y_axis_unit_change_callback == NULL, g->base_offset);
	if (g->y_axis_unit_change_callback)
		g->y_axis_unit_change_callback(g, power_of_ten);

	/*
	 * Use highest tickmark as top of graph, not highest value. Otherwise
	 * it's impossible to see what the max value is, if the graph is
	 * fairly flat.
	 */
	maxy = tm[nticks - 1].value;

	for (i = 0; i < nticks; i++) {
		ty = y2 - (((tm[i].value) - miny) / (maxy - miny)) * (y2 - y1);

		/* really ty < y1 || ty > y2, but protect against rounding */
		if (y1 - ty > 0.01 || ty - y2 > 0.01)
			continue;

		/* draw tick mark */
		cairo_move_to(cr, x1, ty);
		cairo_line_to(cr, x1 - (x2 - x1) * 0.02, ty);
		cairo_stroke(cr);

		/* draw grid lines */
		cairo_save(cr);
		cairo_set_dash(cr, dash, 2, 2.0);
		cairo_set_line_width(cr, 0.5);
		cairo_move_to(cr, x1, ty);
		cairo_line_to(cr, x2, ty);
		cairo_stroke(cr);
		cairo_restore(cr);

		if (!add_tm_text)
			continue;

		/* draw tickmark label */
		draw_right_justified_text(g, cr, x1 - (x2 - x1) * 0.025, ty, 12.0, tm[i].string);
		cairo_stroke(cr);
	}

	/*
	 * Return new max to use
	 */
	return maxy;
}

void bar_graph_draw(struct graph *bg, cairo_t *cr)
{
	double x1, y1, x2, y2;
	double space_per_label, bar_width;
	double label_offset, mindata, maxdata;
	int i, nlabels;
	struct graph_label *lb;

	cairo_save(cr);
	cairo_translate(cr, bg->xoffset, bg->yoffset);
	graph_draw_common(bg, cr, &x1, &y1, &x2, &y2);

	nlabels = count_labels(bg->labels);
	space_per_label = (x2 - x1) / (double) nlabels;

	mindata = find_min_data(bg->labels);
	maxdata = find_max_data(bg->labels);

	if (fabs(maxdata - mindata) < 1e-20) {
		draw_centered_text(bg, cr,
			x1 + (x2 - x1) / 2.0,
			y1 + (y2 - y1) / 2.0, 20.0, "No good data");
		return;
	}

	graph_draw_y_ticks(bg, cr, x1, y1, x2, y2, mindata, maxdata, 10, 1);

	i = 0;
	for (lb = bg->labels; lb; lb = lb->next) {
		int nvalues;
		nvalues = count_values(lb->values);
		bar_width = (space_per_label - space_per_label * 0.2) / (double) nvalues;
		label_offset = bg->xdim * 0.1 + space_per_label * (double) i + space_per_label * 0.1;
		draw_bars(bg, cr, lb, label_offset, bar_width, mindata, maxdata);
		// draw_centered_text(cr, label_offset + (bar_width / 2.0 + bar_width * 0.1), bg->ydim * 0.93,
		draw_centered_text(bg, cr, x1 + space_per_label * (i + 0.5), bg->ydim * 0.93,
			12.0, lb->label); 
		i++;
	}
	cairo_stroke(cr);
	cairo_restore(cr);
}

typedef double (*xy_value_extractor)(struct graph_value *v);

static double getx(struct graph_value *v)
{
	struct xyvalue *xy = v->value;
	return xy->x;
}

static double gety(struct graph_value *v)
{
	struct xyvalue *xy = v->value;
	return xy->y;
}

static double find_xy_value(struct graph *g, xy_value_extractor getvalue, double_comparator cmp)
{
	double tmp, answer = 0.0;
	struct graph_label *i;
	struct graph_value *j;
	int first = 1;

	for (i = g->labels; i; i = i->next)
		for (j = i->values; j; j = j->next) {
			tmp = getvalue(j);
			if (first) {
				first = 0;
				answer = tmp;
			}
			answer = cmp(tmp, answer);	
		}
	return answer;
} 

void line_graph_draw(struct graph *g, cairo_t *cr)
{
	double x1, y1, x2, y2;
	double minx, miny, maxx, maxy, gminx, gminy, gmaxx, gmaxy;
	double tx, ty, top_extra, bottom_extra, left_extra, right_extra;
	struct graph_label *i;
	struct graph_value *j;
	int good_data = 1, first = 1;

	cairo_save(cr);
	cairo_translate(cr, g->xoffset, g->yoffset);
	graph_draw_common(g, cr, &x1, &y1, &x2, &y2);

	minx = find_xy_value(g, getx, mindouble);
	maxx = find_xy_value(g, getx, maxdouble);
	miny = find_xy_value(g, gety, mindouble);
	maxy = find_xy_value(g, gety, maxdouble);

	if (fabs(maxx - minx) < 1e-20 || fabs(maxy - miny) < 1e-20) {
		good_data = 0;
		minx = 0.0;
		miny = 0.0;
		maxx = 10.0;
		maxy = 100.0;
	}

	top_extra = 0.0;
	bottom_extra = 0.0;
	left_extra = 0.0;
	right_extra = 0.0;

	if (g->top_extra > 0.001)
		top_extra = fabs(maxy - miny) * g->top_extra;
	if (g->bottom_extra > 0.001)
		bottom_extra = fabs(maxy - miny) * g->bottom_extra;
	if (g->left_extra > 0.001)
		left_extra = fabs(maxx - minx) * g->left_extra;
	if (g->right_extra > 0.001)
		right_extra = fabs(maxx - minx) * g->right_extra;

	gminx = minx - left_extra;
	gmaxx = maxx + right_extra;
	gminy = miny - bottom_extra;
	gmaxy = maxy + top_extra;

	graph_draw_x_ticks(g, cr, x1, y1, x2, y2, gminx, gmaxx, 10, good_data);
	gmaxy = graph_draw_y_ticks(g, cr, x1, y1, x2, y2, gminy, gmaxy, 10, good_data);

	if (!good_data)
		goto skip_data;

	cairo_set_line_width(cr, 1.5);
	for (i = g->labels; i; i = i->next) {
		first = 1;
		if (i->r < 0) /* invisible data */
			continue;
		cairo_set_source_rgb(cr, i->r, i->g, i->b);
		for (j = i->values; j; j = j->next) {
			struct xyvalue *xy = j->value;

			tx = ((getx(j) - gminx) / (gmaxx - gminx)) * (x2 - x1) + x1;
			ty = y2 - ((gety(j) - gminy) / (gmaxy - gminy)) * (y2 - y1);
			if (first) {
				cairo_move_to(cr, tx, ty);
				first = 0;
			} else {
				cairo_line_to(cr, tx, ty);
			}
			xy->gx = tx;
			xy->gy = ty;
		}
		cairo_stroke(cr);
	}

skip_data:
	cairo_restore(cr);

}

static void gfree(void *f)
{
	if (f)
		free(f);
}

static void setstring(char **str, const char *value)
{
	gfree(*str);
	*str = strdup(value);
}

void graph_title(struct graph *bg, const char *title)
{
	setstring(&bg->title, title);
}

void graph_x_title(struct graph *bg, const char *title)
{
	setstring(&bg->xtitle, title);
}

void graph_y_title(struct graph *bg, const char *title)
{
	setstring(&bg->ytitle, title);
}

static struct graph_label *graph_find_label(struct graph *bg,
				const char *label)
{
	struct graph_label *i;
	
	for (i = bg->labels; i; i = i->next)
		if (strcmp(label, i->label) == 0)
			return i;
	return NULL;
}

void graph_add_label(struct graph *bg, const char *label)
{
	struct graph_label *i;
	
	i = graph_find_label(bg, label);
	if (i)
		return; /* already present. */
	i = calloc(1, sizeof(*i));
	i->parent = bg;
	setstring(&i->label, label);
	i->next = NULL;
	if (!bg->tail)
		bg->labels = i;
	else
		bg->tail->next = i;
	bg->tail = i;
}

static void graph_label_add_value(struct graph_label *i, void *value,
				  const char *tooltip)
{
	struct graph_value *x;

	x = malloc(sizeof(*x));
	x->value = value;
	if (tooltip)
		x->tooltip = strdup(tooltip);
	else
		x->tooltip = NULL;
	x->next = NULL;
	if (!i->tail) {
		i->values = x;
	} else {
		i->tail->next = x;
	}
	i->tail = x;
	i->value_count++;
	if (x->tooltip)
		i->tooltip_count++;

	if (i->parent->per_label_limit != -1 &&
		i->value_count > i->parent->per_label_limit) {
		int to_drop = 1;

		/*
		 * If the limit was dynamically reduced, making us more
		 * than 1 entry ahead after adding this one, drop two
		 * entries. This will make us (eventually) reach the
		 * specified limit.
		 */
		if (i->value_count - i->parent->per_label_limit >= 2)
			to_drop = 2;

		while (to_drop--) {
			x = i->values;
			i->values = i->values->next;
			if (x->tooltip) {
				free(x->tooltip);
				i->tooltip_count--;
			}
			free(x->value);
			free(x);
			i->value_count--;
		}
	}
}

int graph_add_data(struct graph *bg, const char *label, const double value)
{
	struct graph_label *i;
	double *d;

	d = malloc(sizeof(*d));
	*d = value;

	i = graph_find_label(bg, label);
	if (!i)
		return -1;
	graph_label_add_value(i, d, NULL);
	return 0;
}

int graph_add_xy_data(struct graph *bg, const char *label,
		      const double x, const double y, const char *tooltip)
{
	struct graph_label *i;
	struct xyvalue *xy;

	xy = malloc(sizeof(*xy));
	xy->x = x;
	xy->y = y;

	i = graph_find_label(bg, label);
	if (!i)
		return -1;

	graph_label_add_value(i, xy, tooltip);
	return 0;
}

static void graph_free_values(struct graph_value *values)
{
	struct graph_value *i, *next;

	for (i = values; i; i = next) {
		next = i->next;
		gfree(i->value);
		gfree(i);
	}	
}

static void graph_free_labels(struct graph_label *labels)
{
	struct graph_label *i, *next;

	for (i = labels; i; i = next) {
		next = i->next;
		graph_free_values(i->values);
		gfree(i);
	}	
}

void graph_set_color(struct graph *gr, const char *label,
	double red, double green, double blue)
{
	struct graph_label *i;
	double r, g, b;

	if (red < 0.0) { /* invisible color */
		r = -1.0;
		g = -1.0;
		b = -1.0;
	} else {
		r = fabs(red);
		g = fabs(green);
		b = fabs(blue);

		if (r > 1.0)
			r = 1.0;
		if (g > 1.0)
			g = 1.0;
		if (b > 1.0)
			b =1.0;
	}

	for (i = gr->labels; i; i = i->next)
		if (strcmp(i->label, label) == 0) {
			i->r = r;	
			i->g = g;	
			i->b = b;	
			break;
		}
}

void graph_free(struct graph *bg)
{
	gfree(bg->title);
	gfree(bg->xtitle);
	gfree(bg->ytitle);
	graph_free_labels(bg->labels);
}

/* For each line in the line graph, up to per_label_limit segments may
 * be added.  After that, adding more data to the end of the line
 * causes data to drop off of the front of the line.
 */
void line_graph_set_data_count_limit(struct graph *g, int per_label_limit)
{
	g->per_label_limit = per_label_limit;
}

void graph_add_extra_space(struct graph *g, double left_percent, double right_percent,
                                double top_percent, double bottom_percent)
{
	g->left_extra = left_percent;	
	g->right_extra = right_percent;	
	g->top_extra = top_percent;	
	g->bottom_extra = bottom_percent;	
}

/*
 * Normally values are logged in a base unit of 0, but for other purposes
 * it makes more sense to log in higher unit. For instance for bandwidth
 * purposes, you may want to log in KB/sec (or MB/sec) rather than bytes/sec.
 */
void graph_set_base_offset(struct graph *g, unsigned int base_offset)
{
	g->base_offset = base_offset;
}

int graph_has_tooltips(struct graph *g)
{
	struct graph_label *i;

	for (i = g->labels; i; i = i->next)
		if (i->tooltip_count)
			return 1;

	return 0;
}

int graph_contains_xy(struct graph *g, int x, int y)
{
	int first_x = g->xoffset;
	int last_x = g->xoffset + g->xdim;
	int first_y = g->yoffset;
	int last_y = g->yoffset + g->ydim;

	return (x >= first_x && x <= last_x) && (y >= first_y && y <= last_y);
}

static int xy_match(struct xyvalue *xy, int x, int y)
{
	int xdiff = abs(xy->gx - x);
	int ydiff = abs(xy->gy - y);

	return xdiff <= 20 && ydiff <= 10;
}

const char *graph_find_tooltip(struct graph *g, int x, int y)
{
	struct graph_label *i;
	struct graph_value *j;

	for (i = g->labels; i; i = i->next) {
		for (j = i->values; j; j = j->next) {
			struct xyvalue *xy = j->value;

			if (xy_match(xy, x - g->xoffset, y))
				return j->tooltip;
		}
	}

	return NULL;
}
