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

#include <u.h>
#include <libc.h>
#include <draw.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) < 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;
}
