/*
 * graphics file reading for page
 */

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

typedef struct Convert	Convert;
typedef struct GfxInfo	GfxInfo;

struct Convert {
	char *name;
	char *cmd;
	char *truecmd;	/* cmd for true color */
};

struct GfxInfo {
	Graphic *g;
};

/*
 * N.B. These commands need to read stdin if %a is replaced
 * with an empty string.
 */
Convert cvt[] = {
	{ "plan9",	"fb/3to1 rgbv %a |fb/pcp -tplan9" },
	{ "tiff",	"fb/tiff2pic %a | fb/3to1 rgbv | fb/pcp -tplan9" },
	{ "plan9bm",	nil },
	{ "jpeg",	"jpg -9 %a", "jpg -t9 %a" },
	{ "gif",	"gif -9 %a", "gif -t9 %a" },
	{ "inferno",	nil },
	{ "fax",	"aux/g3p9bit -g %a" },
	{ "unknown",	"fb/cvt2pic %a |fb/3to1 rgbv" },
	{ "ppm",	"ppm -9 %a", "ppm -t9 %a" },
/* ``temporary'' hack for hobby */
	{ "ccitt-g4",	"cat %a|rx nslocum /usr/lib/ocr/bin/bcp -M|fb/pcp -tcompressed -l0" },
	{ "png",	"png -9 %a", "png -t9 %a" },
	{ "yuv",	"yuv -9 %a", "yuv -t9 %a"  },
	{ "bmp",	"bmp -9 %a", "bmp -t9 %a"  },
};

static Image*	gfxdrawpage(Document *d, int page);
static char*	gfxpagename(Document*, int);
static int	spawnrc(char*, Graphic*);
//static void	waitrc(void);
//static int	spawnpost(int);
static int	addpage(Document*, char*);
static int	rmpage(Document*, int);
static int	genaddpage(Document*, char*, uchar*, int);

static char*
gfxpagename(Document *doc, int page)
{
	GfxInfo *gfx = doc->extra;
	return gfx->g[page].name;
}

static Image*
gfxdrawpage(Document *doc, int page)
{
	GfxInfo *gfx = doc->extra;
	return convert(gfx->g+page);
}

Document*
initgfx(Biobuf *b, int argc, char **argv, uchar *buf, int nbuf)
{
	GfxInfo *gfx;
	Document *doc;
	int i;

	USED(b);

	doc = emalloc(sizeof(*doc));
	gfx = emalloc(sizeof(*gfx));
	gfx->g = nil;
	
	doc->npage = 0;
	doc->drawpage = gfxdrawpage;
	doc->pagename = gfxpagename;
	doc->addpage = addpage;
	doc->rmpage = rmpage;
	doc->extra = gfx;
	doc->fwdonly = 0;

	fprint(2, "reading through graphics...\n");
	if(argc==0 && buf)
		genaddpage(doc, nil, buf, nbuf);
	else{
		for(i=0; i<argc; i++)
			if(addpage(doc, argv[i]) < 0)
				fprint(2, "warning: not including %s: %r\n", argv[i]);
	}

	return doc;
}

