#include <u.h>
#include <libc.h>
#include <draw.h>
#include <cursor.h>
#include <event.h>
#include <bio.h>
#include <plumb.h>
#include <ctype.h>
#include <keyboard.h>
#include <thread.h>
#include "page.h"

typedef struct Cached Cached;
struct Cached
{
	Document *doc;
	int page;
	int angle;
	Image *im;
};

static Cached cache[5];
static int rabusy;

static Image*
questionmark(void)
{
	static Image *im;

	if(im)
		return im;	
	im = xallocimage(display, Rect(0,0,50,50), GREY1, 1, DBlack);
	if(im == nil)
		return nil;
	string(im, ZP, display->white, ZP, display->defaultfont, "?");
	return im;
}

void
cacheflush(void)
{
	int i;
	Cached *c;

	for(i=0; i<nelem(cache); i++){
		c = &cache[i];
		if(c->im)
			freeimage(c->im);
		c->im = nil;
		c->doc = nil;
	}
}

static Image*
_cachedpage(Document *doc, int angle, int page, char *ra)
{
	int i;
	Cached *c, old;
	Image *im, *tmp;

	if((page < 0 || page >= doc->npage) && !doc->fwdonly)
		return nil;

Again:
	for(i=0; i<nelem(cache); i++){
		c = &cache[i];
		if(c->doc == doc && c->angle == angle && c->page == page){
			if(chatty) fprint(2, "cache%s hit %d\n", ra, page);
			goto Found;
		}
		if(c->doc == nil)
			break;
	}

	if(i >= nelem(cache))
		i = nelem(cache)-1;
	c = &cache[i];
	if(c->im)
		freeimage(c->im);
	c->im = nil;
	c->doc = nil;
	c->page = -1;

	if(chatty) fprint(2, "cache%s load %d\n", ra, page);
	im = doc->drawpage(doc, page);
	if(im == nil){
		if(doc->fwdonly)	/* end of file */
			wexits(0);
		im = questionmark();
		if(im == nil){
		Flush:
			if(i > 0){
				cacheflush();
				goto Again;
			}
			fprint(2, "out of memory: %r\n");
			wexits("memory");
		}
		return im;
	}

	if(im->r.min.x != 0 || im->r.min.y != 0){
		/* translate to 0,0 */
		tmp = xallocimage(display, Rect(0, 0, Dx(im->r), Dy(im->r)), im->chan, 0, DNofill);
		if(tmp == nil){
			freeimage(im);
			goto Flush;
		}
		drawop(tmp, tmp->r, im, nil, im->r.min, S);
		freeimage(im);
		im = tmp;
	}

	switch(angle){
	case 90:
		im = rot90(im);
		break;
	case 180:
		rot180(im);
		break;
	case 270:
		im = rot270(im);
		break;
	}
	if(im == nil)
		goto Flush;

	c->doc = doc;
	c->page = page;
	c->angle = angle;
	c->im = im;

Found:
	if(chatty) fprint(2, "cache%s mtf %d @%d:", ra, c->page, i);
	old = *c;
	memmove(cache+1, cache, (c-cache)*sizeof cache[0]);
	cache[0] = old;
	if(chatty){
		for(i=0; i<nelem(cache); i++)
			fprint(2, " %d", cache[i].page);
		fprint(2, "\n");
	}
	if(chatty) fprint(2, "cache%s return %d %p\n", ra, old.page, old.im);
	return old.im;
}

static void
raproc(void *a)
{
	Cached *c;
	
	c = a;
	lockdisplay(display);
	_cachedpage(c->doc, c->angle, c->page, "-ra");
	rabusy = 0;
	unlockdisplay(display);
	free(c);
	threadexits(0);
}

Image*
cachedpage(Document *doc, int angle, int page)
{
	static int lastpage = -1;
	Cached *c;
	Image *im;
	int ra;
	
	if(doc->npage < 1)
		return display->white;

	im = _cachedpage(doc, angle, page, "");
	if(im == nil)
		return nil;

	/* readahead */
	ra = -1;
	if(!rabusy){
		if(page == lastpage+1)
			ra = page+1;
		else if(page == lastpage-1)
			ra = page-1;
	}
	lastpage = page;
	if(ra >= 0){
		c = emalloc(sizeof(*c));
		c->doc = doc;
		c->angle = angle;
		c->page = ra;
		c->im = nil;
		rabusy = 1;
		if(proccreate(raproc, c, mainstacksize) == -1)
			rabusy = 0;
	}
	return im;
}
