#  This file is part of pybootchartgui.

#  pybootchartgui 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.

#  pybootchartgui 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 pybootchartgui. If not, see <http://www.gnu.org/licenses/>.


import cairo
import math
import re
import random
import colorsys
from operator import itemgetter

class RenderOptions:

	def __init__(self, app_options):
		# should we render a cumulative CPU time chart
		self.cumulative = True
		self.charts = True
		self.kernel_only = False
		self.app_options = app_options

	def proc_tree (self, trace):
		if self.kernel_only:
			return trace.kernel_tree
		else:
			return trace.proc_tree

# Process tree background color.
BACK_COLOR = (1.0, 1.0, 1.0, 1.0)

WHITE = (1.0, 1.0, 1.0, 1.0)
# Process tree border color.
BORDER_COLOR = (0.63, 0.63, 0.63, 1.0)
# Second tick line color.
TICK_COLOR = (0.92, 0.92, 0.92, 1.0)
# 5-second tick line color.
TICK_COLOR_BOLD = (0.86, 0.86, 0.86, 1.0)
# Annotation colour
ANNOTATION_COLOR = (0.63, 0.0, 0.0, 0.5)
# Text color.
TEXT_COLOR = (0.0, 0.0, 0.0, 1.0)

# Font family
FONT_NAME = "Bitstream Vera Sans"
# Title text font.
TITLE_FONT_SIZE = 18
# Default text font.
TEXT_FONT_SIZE = 12
# Axis label font.
AXIS_FONT_SIZE = 11
# Legend font.
LEGEND_FONT_SIZE = 12

# CPU load chart color.
CPU_COLOR = (0.40, 0.55, 0.70, 1.0)
# IO wait chart color.
IO_COLOR = (0.76, 0.48, 0.48, 0.5)
# Disk throughput color.
DISK_TPUT_COLOR = (0.20, 0.71, 0.20, 1.0)
# CPU load chart color.
FILE_OPEN_COLOR = (0.20, 0.71, 0.71, 1.0)
# Mem cached color
MEM_CACHED_COLOR = CPU_COLOR
# Mem used color
MEM_USED_COLOR = IO_COLOR
# Buffers color
MEM_BUFFERS_COLOR = (0.4, 0.4, 0.4, 0.3)
# Swap color
MEM_SWAP_COLOR = DISK_TPUT_COLOR

# Process border color.
PROC_BORDER_COLOR = (0.71, 0.71, 0.71, 1.0)
# Waiting process color.
PROC_COLOR_D = (0.76, 0.48, 0.48, 0.5)
# Running process color.
PROC_COLOR_R = CPU_COLOR
# Sleeping process color.
PROC_COLOR_S = (0.94, 0.94, 0.94, 1.0)
# Stopped process color.
PROC_COLOR_T = (0.94, 0.50, 0.50, 1.0)
# Zombie process color.
PROC_COLOR_Z = (0.71, 0.71, 0.71, 1.0)
# Dead process color.
PROC_COLOR_X = (0.71, 0.71, 0.71, 0.125)
# Paging process color.
PROC_COLOR_W = (0.71, 0.71, 0.71, 0.125)

# Process label color.
PROC_TEXT_COLOR = (0.19, 0.19, 0.19, 1.0)
# Process label font.
PROC_TEXT_FONT_SIZE = 12

# Signature color.
SIG_COLOR = (0.0, 0.0, 0.0, 0.3125)
# Signature font.
SIG_FONT_SIZE = 14
# Signature text.
SIGNATURE = "http://github.com/mmeeks/bootchart"

# Process dependency line color.
DEP_COLOR = (0.75, 0.75, 0.75, 1.0)
# Process dependency line stroke.
DEP_STROKE = 1.0

# Process description date format.
DESC_TIME_FORMAT = "mm:ss.SSS"

# Cumulative coloring bits
HSV_MAX_MOD = 31
HSV_STEP = 7

# Configure task color
TASK_COLOR_CONFIGURE = (1.0, 1.0, 0.00, 1.0)
# Compile task color.
TASK_COLOR_COMPILE = (0.0, 1.00, 0.00, 1.0)
# Install task color
TASK_COLOR_INSTALL = (1.0, 0.00, 1.00, 1.0)
# Sysroot task color
TASK_COLOR_SYSROOT = (0.0, 0.00, 1.00, 1.0)
# Package task color
TASK_COLOR_PACKAGE = (0.0, 1.00, 1.00, 1.0)
# Package Write RPM/DEB/IPK task color
TASK_COLOR_PACKAGE_WRITE = (0.0, 0.50, 0.50, 1.0)

