#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;
	int ppi;
};

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;
	int ppi = 100;
	PDFInfo *pdf;
	PSInfo *ps;

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

	if (doc->type == Tpdf){
		pdf = (PDFInfo *) doc->extra;
		ppi = pdf->gs.ppi;
	}
	else{
		if (doc->type == Tps){
			ps = (PSInfo *) doc->extra;
			ppi = ps->gs.ppi;
		}
	}

Again:
	for(i=0; i<nelem(cache); i++){
		c = &cache[i];
		if(c->doc == doc && c->angle == angle && c->page == page && c->ppi == ppi){
			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;
	c->ppi = -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;
	c->ppi = ppi;

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;
}
