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

int resizing;
int mknewwindow;
int doabort;
int chatty;
int reverse = -1;
int goodps = 1;
int ppi = 100;
int teegs = 0;
int truetoboundingbox;
int textbits=4, gfxbits=4;
int stdinfd;
int truecolor;
int imagemode;
int notewatcher;
int notegp;

int
watcher(void *v, char *x)
{
	USED(v);
	if(strcmp(x, "die") != 0)
		postnote(PNGROUP, notegp, x);
	threadexitsall(0);
	return 0;
}

int
bell(void *u, char *x)
{
	if(x && strcmp(x, "hangup") == 0)
		threadexitsall(0);

	if(x && strstr(x, "die") == nil)
		fprint(2, "postnote %d: %s\n", getpid(), x);

	/* alarms come from the gs monitor */
	if(x && strstr(x, "alarm")){
		postnote(PNGROUP, getpid(), "die (gs error)");
		postnote(PNPROC, notewatcher, "die (gs error)");
	}

	/* function mentions u so that it's in the stack trace */
	if((u == nil || u != x) && doabort)
		abort();

/*	fprint(2, "exiting %d\n", getpid()); */
	wexits("note");
	return 0;
}

static int
afmt(Fmt *fmt)
{
	char *s;

	s = va_arg(fmt->args, char*);
	if(s == nil || s[0] == '\0')
		return fmtstrcpy(fmt, "");
	else
		return fmtprint(fmt, "%#q", s);
}

void
usage(void)
{
	fprint(2, "usage: page [-biRrw] [-p ppi] file...\n");
	wexits("usage");
}

void
threadmain(int argc, char **argv)
{
	Document *doc;
	Biobuf *b;
	char *basename = argv[0];
	enum { Ninput = 16 };
	uchar buf[Ninput+1];
	int readstdin;

	ARGBEGIN{
	/* "temporary" debugging options */
	case 'P':
		goodps = 0;
		break;
	case 'v':
		chatty++;
		break;
	case 'V':
		teegs++;
		break;
	case 'a':
		doabort++;
		break;
	case 'T':
		textbits = atoi(EARGF(usage()));
		gfxbits = atoi(EARGF(usage()));
		break;

	/* real options */
	case 'R':
		resizing = 1;
		break;
	case 'r':
		reverse = 1;
		break;
	case 'p':
		ppi = atoi(EARGF(usage()));
		break;
	case 'b':
		truetoboundingbox = 1;
		break;
	case 'w':
		fprint(2, "%s: -w has only the effect of -R X11 systems\n", basename);
		resizing = 1;
		break;
	case 'i':
		imagemode = 1;
		break;
	default:
		usage();
	}ARGEND;

	notegp = getpid();

	switch(notewatcher = fork()){
	case -1:
		sysfatal("fork\n");
		threadexitsall(0);
	default:
		break;
	case 0:
		atnotify(watcher, 1);
		for(;;)
			sleep(1000);
		/* not reached */
	}

	rfork(RFNOTEG);
	atnotify(bell, 1);

	readstdin = 0;
	if(imagemode == 0 && argc == 0){
		readstdin = 1;
		stdinfd = dup(0, -1);
		close(0);
		open("/dev/tty", OREAD);
	}

	quotefmtinstall();
	fmtinstall('a', afmt);

	fmtinstall('R', Rfmt);
	fmtinstall('P', Pfmt);
	/*
	if(mknewwindow)
		newwin(); */

	if(readstdin){
		b = nil;
		if(readn(stdinfd, buf, Ninput) != Ninput){
			fprint(2, "page: short read reading %s\n", argv[0]);
			wexits("read");
		}
	}else if(argc != 0){
		if(!(b = Bopen(argv[0], OREAD))) {
			fprint(2, "page: cannot open \"%s\"\n", argv[0]);
			wexits("open");
		}	

		if(Bread(b, buf, Ninput) != Ninput) {
			fprint(2, "page: short read reading %s\n", argv[0]);
			wexits("read");
		}
	}else
		b = nil;

	buf[Ninput] = '\0';
	if(imagemode)
		doc = initgfx(nil, 0, nil, nil, 0);
	else if(strncmp((char*)buf, "%PDF-", 5) == 0)
		doc = initpdf(b, argc, argv, buf, Ninput);
	else if(strncmp((char*)buf, "\x04%!", 2) == 0)
		doc = initps(b, argc, argv, buf, Ninput);
	else if(buf[0] == '\x1B' && strstr((char*)buf, "@PJL"))
		doc = initps(b, argc, argv, buf, Ninput);
	else if(strncmp((char*)buf, "%!", 2) == 0)
		doc = initps(b, argc, argv, buf, Ninput);
	else if(strcmp((char*)buf, "\xF7\x02\x01\x83\x92\xC0\x1C;") == 0)
		doc = initdvi(b, argc, argv, buf, Ninput);
	else if(strncmp((char*)buf, "\xD0\xCF\x11\xE0\xA1\xB1\x1A\xE1", 8) == 0)
		doc = initmsdoc(b, argc, argv, buf, Ninput);
	else if(strncmp((char*)buf, "x T ", 4) == 0)
		doc = inittroff(b, argc, argv, buf, Ninput);
	else {
		if(ppi != 100) {
			fprint(2, "page: you can't specify -p with graphic files\n");
			wexits("-p and graphics");
		}
		doc = initgfx(b, argc, argv, buf, Ninput);
	}

	if(doc == nil) {
		fprint(2, "page: error reading file: %r\n");
		wexits("document init");
	}

	if(doc->npage < 1 && !imagemode) {
		fprint(2, "page: no pages found?\n");
		wexits("pagecount");
	}

	if(reverse == -1) /* neither cmdline nor ps reader set it */
		reverse = 0;

	if(initdraw(0, 0, "page") < 0){
		fprint(2, "page: initdraw failed: %r\n");
		wexits("initdraw");
	}
	truecolor = screen->depth > 8;
	viewer(doc);
	wexits(0);
}

void
wexits(char *s)
{
	if(s && *s && strcmp(s, "note") != 0 && mknewwindow)
		sleep(10*1000);
	postnote(PNPROC, notewatcher, "die");
	postnote(PNGROUP, getpid(), "die");
	threadexitsall(s);
}