# Process states
STATE_UNDEFINED = 0
STATE_RUNNING   = 1
STATE_SLEEPING  = 2
STATE_WAITING   = 3
STATE_STOPPED   = 4
STATE_ZOMBIE    = 5

STATE_COLORS = [(0, 0, 0, 0), PROC_COLOR_R, PROC_COLOR_S, PROC_COLOR_D, \
		PROC_COLOR_T, PROC_COLOR_Z, PROC_COLOR_X, PROC_COLOR_W]

# CumulativeStats Types
STAT_TYPE_CPU = 0
STAT_TYPE_IO = 1

# Convert ps process state to an int
def get_proc_state(flag):
	return "RSDTZXW".find(flag) + 1

def draw_text(ctx, text, color, x, y):
	ctx.set_source_rgba(*color)
	ctx.move_to(x, y)
	ctx.show_text(text)

def draw_fill_rect(ctx, color, rect):
	ctx.set_source_rgba(*color)
	ctx.rectangle(*rect)
	ctx.fill()

def draw_rect(ctx, color, rect):
	ctx.set_source_rgba(*color)
	ctx.rectangle(*rect)
	ctx.stroke()

def draw_legend_box(ctx, label, fill_color, x, y, s):
	draw_fill_rect(ctx, fill_color, (x, y - s, s, s))
	draw_rect(ctx, PROC_BORDER_COLOR, (x, y - s, s, s))
	draw_text(ctx, label, TEXT_COLOR, x + s + 5, y)

def draw_legend_line(ctx, label, fill_color, x, y, s):
	draw_fill_rect(ctx, fill_color, (x, y - s/2, s + 1, 3))
	ctx.arc(x + (s + 1)/2.0, y - (s - 3)/2.0, 2.5, 0, 2.0 * math.pi)
	ctx.fill()
	draw_text(ctx, label, TEXT_COLOR, x + s + 5, y)

def draw_label_in_box(ctx, color, label, x, y, w, maxx):
	label_w = ctx.text_extents(label)[2]
	label_x = x + w / 2 - label_w / 2
	if label_w + 10 > w:
		label_x = x + w + 5
	if label_x + label_w > maxx:
		label_x = x - label_w - 5
	draw_text(ctx, label, color, label_x, y)

def draw_sec_labels(ctx, options, rect, sec_w, nsecs):
	ctx.set_font_size(AXIS_FONT_SIZE)
	prev_x = 0
	for i in range(0, rect[2] + 1, sec_w):
		if ((i / sec_w) % nsecs == 0) :
			if options.app_options.as_minutes :
				label = "%.1f" % (i / sec_w / 60.0)
			else :
				label = "%d" % (i / sec_w)
			label_w = ctx.text_extents(label)[2]
			x = rect[0] + i - label_w/2
			if x >= prev_x:
				draw_text(ctx, label, TEXT_COLOR, x, rect[1] - 2)
				prev_x = x + label_w

def draw_box_ticks(ctx, rect, sec_w):
	draw_rect(ctx, BORDER_COLOR, tuple(rect))

	ctx.set_line_cap(cairo.LINE_CAP_SQUARE)

	for i in range(sec_w, rect[2] + 1, sec_w):
		if ((i / sec_w) % 10 == 0) :
			ctx.set_line_width(1.5)
		elif sec_w < 5 :
			continue
		else :
			ctx.set_line_width(1.0)
		if ((i / sec_w) % 30 == 0) :
			ctx.set_source_rgba(*TICK_COLOR_BOLD)
		else :
			ctx.set_source_rgba(*TICK_COLOR)
		ctx.move_to(rect[0] + i, rect[1] + 1)
		ctx.line_to(rect[0] + i, rect[1] + rect[3] - 1)
		ctx.stroke()
	ctx.set_line_width(1.0)

	ctx.set_line_cap(cairo.LINE_CAP_BUTT)

def draw_annotations(ctx, proc_tree, times, rect):
    ctx.set_line_cap(cairo.LINE_CAP_SQUARE)
    ctx.set_source_rgba(*ANNOTATION_COLOR)
    ctx.set_dash([4, 4])

    for time in times:
        if time is not None:
            x = ((time - proc_tree.start_time) * rect[2] / proc_tree.duration)

            ctx.move_to(rect[0] + x, rect[1] + 1)
            ctx.line_to(rect[0] + x, rect[1] + rect[3] - 1)
            ctx.stroke()

    ctx.set_line_cap(cairo.LINE_CAP_BUTT)
    ctx.set_dash([])

