#include <u.h>
#include <libc.h>
#include <draw.h>

static int	fontresize(Font*, int, int, int);
#if 0
static int	freeup(Font*);
#endif

#define	PJW	0	/* use NUL==pjw for invisible characters */

static Rune empty[] = { 0 };
int
cachechars(Font *f, char **ss, Rune **rr, ushort *cp, int max, int *wp, char **subfontname)
{
	int i, th, sh, h, ld, w, rw, wid, nc;
	char *sp;
	Rune r, *rp, vr;
	ulong a;
	Cacheinfo *c, *tc, *ec;

	if(ss){
		sp = *ss;
		rp = empty;
	}else{
		sp = "";
		rp = *rr;
	}
	wid = 0;
	*subfontname = 0;
	for(i=0; i<max && (*sp || *rp); sp+=w, rp+=rw){
		if(ss){
			r = *(uchar*)sp;
			if(r < Runeself)
				w = 1;
			else{
				w = chartorune(&vr, sp);
				r = vr;
			}
			rw = 0;
		}else{
			r = *rp;
			w = 0;
			rw = 1;
		}

		sh = (17 * (uint)r) & (f->ncache-NFLOOK-1);
		c = &f->cache[sh];
		ec = c+NFLOOK;
		h = sh;
		while(c < ec){
			if(c->value==r && c->age)
				goto Found;
			c++;
			h++;
		}
	
		/*
		 * Not found; toss out oldest entry
		 */
		a = ~0;
		th = sh;
		tc = &f->cache[th];
		while(tc < ec){
			if(tc->age < a){
				a = tc->age;
				h = th;
				c = tc;
			}
			tc++;
			th++;
		}

		if(a && (f->age-a)<500){	/* kicking out too recent; resize */
			nc = 2*(f->ncache-NFLOOK) + NFLOOK;
			if(nc <= MAXFCACHE){
				if(i == 0)
					fontresize(f, f->width, nc, f->maxdepth);
				/* else flush first; retry will resize */
				break;
			}
		}

		if(c->age == f->age)	/* flush pending string output */
			break;

		ld = loadchar(f, r, c, h, i, subfontname);
		if(ld <= 0){
			if(ld == 0)
				continue;
			break;
		}
		c = &f->cache[h];	/* may have reallocated f->cache */
	
	    Found:
		wid += c->width;
		c->age = f->age;
		cp[i] = h;
		i++;
	}
	if(ss)
		*ss = sp;
	else
		*rr = rp;
	*wp = wid;
	return i;
}

void
agefont(Font *f)
{
	Cacheinfo *c, *ec;
	Cachesubf *s, *es;

	f->age++;
	if(f->age == 65536){
		/*
		 * Renormalize ages
		 */
		c = f->cache;
		ec = c+f->ncache;
		while(c < ec){
			if(c->age){
				c->age >>= 2;
				c->age++;
			}
			c++;
		}
		s = f->subf;
		es = s+f->nsubf;
		while(s < es){
			if(s->age){
				if(s->age<SUBFAGE && s->cf->name != nil){
					/* clean up */
					if(display==nil || s->f != display->defaultsubfont)
						freesubfont(s->f);
					s->cf = nil;
					s->f = nil;
					s->age = 0;
				}else{
					s->age >>= 2;
					s->age++;
				}
			}
			s++;
		}
		f->age = (65536>>2) + 1;
	}
}

static Subfont*
cf2subfont(Cachefont *cf, Font *f)
{
	int depth;
	char *name;
	Subfont *sf;

	name = cf->subfontname;
	if(name == nil){
		depth = 0;
		if(f->display){
			if(f->display->screenimage)
				depth = f->display->screenimage->depth;
		}else
			depth = 8;
		name = subfontname(cf->name, f->name, depth);
		if(name == nil)
			return nil;
		cf->subfontname = name;
	}
	sf = lookupsubfont(f->display, name);
	return sf;
}

