#include "stdinc.h"
#include "dat.h"
#include "fns.h"

enum
{
	Top = 1,
	Bottom = 1,
	Left = 40,
	Right = 0,
	MinWidth = Left+Right+2,
	MinHeight = Top+Bottom+2,
	DefaultWidth = Left+Right+500,
	DefaultHeight = Top+Bottom+40
};

QLock memdrawlock;
static Memsubfont *smallfont;
static Memimage *black;
static Memimage *blue;
static Memimage *red;
static Memimage *lofill[6];
static Memimage *hifill[6];
static Memimage *grid;

static ulong fill[] = {
	0xFFAAAAFF,	0xBB5D5DFF,	/* peach */
	DPalegreygreen, DPurpleblue,	/* aqua */
	DDarkyellow, DYellowgreen,	/* yellow */
	DMedgreen, DDarkgreen,		/* green */
	0x00AAFFFF, 0x0088CCFF,	/* blue */
	0xCCCCCCFF, 0x888888FF,	/* grey */
};

Memimage*
allocrepl(ulong color)
{
	Memimage *m;
	
	m = allocmemimage(Rect(0,0,1,1), RGB24);
	memfillcolor(m, color);
	m->flags |= Frepl;
	m->clipr = Rect(-1000000, -1000000, 1000000, 1000000);
	return m;
}

static void
ginit(void)
{
	static int first = 1;
	int i;
	
	if(!first)
		return;
		
	first = 0;
	memimageinit();
	smallfont = openmemsubfont(unsharp("#9/font/lucidasans/lstr.10"));
	black = memblack;
	blue = allocrepl(DBlue);
	red = allocrepl(DRed);
	grid = allocrepl(0x77777777);
	for(i=0; i<nelem(fill)/2 && i<nelem(lofill) && i<nelem(hifill); i++){
		lofill[i] = allocrepl(fill[2*i]);
		hifill[i] = allocrepl(fill[2*i+1]);
	}
}

static void
mklabel(char *str, int v)
{
	if(v < 0){
		v = -v;
		*str++ = '-';
	}
	if(v < 10000)
		sprint(str, "%d", v);
	else if(v < 10000000)
		sprint(str, "%dk", v/1000);
	else
		sprint(str, "%dM", v/1000000);
}

static void
drawlabel(Memimage *m, Point p, int n)
{
	char buf[30];
	Point w;
	
	mklabel(buf, n);
	w = memsubfontwidth(smallfont, buf);
	memimagestring(m, Pt(p.x-5-w.x, p.y), memblack, ZP, smallfont, buf);
}

static int
scalept(int val, int valmin, int valmax, int ptmin, int ptmax)
{
	if(val <= valmin)
		val = valmin;
	if(val >= valmax)
		val = valmax;
	if(valmax == valmin)
		valmax++;
	return ptmin + (vlong)(val-valmin)*(ptmax-ptmin)/(valmax-valmin);
}

Memimage*
statgraph(Graph *g)
{
	int i, lastlo, nbin, x, lo, hi, min, max, first;
	Memimage *m;
	Rectangle r;
	Statbin *b, bin[2000];	/* 32 kB, but whack is worse */

	needstack(8192);	/* double check that bin didn't kill us */
	
	if(g->wid <= MinWidth)
		g->wid = DefaultWidth;
	if(g->ht <= MinHeight)
		g->ht = DefaultHeight;
	if(g->wid > nelem(bin))
		g->wid = nelem(bin);
	if(g->fill < 0)
		g->fill = ((uint)g->arg>>8)%nelem(lofill);
	if(g->fill > nelem(lofill))
		g->fill %= nelem(lofill);
	
	nbin = g->wid - (Left+Right);
	binstats(g->fn, g->arg, g->t0, g->t1, bin, nbin);

	/*
	 * compute bounds
	 */
	min = g->min;
	max = g->max;
	if(min < 0 || max <= min){
		min = max = 0;
		first = 1;
		for(i=0; i<nbin; i++){
			b = &bin[i];
			if(b->nsamp == 0)
				continue;
			if(first || b->min < min)
				min = b->min;
			if(first || b->max > max)
				max = b->max;
			first = 0;
		}
	}

	qlock(&memdrawlock);
	ginit();
	if(smallfont==nil || black==nil || blue==nil || red==nil || hifill==nil || lofill==nil){
		werrstr("graphics initialization failed");
		qunlock(&memdrawlock);
		return nil;
	}

	/* fresh image */
	m = allocmemimage(Rect(0,0,g->wid,g->ht), ABGR32);
	if(m == nil){
		qunlock(&memdrawlock);
		return nil;
	}
	r = Rect(Left, Top, g->wid-Right, g->ht-Bottom);
	memfillcolor(m, DTransparent);
	
	/* x axis */
	memimagedraw(m, Rect(r.min.x, r.max.y, r.max.x, r.max.y+1), black, ZP, memopaque, ZP, S);

	/* y labels */
	drawlabel(m, r.min, max);
	if(min != 0)
		drawlabel(m, Pt(r.min.x, r.max.y-smallfont->height), min);
	
	/* actual data */
	lastlo = -1;
	for(i=0; i<nbin; i++){
		b = &bin[i];
		if(b->nsamp == 0)
			continue;
		lo = scalept(b->min, min, max, r.max.y, r.min.y);
		hi = scalept(b->max, min, max, r.max.y, r.min.y);
		x = r.min.x+i;
		hi-=2;
		if(0)
		if(lastlo != -1){
			if(lastlo < lo)
				memimagedraw(m, Rect(x-1, lastlo, x, lo), hifill[g->fill], ZP, memopaque, ZP, S);
			else if(lastlo > lo)
				memimagedraw(m, Rect(x-1, lo, x, lastlo), hifill[g->fill], ZP, memopaque, ZP, S);
		}
		memimagedraw(m, Rect(x, hi, x+1,lo), hifill[g->fill], ZP, memopaque, ZP, S);
		memimagedraw(m, Rect(x, lo, x+1, r.max.y), lofill[g->fill], ZP, memopaque, ZP, S);
		lastlo = lo;
	}

	if(bin[nbin-1].nsamp)
		drawlabel(m, Pt(r.max.x, r.min.y+(Dy(r)-smallfont->height)/2), bin[nbin-1].avg);
	qunlock(&memdrawlock);
	return m;
}