def draw_chart(ctx, color, fill, chart_bounds, data, proc_tree, data_range):
	ctx.set_line_width(0.5)
	x_shift = proc_tree.start_time

	def transform_point_coords(point, x_base, y_base, \
				   xscale, yscale, x_trans, y_trans):
		x = (point[0] - x_base) * xscale + x_trans
		y = (point[1] - y_base) * -yscale + y_trans + chart_bounds[3]
		return x, y

	max_x = max (x for (x, y) in data)
	max_y = max (y for (x, y) in data)
	# avoid divide by zero
	if max_y == 0:
		max_y = 1.0
	xscale = float (chart_bounds[2]) / max_x
	# If data_range is given, scale the chart so that the value range in
	# data_range matches the chart bounds exactly.
	# Otherwise, scale so that the actual data matches the chart bounds.
	if data_range:
		yscale = float(chart_bounds[3]) / (data_range[1] - data_range[0])
		ybase = data_range[0]
	else:
		yscale = float(chart_bounds[3]) / max_y
		ybase = 0

	first = transform_point_coords (data[0], x_shift, ybase, xscale, yscale, \
				        chart_bounds[0], chart_bounds[1])
	last =  transform_point_coords (data[-1], x_shift, ybase, xscale, yscale, \
				        chart_bounds[0], chart_bounds[1])

	ctx.set_source_rgba(*color)
	ctx.move_to(*first)
	for point in data:
		x, y = transform_point_coords (point, x_shift, ybase, xscale, yscale, \
					       chart_bounds[0], chart_bounds[1])
		ctx.line_to(x, y)
	if fill:
		ctx.stroke_preserve()
		ctx.line_to(last[0], chart_bounds[1]+chart_bounds[3])
		ctx.line_to(first[0], chart_bounds[1]+chart_bounds[3])
		ctx.line_to(first[0], first[1])
		ctx.fill()
	else:
		ctx.stroke()
	ctx.set_line_width(1.0)

bar_h = 55
meminfo_bar_h = 2 * bar_h
header_h = 60
# offsets
off_x, off_y = 220, 10
sec_w_base = 1 # the width of a second
proc_h = 16 # the height of a process
leg_s = 10
MIN_IMG_W = 800
CUML_HEIGHT = 2000 # Increased value to accomodate CPU and I/O Graphs
OPTIONS = None

def extents(options, xscale, trace):
	start = min(trace.start.keys())
	end = start

        processes = 0
        for proc in trace.processes:
                if not options.app_options.show_all and \
                   trace.processes[proc][1] - trace.processes[proc][0] < options.app_options.mintime:
                        continue

                if trace.processes[proc][1] > end:
                        end = trace.processes[proc][1]
                processes += 1

	if trace.min is not None and trace.max is not None:
		start = trace.min
		end = trace.max

	w = int ((end - start) * sec_w_base * xscale) + 2 * off_x
	h = proc_h * processes + header_h + 2 * off_y

	return (w, h)

def clip_visible(clip, rect):
	xmax = max (clip[0], rect[0])
	ymax = max (clip[1], rect[1])
	xmin = min (clip[0] + clip[2], rect[0] + rect[2])
	ymin = min (clip[1] + clip[3], rect[1] + rect[3])
	return (xmin > xmax and ymin > ymax)

