/*
 * ps.c
 * 
 * provide postscript file reading support for page
 */

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

typedef struct PSInfo	PSInfo;
typedef struct Page	Page;
	
struct Page {
	char *name;
	int offset;			/* offset of page beginning within file */
};

struct PSInfo {
	GSInfo gs;
	Rectangle bbox;	/* default bounding box */
	Page *page;
	int npage;
	int clueless;	/* don't know where page boundaries are */
	long psoff;	/* location of %! in file */
	char ctm[256];
};

static int	pswritepage(Document *d, int fd, int page);
static Image*	psdrawpage(Document *d, int page);
static char*	pspagename(Document*, int);

#define R(r) (r).min.x, (r).min.y, (r).max.x, (r).max.y
Rectangle
rdbbox(char *p)
{
	Rectangle r;
	int a;
	char *f[4];
	while(*p == ':' || *p == ' ' || *p == '\t')
		p++;
	if(tokenize(p, f, 4) != 4)
		return Rect(0,0,0,0);
	r = Rect(atoi(f[0]), atoi(f[1]), atoi(f[2]), atoi(f[3]));
	r = canonrect(r);
	if(Dx(r) <= 0 || Dy(r) <= 0)
		return Rect(0,0,0,0);

	if(truetoboundingbox)
		return r;

	/* initdraw not called yet, can't use %R */
	if(chatty) fprint(2, "[%d %d %d %d] -> ", R(r));
	/*
	 * attempt to sniff out A4, 8½×11, others
	 * A4 is 596×842
	 * 8½×11 is 612×792
	 */

	a = Dx(r)*Dy(r);
	if(a < 300*300){	/* really small, probably supposed to be */
		/* empty */
	} else if(Dx(r) <= 596 && r.max.x <= 596 && Dy(r) > 792 && Dy(r) <= 842 && r.max.y <= 842)	/* A4 */
		r = Rect(0, 0, 596, 842);
	else {	/* cast up to 8½×11 */
		if(Dx(r) <= 612 && r.max.x <= 612){
			r.min.x = 0;
			r.max.x = 612;
		}
		if(Dy(r) <= 792 && r.max.y <= 792){
			r.min.y = 0;
			r.max.y = 792;
		}
	}
	if(chatty) fprint(2, "[%d %d %d %d]\n", R(r));
	return r;
}

#define RECT(X) X.min.x, X.min.y, X.max.x, X.max.y

int
prefix(char *x, char *y)
{
	return strncmp(x, y, strlen(y)) == 0;
}

/*
 * document ps is really being printed as n-up pages.
 * we need to treat every n pages as 1.
 */
void
repaginate(PSInfo *ps, int n)
{
	int i, np, onp;
	Page *page;

	page = ps->page;
	onp = ps->npage;
	np = (ps->npage+n-1)/n;

	if(chatty) {
		for(i=0; i<=onp+1; i++)
			print("page %d: %d\n", i, page[i].offset);
	}

	for(i=0; i<np; i++)
		page[i] = page[n*i];

	/* trailer */
	page[np] = page[onp];

	/* EOF */
	page[np+1] = page[onp+1];

	ps->npage = np;

	if(chatty) {
		for(i=0; i<=np+1; i++)
			print("page %d: %d\n", i, page[i].offset);
	}

}

