/*
 * pdf.c
 * 
 * pdf file support for page
 */

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

typedef struct PDFInfo	PDFInfo;
struct PDFInfo {
	GSInfo gs;
	Rectangle *pagebbox;
};

static Image*	pdfdrawpage(Document *d, int page);
static char*	pdfpagename(Document*, int);

char *pdfprolog = 
#include "pdfprolog.c"
	;

Rectangle
pdfbbox(GSInfo *gs)
{
	char *p;
	char *f[4];
	Rectangle r;
	
	r = Rect(0,0,0,0);
	waitgs(gs);
	gscmd(gs, "/CropBox knownoget {} {[0 0 0 0]} ifelse PAGE==\n");
	p = Brdline(&gs->gsrd, '\n');
	p[Blinelen(&gs->gsrd)-1] ='\0';
	if(p[0] != '[')
		return r;
	if(tokenize(p+1, f, 4) != 4)
		return r;
	r = Rect(atoi(f[0]), atoi(f[1]), atoi(f[2]), atoi(f[3]));
	waitgs(gs);
	return r;
}

Document*
initpdf(Biobuf *b, int argc, char **argv, uchar *buf, int nbuf)
{
	Document *d;
	PDFInfo *pdf;
	char *p;
	char *fn;
	char fdbuf[20];
	int fd;
	int i, npage;
	Rectangle bbox;

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

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

	/* sanity check */
	Bseek(b, 0, 0);
	if(!(p = Brdline(b, '\n')) && !(p = Brdline(b, '\r'))) {
		fprint(2, "cannot find end of first line\n");
		wexits("initps");
	}
	if(strncmp(p, "%PDF-", 5) != 0) {
		werrstr("not pdf");
		return nil;
	}

	/* setup structures so one free suffices */
	p = emalloc(sizeof(*d) + sizeof(*pdf));
	d = (Document*) p;
	p += sizeof(*d);
	pdf = (PDFInfo*) p;

	d->extra = pdf;
	d->b = b;
	d->drawpage = pdfdrawpage;
	d->pagename = pdfpagename;
	d->fwdonly = 0;

	if(spawngs(&pdf->gs, "-dDELAYSAFER") < 0)
		return nil;

	gscmd(&pdf->gs, "%s", pdfprolog);
	waitgs(&pdf->gs);

	setdim(&pdf->gs, Rect(0,0,0,0), ppi, 0);
	gscmd(&pdf->gs, "(%s) (r) file { DELAYSAFER { .setsafe } if } stopped pop pdfopen begin\n", fn);
	gscmd(&pdf->gs, "pdfpagecount PAGE==\n");
	p = Brdline(&pdf->gs.gsrd, '\n');
	npage = atoi(p);
	if(npage < 1) {
		fprint(2, "no pages?\n");
		return nil;
	}
	d->npage = npage;
	d->docname = argv[0];

	gscmd(&pdf->gs, "Trailer\n");
	bbox = pdfbbox(&pdf->gs);

	pdf->pagebbox = emalloc(sizeof(Rectangle)*npage);
	for(i=0; i<npage; i++) {
		gscmd(&pdf->gs, "%d pdfgetpage\n", i+1);
		pdf->pagebbox[i] = pdfbbox(pdf);
		if(Dx(pdf->pagebbox[i]) <= 0)
			pdf->pagebbox[i] = bbox;
	}
	return d;
}

static Image*
pdfdrawpage(Document *doc, int page)
{
	PDFInfo *pdf = doc->extra;
	Image *im;

	gscmd(&pdf->gs, "%d DoPDFPage\n", page+1);
	im = readimage(display, pdf->gs.gsdfd, 0);
	if(im == nil) {
		fprint(2, "fatal: readimage error %r\n");
		wexits("readimage");
	}
	waitgs(&pdf->gs);
	return im;
}

static char*
pdfpagename(Document *d, int page)
{
	static char str[15];
	
	USED(d);
	sprint(str, "p %d", page+1);
	return str;
}