def render_charts(ctx, options, clip, trace, curr_y, w, h, sec_w):
	proc_tree = options.proc_tree(trace)

	# render bar legend
	ctx.set_font_size(LEGEND_FONT_SIZE)

	draw_legend_box(ctx, "CPU (user+sys)", CPU_COLOR, off_x, curr_y+20, leg_s)
	draw_legend_box(ctx, "I/O (wait)", IO_COLOR, off_x + 120, curr_y+20, leg_s)

	# render I/O wait
	chart_rect = (off_x, curr_y+30, w, bar_h)
	if clip_visible (clip, chart_rect):
		draw_box_ticks (ctx, chart_rect, sec_w)
		draw_annotations (ctx, proc_tree, trace.times, chart_rect)
		draw_chart (ctx, IO_COLOR, True, chart_rect, \
			    [(sample.time, sample.user + sample.sys + sample.io) for sample in trace.cpu_stats], \
			    proc_tree, None)
		# render CPU load
		draw_chart (ctx, CPU_COLOR, True, chart_rect, \
			    [(sample.time, sample.user + sample.sys) for sample in trace.cpu_stats], \
			    proc_tree, None)

	curr_y = curr_y + 30 + bar_h

	# render second chart
	draw_legend_line(ctx, "Disk throughput", DISK_TPUT_COLOR, off_x, curr_y+20, leg_s)
	draw_legend_box(ctx, "Disk utilization", IO_COLOR, off_x + 120, curr_y+20, leg_s)

        # render I/O utilization
	chart_rect = (off_x, curr_y+30, w, bar_h)
	if clip_visible (clip, chart_rect):
		draw_box_ticks (ctx, chart_rect, sec_w)
		draw_annotations (ctx, proc_tree, trace.times, chart_rect)
		draw_chart (ctx, IO_COLOR, True, chart_rect, \
			    [(sample.time, sample.util) for sample in trace.disk_stats], \
			    proc_tree, None)

	# render disk throughput
	max_sample = max (trace.disk_stats, key = lambda s: s.tput)
	if clip_visible (clip, chart_rect):
		draw_chart (ctx, DISK_TPUT_COLOR, False, chart_rect, \
			    [(sample.time, sample.tput) for sample in trace.disk_stats], \
			    proc_tree, None)

	pos_x = off_x + ((max_sample.time - proc_tree.start_time) * w / proc_tree.duration)

	shift_x, shift_y = -20, 20
	if (pos_x < off_x + 245):
		shift_x, shift_y = 5, 40

	label = "%dMB/s" % round ((max_sample.tput) / 1024.0)
	draw_text (ctx, label, DISK_TPUT_COLOR, pos_x + shift_x, curr_y + shift_y)

	curr_y = curr_y + 30 + bar_h

	# render mem usage
	chart_rect = (off_x, curr_y+30, w, meminfo_bar_h)
	mem_stats = trace.mem_stats
	if mem_stats and clip_visible (clip, chart_rect):
		mem_scale = max(sample.records['MemTotal'] - sample.records['MemFree'] for sample in mem_stats)
		draw_legend_box(ctx, "Mem cached (scale: %u MiB)" % (float(mem_scale) / 1024), MEM_CACHED_COLOR, off_x, curr_y+20, leg_s)
		draw_legend_box(ctx, "Used", MEM_USED_COLOR, off_x + 240, curr_y+20, leg_s)
		draw_legend_box(ctx, "Buffers", MEM_BUFFERS_COLOR, off_x + 360, curr_y+20, leg_s)
		draw_legend_line(ctx, "Swap (scale: %u MiB)" % max([(sample.records['SwapTotal'] - sample.records['SwapFree'])/1024 for sample in mem_stats]), \
				 MEM_SWAP_COLOR, off_x + 480, curr_y+20, leg_s)
		draw_box_ticks(ctx, chart_rect, sec_w)
		draw_annotations(ctx, proc_tree, trace.times, chart_rect)
		draw_chart(ctx, MEM_BUFFERS_COLOR, True, chart_rect, \
			   [(sample.time, sample.records['MemTotal'] - sample.records['MemFree']) for sample in trace.mem_stats], \
			   proc_tree, [0, mem_scale])
		draw_chart(ctx, MEM_USED_COLOR, True, chart_rect, \
			   [(sample.time, sample.records['MemTotal'] - sample.records['MemFree'] - sample.records['Buffers']) for sample in mem_stats], \
			   proc_tree, [0, mem_scale])
		draw_chart(ctx, MEM_CACHED_COLOR, True, chart_rect, \
			   [(sample.time, sample.records['Cached']) for sample in mem_stats], \
			   proc_tree, [0, mem_scale])
		draw_chart(ctx, MEM_SWAP_COLOR, False, chart_rect, \
			   [(sample.time, float(sample.records['SwapTotal'] - sample.records['SwapFree'])) for sample in mem_stats], \
			   proc_tree, None)

		curr_y = curr_y + meminfo_bar_h

	return curr_y