Document*
initps(Biobuf *b, int argc, char **argv, uchar *buf, int nbuf)
{
	Document *d;
	PSInfo *ps;
	char *p;
	char *q, *r;
	char eol;
	char *nargv[1];
	char fdbuf[20];
	char tmp[32];
	int fd;
	int i;
	int incomments;
	int cantranslate;
	int trailer=0;
	int nesting=0;
	int dumb=0;
	int landscape=0;
	long psoff;
	long npage, mpage;
	Page *page;
	Rectangle bbox = Rect(0,0,0,0);

	if(argc > 1) {
		fprint(2, "can only view one ps file at a time\n");
		return nil;
	}

	fprint(2, "reading through postscript...\n");
	if(b == nil){	/* standard input; spool to disk (ouch) */
		fd = spooltodisk(buf, nbuf, nil);
		sprint(fdbuf, "/fd/%d", fd);
		b = Bopen(fdbuf, OREAD);
		if(b == nil){
			fprint(2, "cannot open disk spool file\n");
			wexits("Bopen temp");
		}
		nargv[0] = fdbuf;
		argv = nargv;
	}

	/* find %!, perhaps after PCL nonsense */
	Bseek(b, 0, 0);
	psoff = 0;
	eol = 0;
	for(i=0; i<16; i++){
		psoff = Boffset(b);
		if(!(p = Brdline(b, eol='\n')) && !(p = Brdline(b, eol='\r'))) {
			fprint(2, "cannot find end of first line\n");
			wexits("initps");
		}
		if(p[0]=='\x1B')
			p++, psoff++;
		if(p[0] == '%' && p[1] == '!')
			break;
	}
	if(i == 16){
		werrstr("not ps");
		return nil;
	}

	/* page counting */
	npage = 0;
	mpage = 16;
	page = emalloc(mpage*sizeof(*page));
	memset(page, 0, mpage*sizeof(*page));

	cantranslate = goodps;
	incomments = 1;
Keepreading:
	while(p = Brdline(b, eol)) {
		if(p[0] == '%')
			if(chatty) fprint(2, "ps %.*s\n", utfnlen(p, Blinelen(b)-1), p);
		if(npage == mpage) {
			mpage *= 2;
			page = erealloc(page, mpage*sizeof(*page));
			memset(&page[npage], 0, npage*sizeof(*page));
		}

		if(p[0] != '%' || p[1] != '%')
			continue;

		if(prefix(p, "%%BeginDocument")) {
			nesting++;
			continue;
		}
		if(nesting > 0 && prefix(p, "%%EndDocument")) {
			nesting--;
			continue;
		}
		if(nesting)
			continue;

		if(prefix(p, "%%EndComment")) {
			incomments = 0;
			continue;
		}
		if(reverse == -1 && prefix(p, "%%PageOrder")) {
			/* glean whether we should reverse the viewing order */
			p[Blinelen(b)-1] = 0;
			if(strstr(p, "Ascend"))
				reverse = 0;
			else if(strstr(p, "Descend"))
				reverse = 1;
			else if(strstr(p, "Special"))
				dumb = 1;
			p[Blinelen(b)-1] = '\n';
			continue;
		} else if(prefix(p, "%%Trailer")) {
			incomments = 1;
			page[npage].offset = Boffset(b)-Blinelen(b);
			trailer = 1;
			continue;
		} else if(incomments && prefix(p, "%%Orientation")) {
			if(strstr(p, "Landscape"))
				landscape = 1;
		} else if(incomments && Dx(bbox)==0 && prefix(p, q="%%BoundingBox")) {
			bbox = rdbbox(p+strlen(q)+1);
			if(chatty)
				/* can't use %R because haven't initdraw() */
				fprint(2, "document bbox [%d %d %d %d]\n",
					RECT(bbox));
			continue;
		}

		/*
		 * If they use the initgraphics command, we can't play our translation tricks.
		 */
		p[Blinelen(b)-1] = 0;
		if((q=strstr(p, "initgraphics")) && ((r=strchr(p, '%'))==nil || r > q))
			cantranslate = 0;
		p[Blinelen(b)-1] = eol;

		if(!prefix(p, "%%Page:"))
			continue;

		/* 
		 * figure out of the %%Page: line contains a page number
		 * or some other page description to use in the menu bar.
		 * 
		 * lines look like %%Page: x y or %%Page: x
		 * we prefer just x, and will generate our
		 * own if necessary.
		 */
		p[Blinelen(b)-1] = 0;
		if(chatty) fprint(2, "page %s\n", p);
		r = p+7;
		while(*r == ' ' || *r == '\t')
			r++;
		q = r;
		while(*q && *q != ' ' && *q != '\t')
			q++;
		free(page[npage].name);
		if(*r) {
			if(*r == '"' && *q == '"')
				r++, q--;
			if(*q)
				*q = 0;
			page[npage].name = estrdup(r);
			*q = 'x';
		} else {
			snprint(tmp, sizeof tmp, "p %ld", npage+1);
			page[npage].name = estrdup(tmp);
		}

		/*
		 * store the offset info for later viewing
		 */
		trailer = 0;
		p[Blinelen(b)-1] = eol;
		page[npage++].offset = Boffset(b)-Blinelen(b);
	}
	if(Blinelen(b) > 0){
		fprint(2, "page: linelen %d\n", Blinelen(b));
		Bseek(b, Blinelen(b), 1);
		goto Keepreading;
	}

	if(Dx(bbox) == 0 || Dy(bbox) == 0)
		bbox = Rect(0,0,612,792);	/* 8½×11 */
	/*
	 * if we didn't find any pages, assume the document
	 * is one big page
	 */
	if(npage == 0) {
		dumb = 1;
		if(chatty) fprint(2, "don't know where pages are\n");
		reverse = 0;
		goodps = 0;
		trailer = 0;
		page[npage].name = "p 1";
		page[npage++].offset = 0;
	}

	if(npage+2 > mpage) {
		mpage += 2;
		page = erealloc(page, mpage*sizeof(*page));
		memset(&page[mpage-2], 0, 2*sizeof(*page));
	}

	if(!trailer)
		page[npage].offset = Boffset(b);

	Bseek(b, 0, 2); /* EOF */
	page[npage+1].offset = Boffset(b);

	d = emalloc(sizeof(*d));
	ps = emalloc(sizeof(*ps));
	ps->page = page;
	ps->npage = npage;
	ps->bbox = bbox;
	ps->psoff = psoff;

	d->extra = ps;
	d->npage = ps->npage;
	d->b = b;
	d->drawpage = psdrawpage;
	d->pagename = pspagename;

	d->fwdonly = ps->clueless = dumb;
	d->docname = argv[0];

	if(spawngs(&ps->gs, "-dSAFER") < 0)
		return nil;

	if(!cantranslate)
		bbox.min = ZP;
	setdim(&ps->gs, bbox, ppi, landscape);

	if(goodps){
		/*
		 * We want to only send the page (i.e. not header and trailer) information
	 	 * for each page, so initialize the device by sending the header now.
		 */
		pswritepage(d, ps->gs.gsfd, -1);
		waitgs(&ps->gs);
	}

	if(dumb) {
		fprint(ps->gs.gsfd, "(%s) run\n", argv[0]);
		fprint(ps->gs.gsfd, "(/fd/3) (w) file dup (THIS IS NOT A PLAN9 BITMAP 01234567890123456789012345678901234567890123456789\\n) writestring flushfile\n");
	}

	ps->bbox = bbox;

	return d;
}

