#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(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 = malloc((f->nsubf+DSUBF)*sizeof *subf);
			if(f->subf == nil){
				f->subf = of;
				goto Toss;
			}
			memmove(f->subf, of, (f->nsubf+DSUBF)*sizeof *subf);
			memset(f->subf+f->nsubf, 0, DSUBF*sizeof *subf);
			subf = &f->subf[f->nsubf];
			f->nsubf += DSUBF;
			free(of);
		}
	}
	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;
}