def render_processes_chart(ctx, options, trace, curr_y, w, h, sec_w):
        chart_rect = [off_x, curr_y+header_h, w, h - 2 * off_y - (curr_y+header_h) + proc_h]

	draw_legend_box (ctx, "Configure", \
			 TASK_COLOR_CONFIGURE, off_x  , curr_y + 45, leg_s)
	draw_legend_box (ctx, "Compile", \
			 TASK_COLOR_COMPILE, off_x+120, curr_y + 45, leg_s)
	draw_legend_box (ctx, "Install", \
			 TASK_COLOR_INSTALL, off_x+240, curr_y + 45, leg_s)
	draw_legend_box (ctx, "Populate Sysroot", \
			 TASK_COLOR_SYSROOT, off_x+360, curr_y + 45, leg_s)
	draw_legend_box (ctx, "Package", \
			 TASK_COLOR_PACKAGE, off_x+480, curr_y + 45, leg_s)
	draw_legend_box (ctx, "Package Write",
			 TASK_COLOR_PACKAGE_WRITE, off_x+600, curr_y + 45, leg_s)

	ctx.set_font_size(PROC_TEXT_FONT_SIZE)

	draw_box_ticks(ctx, chart_rect, sec_w)
	draw_sec_labels(ctx, options, chart_rect, sec_w, 30)

	y = curr_y+header_h

        offset = trace.min or min(trace.start.keys())
        for s in sorted(trace.start.keys()):
            for val in sorted(trace.start[s]):
                if not options.app_options.show_all and \
                   trace.processes[val][1] - s < options.app_options.mintime:
                    continue
                task = val.split(":")[1]
                #print val
                #print trace.processes[val][1]
                #print s
                x = chart_rect[0] + (s - offset) * sec_w
                w = ((trace.processes[val][1] - s) * sec_w)

                #print "proc at %s %s %s %s" % (x, y, w, proc_h)
                col = None
                if task == "do_compile":
                    col = TASK_COLOR_COMPILE
                elif task == "do_configure":
                    col = TASK_COLOR_CONFIGURE
                elif task == "do_install":
                    col = TASK_COLOR_INSTALL
                elif task == "do_populate_sysroot":
                    col = TASK_COLOR_SYSROOT
                elif task == "do_package":
                    col = TASK_COLOR_PACKAGE
                elif task == "do_package_write_rpm" or \
                     task == "do_package_write_deb" or \
                     task == "do_package_write_ipk":
                    col = TASK_COLOR_PACKAGE_WRITE
                else:
                    col = WHITE

                if col:
                    draw_fill_rect(ctx, col, (x, y, w, proc_h))
                draw_rect(ctx, PROC_BORDER_COLOR, (x, y, w, proc_h))

                draw_label_in_box(ctx, PROC_TEXT_COLOR, val, x, y + proc_h - 4, w, proc_h)
                y = y + proc_h

	return curr_y

#
# Render the chart.
#
def render(ctx, options, xscale, trace):
	(w, h) = extents (options, xscale, trace)
	global OPTIONS
	OPTIONS = options.app_options

	# x, y, w, h
	clip = ctx.clip_extents()

	sec_w = int (xscale * sec_w_base)
	ctx.set_line_width(1.0)
	ctx.select_font_face(FONT_NAME)
	draw_fill_rect(ctx, WHITE, (0, 0, max(w, MIN_IMG_W), h))
	w -= 2*off_x
	curr_y = off_y;

	curr_y = render_processes_chart (ctx, options, trace, curr_y, w, h, sec_w)

	return

	proc_tree = options.proc_tree (trace)

	# draw the title and headers
	if proc_tree.idle:
		duration = proc_tree.idle
	else:
		duration = proc_tree.duration

	if not options.kernel_only:
		curr_y = draw_header (ctx, trace.headers, duration)
	else:
		curr_y = off_y;

	if options.charts:
		curr_y = render_charts (ctx, options, clip, trace, curr_y, w, h, sec_w)

	# draw process boxes
	proc_height = h
	if proc_tree.taskstats and options.cumulative:
		proc_height -= CUML_HEIGHT

	draw_process_bar_chart(ctx, clip, options, proc_tree, trace.times,
			       curr_y, w, proc_height, sec_w)

	curr_y = proc_height
	ctx.set_font_size(SIG_FONT_SIZE)
	draw_text(ctx, SIGNATURE, SIG_COLOR, off_x + 5, proc_height - 8)

	# draw a cumulative CPU-time-per-process graph
	if proc_tree.taskstats and options.cumulative:
		cuml_rect = (off_x, curr_y + off_y, w, CUML_HEIGHT/2 - off_y * 2)
		if clip_visible (clip, cuml_rect):
			draw_cuml_graph(ctx, proc_tree, cuml_rect, duration, sec_w, STAT_TYPE_CPU)

	# draw a cumulative I/O-time-per-process graph
	if proc_tree.taskstats and options.cumulative:
		cuml_rect = (off_x, curr_y + off_y * 100, w, CUML_HEIGHT/2 - off_y * 2)
		if clip_visible (clip, cuml_rect):
			draw_cuml_graph(ctx, proc_tree, cuml_rect, duration, sec_w, STAT_TYPE_IO)

