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

extern int	debug;
int	cflag = 0;
int	dflag = 0;
int	eflag = 0;
int	nineflag = 0;
int	threeflag = 0;
int	colorspace = CRGB;
int	output = 0;
ulong	outchan = CMAP8;
Image	*image;
int	defaultcolor = 1;

enum{
	Border	= 2,
	Edge	= 5
};

char	*show(int, char*, int);

void
eresized(int new)
{
	Rectangle r;

	if(new && getwindow(display, Refnone) < 0){
		fprint(2, "png: can't reattach to window\n");
		exits("resize");
	}
	if(image == nil)
		return;
	r = insetrect(screen->clipr, Edge+Border);
	r.max.x = r.min.x+Dx(image->r);
	r.max.y = r.min.y+Dy(image->r);
	border(screen, r, -Border, nil, ZP);
	draw(screen, r, image, nil, image->r.min);
	flushimage(display, 1);
}

void
main(int argc, char *argv[])
{
	int fd, i;
	char *err;
	char buf[12+1];

	ARGBEGIN{
	case 'c':		/* produce encoded, compressed, bitmap file; no display by default */
		cflag++;
		dflag++;
		output++;
		if(defaultcolor)
			outchan = CMAP8;
		break;
	case 'D':
		debug++;
		break;
	case 'd':		/* suppress display of image */
		dflag++;
		break;
	case 'e':		/* disable floyd-steinberg error diffusion */
		eflag++;
		break;
	case 'k':		/* force black and white */
		defaultcolor = 0;
		outchan = GREY8;
		break;
	case 'r':
		colorspace = CRGB;
		break;
	case '3':		/* produce encoded, compressed, three-color bitmap file; no display by default */
		threeflag++;
		/* fall through */
	case 't':		/* produce encoded, compressed, true-color bitmap file; no display by default */
		cflag++;
		dflag++;
		output++;
		defaultcolor = 0;
		outchan = RGB24;
		break;
	case 'v':		/* force RGBV */
		defaultcolor = 0;
		outchan = CMAP8;
		break;
	case '9':		/* produce plan 9, uncompressed, bitmap file; no display by default */
		nineflag++;
		dflag++;
		output++;
		if(defaultcolor)
			outchan = CMAP8;
		break;
	default:
		fprint(2, "usage: png -39cdekrtv [file.png ...]\n");
		exits("usage");
	}ARGEND;

	if(dflag==0 && colorspace==CYCbCr){	/* see if we should convert right to RGB */
		fd = open("/dev/screen", OREAD);
		if(fd > 0){
			buf[12] = '\0';
			if(read(fd, buf, 12)==12 && chantodepth(strtochan(buf))>8)
				colorspace = CRGB;
			close(fd);
		}
	}

	err = nil;
	if(argc == 0)
		err = show(0, "<stdin>", outchan);
	else{
		for(i=0; i<argc; i++){
			fd = open(argv[i], OREAD);
			if(fd < 0){
				fprint(2, "png: can't open %s: %r\n", argv[i]);
				err = "open";
			}else{
				err = show(fd, argv[i], outchan);
				close(fd);
			}
			if((nineflag || cflag) && argc>1 && err==nil){
				fprint(2, "png: exiting after one file\n");
				break;
			}
		}
	}
	exits(err);
}

char*
show(int fd, char *name, int outc)
{
	Rawimage **array, *r, *c;
	static int inited;
	Image *i;
	int j, ch, outchan;
	Biobuf b;
	char buf[32];

	if(Binit(&b, fd, OREAD) < 0)
		return nil;
	outchan = outc;
	array = Breadpng(&b, colorspace);
	if(array == nil || array[0]==nil){
		fprint(2, "png: decode %s failed: %r\n", name);
		return "decode";
	}
	Bterm(&b);

	r = array[0];
	if(!dflag && !inited){
		if(initdraw(0, 0, 0) < 0){
			fprint(2, "png: initdraw failed: %r\n");
			return "initdraw";
		}
		einit(Ekeyboard|Emouse);
		if(defaultcolor && screen->depth>8 && outchan==CMAP8)
			outchan = RGB24;
		inited++;
	}
	if(outchan == CMAP8)
		c = torgbv(r, !eflag);
	else{
		if(outchan==GREY8 || (r->chandesc==CY && threeflag==0)){
			c = totruecolor(r, CY);
			outchan = GREY8;
		}else
			c = totruecolor(r, CRGB24);
	}
	if(c == nil){
		fprint(2, "png: conversion of %s failed: %r\n", name);
		return "torgbv";
	}
	if(!dflag){
		if(c->chandesc == CY)
			i = allocimage(display, c->r, GREY8, 0, 0);
		else
			i = allocimage(display, c->r, outchan, 0, 0);
		if(i == nil){
			fprint(2, "png: allocimage %s failed: %r\n", name);
			return "allocimage";
		}
		if(loadimage(i, i->r, c->chans[0], c->chanlen) < 0){
			fprint(2, "png: loadimage %s failed: %r\n", name);
			return "loadimage";
		}
		image = i;
		eresized(0);
		if((ch=ekbd())=='q' || ch==0x7F || ch==0x04)
			exits(nil);
		draw(screen, screen->clipr, display->white, nil, ZP);
		image = nil;
		freeimage(i);
	}
	if(nineflag){
		chantostr(buf, outchan);
		print("%11s %11d %11d %11d %11d ", buf,
			c->r.min.x, c->r.min.y, c->r.max.x, c->r.max.y);
		if(write(1, c->chans[0], c->chanlen) != c->chanlen){
			fprint(2, "png: %s: write error %r\n", name);
			return "write";
		}
	}else if(cflag){
		if(writerawimage(1, c) < 0){
			fprint(2, "png: %s: write error: %r\n", name);
			return "write";
		}
	}
	for(j=0; j<r->nchans; j++)
		free(r->chans[j]);
	free(r->cmap);
	free(r);
	free(array);
	if(c){
		free(c->chans[0]);
		free(c);
	}
	return nil;
}