static int
pswritepage(Document *d, int fd, int page)
{
	Biobuf *b = d->b;
	PSInfo *ps = d->extra;
	int t, n, i;
	long begin, end;
	char buf[8192];

	if(page == -1)
		begin = ps->psoff;
	else
		begin = ps->page[page].offset;

	end = ps->page[page+1].offset;

	if(chatty) {
		fprint(2, "writepage(%d)... from #%ld to #%ld...\n",
			page, begin, end);
	}
	Bseek(b, begin, 0);

	t = end-begin;
	n = sizeof(buf);
	if(n > t) n = t;
	while(t > 0 && (i=Bread(b, buf, n)) > 0) {
		if(write(fd, buf, i) != i)
			return -1;
		t -= i;
		if(n > t)
			n = t;
	}
	return end-begin;
}

static Image*
psdrawpage(Document *d, int page)
{
	PSInfo *ps = d->extra;
	Image *im;

	if(ps->clueless)
		return readimage(display, ps->gs.gsdfd, 0);

	waitgs(&ps->gs);

	if(goodps)
		pswritepage(d, ps->gs.gsfd, page);
	else {
		pswritepage(d, ps->gs.gsfd, -1);
		pswritepage(d, ps->gs.gsfd, page);
		pswritepage(d, ps->gs.gsfd, d->npage);
	}
	/*
	 * If last line terminator is \r, gs will read ahead to check for \n
	 * so send one to avoid deadlock.
	 */
	write(ps->gs.gsfd, "\n", 1);
	im = readimage(display, ps->gs.gsdfd, 0);
	if(im == nil) {
		fprint(2, "fatal: readimage error %r\n");
		wexits("readimage");
	}
	waitgs(&ps->gs);

	return im;
}

static char*
pspagename(Document *d, int page)
{
	PSInfo *ps = (PSInfo *) d->extra;
	return ps->page[page].name;
}