def draw_process_bar_chart(ctx, clip, options, proc_tree, times, curr_y, w, h, sec_w):
	header_size = 0
	if not options.kernel_only:
		draw_legend_box (ctx, "Running (%cpu)",
				 PROC_COLOR_R, off_x    , curr_y + 45, leg_s)
		draw_legend_box (ctx, "Unint.sleep (I/O)",
				 PROC_COLOR_D, off_x+120, curr_y + 45, leg_s)
		draw_legend_box (ctx, "Sleeping",
				 PROC_COLOR_S, off_x+240, curr_y + 45, leg_s)
		draw_legend_box (ctx, "Zombie",
				 PROC_COLOR_Z, off_x+360, curr_y + 45, leg_s)
		header_size = 45

	chart_rect = [off_x, curr_y + header_size + 15,
		      w, h - 2 * off_y - (curr_y + header_size + 15) + proc_h]
	ctx.set_font_size (PROC_TEXT_FONT_SIZE)

	draw_box_ticks (ctx, chart_rect, sec_w)
	if sec_w > 100:
		nsec = 1
	else:
		nsec = 5
	draw_sec_labels (ctx, options, chart_rect, sec_w, nsec)
	draw_annotations (ctx, proc_tree, times, chart_rect)

	y = curr_y + 60
	for root in proc_tree.process_tree:
		draw_processes_recursively(ctx, root, proc_tree, y, proc_h, chart_rect, clip)
		y = y + proc_h * proc_tree.num_nodes([root])


def draw_header (ctx, headers, duration):
    toshow = [
      ('system.uname', 'uname', lambda s: s),
      ('system.release', 'release', lambda s: s),
      ('system.cpu', 'CPU', lambda s: re.sub('model name\s*:\s*', '', s, 1)),
      ('system.kernel.options', 'kernel options', lambda s: s),
    ]

    header_y = ctx.font_extents()[2] + 10
    ctx.set_font_size(TITLE_FONT_SIZE)
    draw_text(ctx, headers['title'], TEXT_COLOR, off_x, header_y)
    ctx.set_font_size(TEXT_FONT_SIZE)

    for (headerkey, headertitle, mangle) in toshow:
        header_y += ctx.font_extents()[2]
        if headerkey in headers:
            value = headers.get(headerkey)
        else:
            value = ""
        txt = headertitle + ': ' + mangle(value)
        draw_text(ctx, txt, TEXT_COLOR, off_x, header_y)

    dur = duration / 100.0
    txt = 'time : %02d:%05.2f' % (math.floor(dur/60), dur - 60 * math.floor(dur/60))
    if headers.get('system.maxpid') is not None:
        txt = txt + '      max pid: %s' % (headers.get('system.maxpid'))

    header_y += ctx.font_extents()[2]
    draw_text (ctx, txt, TEXT_COLOR, off_x, header_y)

    return header_y