static int
genaddpage(Document *doc, char *name, uchar *buf, int nbuf)
{
	Graphic *g;
	GfxInfo *gfx;
	Biobuf *b;
	uchar xbuf[32];
	int i, l;

	l = 0;
	gfx = doc->extra;

	assert((name == nil) ^ (buf == nil));
	assert(name != nil || doc->npage == 0);

	for(i=0; i<doc->npage; i++)
		if(strcmp(gfx->g[i].name, name) == 0)
			return i;

	if(name){
		l = strlen(name);
		if((b = Bopen(name, OREAD)) == nil) {
			werrstr("Bopen: %r");
			return -1;
		}

		if(Bread(b, xbuf, sizeof xbuf) != sizeof xbuf) {
			werrstr("short read: %r");
			return -1;
		}
		Bterm(b);
		buf = xbuf;
		nbuf = sizeof xbuf;
	}


	gfx->g = erealloc(gfx->g, (doc->npage+1)*(sizeof(*gfx->g)));
	g = &gfx->g[doc->npage];

	memset(g, 0, sizeof *g);
	if(memcmp(buf, "GIF", 3) == 0)
		g->type = Igif;
	else if(memcmp(buf, "\111\111\052\000", 4) == 0) 
		g->type = Itiff;
	else if(memcmp(buf, "\115\115\000\052", 4) == 0)
		g->type = Itiff;
	else if(memcmp(buf, "\377\330\377", 3) == 0)
		g->type = Ijpeg;
	else if(memcmp(buf, "\211PNG\r\n\032\n", 3) == 0)
		g->type = Ipng;
	else if(memcmp(buf, "compressed\n", 11) == 0)
		g->type = Iinferno;
	else if(memcmp(buf, "\0PC Research, Inc", 17) == 0)
		g->type = Ifax;
	else if(memcmp(buf, "TYPE=ccitt-g31", 14) == 0)
		g->type = Ifax;
	else if(memcmp(buf, "II*", 3) == 0)
		g->type = Ifax;
	else if(memcmp(buf, "TYPE=ccitt-g4", 13) == 0)
		g->type = Iccittg4;
	else if(memcmp(buf, "TYPE=", 5) == 0)
		g->type = Ipic;
	else if(buf[0] == 'P' && '0' <= buf[1] && buf[1] <= '9')
		g->type = Ippm;
	else if(memcmp(buf, "BM", 2) == 0)
		g->type = Ibmp;
	else if(memcmp(buf, "          ", 10) == 0 &&
		'0' <= buf[10] && buf[10] <= '9' &&
		buf[11] == ' ')
		g->type = Iplan9bm;
	else if(strtochan((char*)buf) != 0)
		g->type = Iplan9bm;
	else if (l > 4 && strcmp(name + l -4, ".yuv") == 0)
		g->type = Iyuv;
	else
		g->type = Icvt2pic;

	if(name){
		g->name = estrdup(name);
		g->fd = -1;
	}else{
		g->name = estrdup("stdin");	/* so it can be freed */
		g->fd = stdinpipe(buf, nbuf);
	}

	if(chatty) fprint(2, "classified \"%s\" as \"%s\"\n", g->name, cvt[g->type].name);
	return doc->npage++;
}

static int 
addpage(Document *doc, char *name)
{
	return genaddpage(doc, name, nil, 0);
}

static int
rmpage(Document *doc, int n)
{
	int i;
	GfxInfo *gfx;

	if(n < 0 || n >= doc->npage)
		return -1;

	gfx = doc->extra;
	doc->npage--;
	free(gfx->g[n].name);

	for(i=n; i<doc->npage; i++)
		gfx->g[i] = gfx->g[i+1];

	if(n < doc->npage)
		return n;
	if(n == 0)
		return 0;
	return n-1;
}


Image*
convert(Graphic *g)
{
	int fd;
	Convert c;
	char *cmd;
	char *name, buf[1000];
	Image *im;
	int rcspawned = 0;

	c = cvt[g->type];
	if(c.cmd == nil) {
		if(chatty) fprint(2, "no conversion for bitmap \"%s\"...\n", g->name);
		if(g->fd < 0){	/* not stdin */
			fd = open(g->name, OREAD);
			if(fd < 0) {
				fprint(2, "cannot open file: %r\n");
				wexits("open");
			}
		}else
			fd = g->fd;
	} else {
		cmd = c.cmd;
		if(truecolor && c.truecmd)
			cmd = c.truecmd;

		if(g->fd >= 0)	/* is pipe */
			name = "";
		else
			name = g->name;
		if(strlen(cmd)+strlen(name) > sizeof buf) {
			fprint(2, "command too long\n");
			wexits("convert");
		}
		snprint(buf, sizeof buf, cmd, name);
		if(chatty) fprint(2, "using \"%s\" to convert \"%s\"...\n", buf, g->name);
		fd = spawnrc(buf, g);
		rcspawned++;
		if(fd < 0) {
			fprint(2, "cannot spawn converter: %r\n");
			wexits("convert");
		}	
	}

	im = readimage(display, fd, 0);
	if(im == nil) {
		fprint(2, "warning: couldn't read image: %r\n");
	}

	close(fd);
	return im;
}

static int
spawnrc(char *cmd, Graphic *g)
{
	int pfd[2];
	int fd[3];

	if(chatty) fprint(2, "spawning(%s)...", cmd);

	if(pipe(pfd) < 0)
		return -1;

	if(g->fd > 0)
		fd[0] = dup(g->fd, -1);
	else
		fd[0] = open("/dev/null", OREAD);
	fd[1] = pfd[1];
	fd[2] = dup(2, -1);

	if(threadspawnl(fd, "rc", "rc", "-c", cmd, nil) == -1)
		return -1;

	return pfd[0];
}