/* return 1 if load succeeded, 0 if failed, -1 if must retry */
int
loadchar(Font *f, Rune r, Cacheinfo *c, int h, int noflush, char **subfontname)
{
	int i, oi, wid, top, bottom;
	int pic;	/* need >16 bits for adding offset below */
	Fontchar *fi;
	Cachefont *cf;
	Cachesubf *subf, *of;
	uchar *b;

	pic = r;
    Again:
	for(i=0; i<f->nsub; i++){
		cf = f->sub[i];
		if(cf->min<=pic && pic<=cf->max)
			goto Found;
	}
    TryPJW:
	if(pic != PJW){
		pic = PJW;
		goto Again;
	}
	return 0;

    Found:
	/*
	 * Choose exact or oldest
	 */
	oi = 0;
	subf = &f->subf[0];
	for(i=0; i<f->nsubf; i++){
		if(cf == subf->cf)
			goto Found2;
		if(subf->age < f->subf[oi].age)
			oi = i;
		subf++;
	}
	subf = &f->subf[oi];

	if(subf->f){
		if(f->age-subf->age>SUBFAGE || f->nsubf>MAXSUBF){
    Toss:
			/* ancient data; toss */
			freesubfont(subf->f);
			subf->cf = nil;
			subf->f = nil;
			subf->age = 0;
		}else{				/* too recent; grow instead */
			of = f->subf;
			f->subf = realloc(of, (f->nsubf+DSUBF)*sizeof *subf);
			if(f->subf == nil){
				f->subf = of;
				goto Toss;
			}
			memset(f->subf+f->nsubf, 0, DSUBF*sizeof *subf);
			subf = &f->subf[f->nsubf];
			f->nsubf += DSUBF;
		}
	}
	subf->age = 0;
	subf->cf = nil;
	subf->f = cf2subfont(cf, f);
	if(subf->f == nil){
		if(cf->subfontname == nil)
			goto TryPJW;
		*subfontname = cf->subfontname;
		return -1;
	}

	subf->cf = cf;
	if(subf->f->ascent > f->ascent && f->display){
		/* should print something? this is a mistake in the font file */
		/* must prevent c->top from going negative when loading cache */
		Image *b;
		int d, t;
		d = subf->f->ascent - f->ascent;
		b = subf->f->bits;
		draw(b, b->r, b, nil, addpt(b->r.min, Pt(0, d)));
		draw(b, Rect(b->r.min.x, b->r.max.y-d, b->r.max.x, b->r.max.y), f->display->black, nil, b->r.min);
		for(i=0; i<subf->f->n; i++){
			t = subf->f->info[i].top-d;
			if(t < 0)
				t = 0;
			subf->f->info[i].top = t;
			t = subf->f->info[i].bottom-d;
			if(t < 0)
				t = 0;
			subf->f->info[i].bottom = t;
		}
		subf->f->ascent = f->ascent;
	}

    Found2:
	subf->age = f->age;

	/* possible overflow here, but works out okay */
	pic += cf->offset;
	pic -= cf->min;
	if(pic >= subf->f->n)
		goto TryPJW;
	fi = &subf->f->info[pic];
	if(fi->width == 0)
		goto TryPJW;
	wid = (fi+1)->x - fi->x;
	if(f->width < wid || f->width == 0 || f->maxdepth < subf->f->bits->depth){
		/*
		 * Flush, free, reload (easier than reformatting f->b)
		 */
		if(noflush)
			return -1;
		if(f->width < wid)
			f->width = wid;
		if(f->maxdepth < subf->f->bits->depth)
			f->maxdepth = subf->f->bits->depth;
		i = fontresize(f, f->width, f->ncache, f->maxdepth);
		if(i <= 0)
			return i;
		/* c is still valid as didn't reallocate f->cache */
	}
	c->value = r;
	top = fi->top + (f->ascent-subf->f->ascent);
	bottom = fi->bottom + (f->ascent-subf->f->ascent);
	c->width = fi->width;
	c->x = h*f->width;
	c->left = fi->left;
	if(f->display == nil)
		return 1;
	flushimage(f->display, 0);	/* flush any pending errors */
	b = bufimage(f->display, 37);
	if(b == 0)
		return 0;
	b[0] = 'l';
	BPLONG(b+1, f->cacheimage->id);
	BPLONG(b+5, subf->f->bits->id);
	BPSHORT(b+9, c-f->cache);
	BPLONG(b+11, c->x);
	BPLONG(b+15, top);
	BPLONG(b+19, c->x+((fi+1)->x-fi->x));
	BPLONG(b+23, bottom);
	BPLONG(b+27, fi->x);
	BPLONG(b+31, fi->top);
	b[35] = fi->left;
	b[36] = fi->width;
	return 1;
}

/* release all subfonts, return number freed */
#if 0
static
int
freeup(Font *f)
{
	Cachesubf *s, *es;
	int nf;

	if(f->sub[0]->name == nil)	/* font from mkfont; don't free */
		return 0;
	s = f->subf;
	es = s+f->nsubf;
	nf = 0;
	while(s < es){
		if(s->age){
			freesubfont(s->f);
			s->cf = nil;
			s->f = nil;
			s->age = 0;
			nf++;
		}
		s++;
	}
	return nf;
}
#endif

/* return whether resize succeeded && f->cache is unchanged */
static int
fontresize(Font *f, int wid, int ncache, int depth)
{
	Cacheinfo *i;
	int ret;
	Image *new;
	uchar *b;
	Display *d;

	ret = 0;
	if(depth <= 0)
		depth = 1;

	d = f->display;
	if(d == nil)
		goto Nodisplay;

	new = allocimage(d, Rect(0, 0, ncache*wid, f->height), CHAN1(CGrey, depth), 0, 0);
	if(new == nil){
		fprint(2, "font cache resize failed: %r\n");
		abort();
		goto Return;
	}
	flushimage(d, 0);	/* flush any pending errors */
	b = bufimage(d, 1+4+4+1);
	if(b == 0){
		freeimage(new);
		goto Return;
	}
	b[0] = 'i';
	BPLONG(b+1, new->id);
	BPLONG(b+5, ncache);
	b[9] = f->ascent;
	if(flushimage(d, 0) < 0){
		fprint(2, "resize: init failed: %r\n");
		freeimage(new);
		goto Return;
	}
	freeimage(f->cacheimage);
	f->cacheimage = new;
    Nodisplay:
	f->width = wid;
	f->maxdepth = depth;
	ret = 1;
	if(f->ncache != ncache){
		i = malloc(ncache*sizeof f->cache[0]);
		if(i != nil){
			ret = 0;
			free(f->cache);
			f->ncache = ncache;
			f->cache = i;
		}
		/* else just wipe the cache clean and things will be ok */
	}
    Return:
	memset(f->cache, 0, f->ncache*sizeof f->cache[0]);
	return ret;
}