def draw_processes_recursively(ctx, proc, proc_tree, y, proc_h, rect, clip) :
	x = rect[0] +  ((proc.start_time - proc_tree.start_time) * rect[2] / proc_tree.duration)
	w = ((proc.duration) * rect[2] / proc_tree.duration)

	draw_process_activity_colors(ctx, proc, proc_tree, x, y, w, proc_h, rect, clip)
	draw_rect(ctx, PROC_BORDER_COLOR, (x, y, w, proc_h))
	ipid = int(proc.pid)
	if not OPTIONS.show_all:
		cmdString = proc.cmd
	else:
		cmdString = ''
	if (OPTIONS.show_pid or OPTIONS.show_all) and ipid is not 0:
		cmdString = cmdString + " [" + str(ipid // 1000) + "]"
	if OPTIONS.show_all:
		if proc.args:
			cmdString = cmdString + " '" + "' '".join(proc.args) + "'"
		else:
			cmdString = cmdString + " " + proc.exe

	draw_label_in_box(ctx, PROC_TEXT_COLOR, cmdString, x, y + proc_h - 4, w, rect[0] + rect[2])

	next_y = y + proc_h
	for child in proc.child_list:
		if next_y > clip[1] + clip[3]:
			break
		child_x, child_y = draw_processes_recursively(ctx, child, proc_tree, next_y, proc_h, rect, clip)
		draw_process_connecting_lines(ctx, x, y, child_x, child_y, proc_h)
		next_y = next_y + proc_h * proc_tree.num_nodes([child])

	return x, y


def draw_process_activity_colors(ctx, proc, proc_tree, x, y, w, proc_h, rect, clip):

	if y > clip[1] + clip[3] or y + proc_h + 2 < clip[1]:
		return

	draw_fill_rect(ctx, PROC_COLOR_S, (x, y, w, proc_h))

	last_tx = -1
	for sample in proc.samples :
		tx = rect[0] + round(((sample.time - proc_tree.start_time) * rect[2] / proc_tree.duration))

		# samples are sorted chronologically
		if tx < clip[0]:
			continue
		if tx > clip[0] + clip[2]:
			break

		tw = round(proc_tree.sample_period * rect[2] / float(proc_tree.duration))
		if last_tx != -1 and abs(last_tx - tx) <= tw:
			tw -= last_tx - tx
			tx = last_tx
		tw = max (tw, 1) # nice to see at least something

		last_tx = tx + tw
		state = get_proc_state( sample.state )

		color = STATE_COLORS[state]
		if state == STATE_RUNNING:
			alpha = min (sample.cpu_sample.user + sample.cpu_sample.sys, 1.0)
			color = tuple(list(PROC_COLOR_R[0:3]) + [alpha])
#			print "render time %d [ tx %d tw %d ], sample state %s color %s alpha %g" % (sample.time, tx, tw, state, color, alpha)
		elif state == STATE_SLEEPING:
			continue

		draw_fill_rect(ctx, color, (tx, y, tw, proc_h))

def draw_process_connecting_lines(ctx, px, py, x, y, proc_h):
	ctx.set_source_rgba(*DEP_COLOR)
	ctx.set_dash([2, 2])
	if abs(px - x) < 3:
		dep_off_x = 3
		dep_off_y = proc_h / 4
		ctx.move_to(x, y + proc_h / 2)
		ctx.line_to(px - dep_off_x, y + proc_h / 2)
		ctx.line_to(px - dep_off_x, py - dep_off_y)
		ctx.line_to(px, py - dep_off_y)
	else:
		ctx.move_to(x, y + proc_h / 2)
		ctx.line_to(px, y + proc_h / 2)
		ctx.line_to(px, py)
	ctx.stroke()
	ctx.set_dash([])

# elide the bootchart collector - it is quite distorting
def elide_bootchart(proc):
	return proc.cmd == 'bootchartd' or proc.cmd == 'bootchart-colle'

class CumlSample:
	def __init__(self, proc):
		self.cmd = proc.cmd
		self.samples = []
		self.merge_samples (proc)
		self.color = None

	def merge_samples(self, proc):
		self.samples.extend (proc.samples)
		self.samples.sort (key = lambda p: p.time)

	def next(self):
		global palette_idx
		palette_idx += HSV_STEP
		return palette_idx

	def get_color(self):
		if self.color is None:
			i = self.next() % HSV_MAX_MOD
			h = 0.0
			if i is not 0:
				h = (1.0 * i) / HSV_MAX_MOD
			s = 0.5
			v = 1.0
			c = colorsys.hsv_to_rgb (h, s, v)
			self.color = (c[0], c[1], c[2], 1.0)
		return self.color


def draw_cuml_graph(ctx, proc_tree, chart_bounds, duration, sec_w, stat_type):
	global palette_idx
	palette_idx = 0

	time_hash = {}
	total_time = 0.0
	m_proc_list = {}

	if stat_type is STAT_TYPE_CPU:
		sample_value = 'cpu'
	else:
		sample_value = 'io'
	for proc in proc_tree.process_list:
		if elide_bootchart(proc):
			continue

		for sample in proc.samples:
			total_time += getattr(sample.cpu_sample, sample_value)
			if not sample.time in time_hash:
				time_hash[sample.time] = 1

		# merge pids with the same cmd
		if not proc.cmd in m_proc_list:
			m_proc_list[proc.cmd] = CumlSample (proc)
			continue
		s = m_proc_list[proc.cmd]
		s.merge_samples (proc)

	# all the sample times
	times = sorted(time_hash)
	if len (times) < 2:
		print("degenerate boot chart")
		return

	pix_per_ns = chart_bounds[3] / total_time
#	print "total time: %g pix-per-ns %g" % (total_time, pix_per_ns)

	# FIXME: we have duplicates in the process list too [!] - why !?

	# Render bottom up, left to right
	below = {}
	for time in times:
		below[time] = chart_bounds[1] + chart_bounds[3]

	# same colors each time we render
	random.seed (0)

	ctx.set_line_width(1)

	legends = []
	labels = []

	# render each pid in order
	for cs in m_proc_list.values():
		row = {}
		cuml = 0.0

		# print "pid : %s -> %g samples %d" % (proc.cmd, cuml, len (cs.samples))
		for sample in cs.samples:
			cuml += getattr(sample.cpu_sample, sample_value)
			row[sample.time] = cuml

		process_total_time = cuml

		# hide really tiny processes
		if cuml * pix_per_ns <= 2:
			continue

		last_time = times[0]
		y = last_below = below[last_time]
		last_cuml = cuml = 0.0

		ctx.set_source_rgba(*cs.get_color())
		for time in times:
			render_seg = False

			# did the underlying trend increase ?
			if below[time] != last_below:
				last_below = below[last_time]
				last_cuml = cuml
				render_seg = True

			# did we move up a pixel increase ?
			if time in row:
				nc = round (row[time] * pix_per_ns)
				if nc != cuml:
					last_cuml = cuml
					cuml = nc
					render_seg = True

#			if last_cuml > cuml:
#				assert fail ... - un-sorted process samples

			# draw the trailing rectangle from the last time to
			# before now, at the height of the last segment.
			if render_seg:
				w = math.ceil ((time - last_time) * chart_bounds[2] / proc_tree.duration) + 1
				x = chart_bounds[0] + round((last_time - proc_tree.start_time) * chart_bounds[2] / proc_tree.duration)
				ctx.rectangle (x, below[last_time] - last_cuml, w, last_cuml)
				ctx.fill()
#				ctx.stroke()
				last_time = time
				y = below [time] - cuml

			row[time] = y

		# render the last segment
		x = chart_bounds[0] + round((last_time - proc_tree.start_time) * chart_bounds[2] / proc_tree.duration)
		y = below[last_time] - cuml
		ctx.rectangle (x, y, chart_bounds[2] - x, cuml)
		ctx.fill()
#		ctx.stroke()

		# render legend if it will fit
		if cuml > 8:
			label = cs.cmd
			extnts = ctx.text_extents(label)
			label_w = extnts[2]
			label_h = extnts[3]
#			print "Text extents %g by %g" % (label_w, label_h)
			labels.append((label,
				       chart_bounds[0] + chart_bounds[2] - label_w - off_x * 2,
				       y + (cuml + label_h) / 2))
			if cs in legends:
				print("ARGH - duplicate process in list !")

		legends.append ((cs, process_total_time))

		below = row

	# render grid-lines over the top
	draw_box_ticks(ctx, chart_bounds, sec_w)

	# render labels
	for l in labels:
		draw_text(ctx, l[0], TEXT_COLOR, l[1], l[2])

	# Render legends
	font_height = 20
	label_width = 300
	LEGENDS_PER_COL = 15
	LEGENDS_TOTAL = 45
	ctx.set_font_size (TITLE_FONT_SIZE)
	dur_secs = duration / 100
	cpu_secs = total_time / 1000000000

	# misleading - with multiple CPUs ...
#	idle = ((dur_secs - cpu_secs) / dur_secs) * 100.0
	if stat_type is STAT_TYPE_CPU:
		label = "Cumulative CPU usage, by process; total CPU: " \
			" %.5g(s) time: %.3g(s)" % (cpu_secs, dur_secs)
	else:
		label = "Cumulative I/O usage, by process; total I/O: " \
			" %.5g(s) time: %.3g(s)" % (cpu_secs, dur_secs)

	draw_text(ctx, label, TEXT_COLOR, chart_bounds[0] + off_x,
		  chart_bounds[1] + font_height)

	i = 0
	legends = sorted(legends, key=itemgetter(1), reverse=True)
	ctx.set_font_size(TEXT_FONT_SIZE)
	for t in legends:
		cs = t[0]
		time = t[1]
		x = chart_bounds[0] + off_x + int (i/LEGENDS_PER_COL) * label_width
		y = chart_bounds[1] + font_height * ((i % LEGENDS_PER_COL) + 2)
		str = "%s - %.0f(ms) (%2.2f%%)" % (cs.cmd, time/1000000, (time/total_time) * 100.0)
		draw_legend_box(ctx, str, cs.color, x, y, leg_s)
		i = i + 1
		if i >= LEGENDS_TOTAL:
			break
