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

#include <u.h>
#include <libc.h>
#include <draw.h>
#include <cursor.h>
#include <thread.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, "/dev/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->gs);
		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 = convert(&pdf->gs.g);
	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;
}
