#include <u.h>
#include <libc.h>
#include <bio.h>
#include <thread.h>
#include <plumb.h>
#include <9pclient.h> /* jpc */
#include "dat.h"

extern CFsys *acmefs; /* jpc */

Window*
newwindow(void)
{
	char buf[12];
	Window *w;
	int n = 0;

	w = emalloc(sizeof(Window));
/* jpc
	w->ctl = open("/mnt/wsys/new/ctl", ORDWR|OCEXEC);
	if(w->ctl<0 || read(w->ctl, buf, 12)!=12)
		error("can't open window ctl file: %r");
*/
/*	w->ctl = fsopenfd(acmefs, "new/ctl", ORDWR|OCEXEC);
	if(w->ctl<0 || (n = read(w->ctl, buf, 12))!=12) {
		fprint(2,"%d bytes read from %d\n",n,w->ctl);
		error("can't open window ctl file: %r");
	}
  jpc end */
	w->ctl = fsopen(acmefs, "new/ctl", ORDWR|OCEXEC);
	if(w->ctl == nil || (n = fsread(w->ctl, buf, 12))!=12) {
		fprint(2,"%d bytes read from %d\n",n,w->ctl);
		error("can't open window ctl file: %r");
	}

	ctlprint(w->ctl, "noscroll\n");
	w->id = atoi(buf);
	w->event = winopenfid(w, "event");
	w->addr = nil;	/* will be opened when needed */
	w->body = nil;
	w->data = nil;
	w->cevent = chancreate(sizeof(Event*), 0);
	return w;
}

void
winsetdump(Window *w, char *dir, char *cmd)
{
	if(dir != nil)
		ctlprint(w->ctl, "dumpdir %s\n", dir);
	if(cmd != nil)
		ctlprint(w->ctl, "dump %s\n", cmd);
}

void
wineventproc(void *v)
{
	Window *w;
	int i;

	w = v;
	for(i=0; ; i++){
		if(i >= NEVENT)
			i = 0;
		wingetevent(w, &w->e[i]);
		sendp(w->cevent, &w->e[i]);
	}
}

static CFid*
winopenfid1(Window *w, char *f, int m)
{
	char buf[64];
	CFid* fd;

	sprint(buf, "%d/%s", w->id, f);
	fd = fsopen(acmefs, buf, m|OCEXEC);
	if(fd == nil)
		error("can't open window file %s: %r", f);
	return fd;
}

static int
winopenfile1(Window *w, char *f, int m)
{
	char buf[64];
	int fd;

/* jpc
	sprint(buf, "/mnt/wsys/%d/%s", w->id, f);
	fd = open(buf, m|OCEXEC);
*/
	sprint(buf, "%d/%s", w->id, f);
	fd = fsopenfd(acmefs, buf, m|OCEXEC);
	if(fd < 0)
		error("can't open window file %s: %r", f);
	return fd;
}

CFid*
winopenfid(Window *w, char *f)
{
	return winopenfid1(w, f, ORDWR);
}

int
winopenfile(Window *w, char *f)
{
	return winopenfile1(w, f, ORDWR);
}

void
wintagwrite(Window *w, char *s, int n)
{
	CFid* fid;

	fid = winopenfid(w, "tag");
	if(fswrite(fid, s, n) != n)
		error("tag write: %r");
	fsclose(fid);
}

void
winname(Window *w, char *s)
{
	ctlprint(w->ctl, "name %s\n", s);
}

void
winopenbody(Window *w, int mode)
{
	char buf[256];
	CFid* fid;

/* jpc
	sprint(buf, "/mnt/wsys/%d/body", w->id);
	w->body = Bopen(buf, mode|OCEXEC);
*/
	sprint(buf, "%d/body", w->id);
	fid = fsopen(acmefs,buf, mode|OCEXEC);
	w->body = fid; // jpcBfdopen(id, mode|OCEXEC);
	if(w->body == nil)
		error("can't open window body file: %r");
}

void
winclosebody(Window *w)
{
	if(w->body != nil){
		// jpc Bterm(w->body);
		fsclose(w->body);
		w->body = nil;
	}
}

void
winwritebody(Window *w, char *s, int n)
{
	if(w->body == nil)
		winopenbody(w, OWRITE);
	// jpc if(Bwrite(w->body, s, n) != n)
	if(fswrite(w->body, s, n) != n)
		error("write error to window: %r");
}

int
wingetec(Window *w)
{
	if(w->nbuf == 0){
		w->nbuf = fsread(w->event, w->buf, sizeof w->buf);
		if(w->nbuf <= 0){
			/* probably because window has exited, and only called by wineventproc, so just shut down */
			threadexits(nil);
		}
		w->bufp = w->buf;
	}
	w->nbuf--;
	return *w->bufp++;
}

int
wingeten(Window *w)
{
	int n, c;

	n = 0;
	while('0'<=(c=wingetec(w)) && c<='9')
		n = n*10+(c-'0');
	if(c != ' ')
		error("event number syntax");
	return n;
}

int
wingeter(Window *w, char *buf, int *nb)
{
	Rune r;
	int n;

	r = wingetec(w);
	buf[0] = r;
	n = 1;
	if(r >= Runeself) {
		while(!fullrune(buf, n))
			buf[n++] = wingetec(w);
		chartorune(&r, buf);
	} 
	*nb = n;
	return r;
}

void
wingetevent(Window *w, Event *e)
{
	int i, nb;

	e->c1 = wingetec(w);
	e->c2 = wingetec(w);
	e->q0 = wingeten(w);
	e->q1 = wingeten(w);
	e->flag = wingeten(w);
	e->nr = wingeten(w);
	if(e->nr > EVENTSIZE)
		error("event string too long");
	e->nb = 0;
	for(i=0; i<e->nr; i++){
		e->r[i] = wingeter(w, e->b+e->nb, &nb);
		e->nb += nb;
	}
	e->r[e->nr] = 0;
	e->b[e->nb] = 0;
	if(wingetec(w) != '\n')
		error("event syntax error");
}

void
winwriteevent(Window *w, Event *e)
{
	fsprint(w->event, "%c%c%d %d\n", e->c1, e->c2, e->q0, e->q1);
}

void
winread(Window *w, uint q0, uint q1, char *data)
{
	int m, n, nr;
	char buf[256];

	if(w->addr == nil)
		w->addr = winopenfid(w, "addr");
	if(w->data == nil)
		w->data = winopenfid(w, "data");
	m = q0;
	while(m < q1){
		n = sprint(buf, "#%d", m);
		if(fswrite(w->addr, buf, n) != n)
			error("error writing addr: %r");
		n = fsread(w->data, buf, sizeof buf);
		if(n <= 0)
			error("reading data: %r");
		nr = utfnlen(buf, n);
		while(m+nr >q1){
			do; while(n>0 && (buf[--n]&0xC0)==0x80);
			--nr;
		}
		if(n == 0)
			break;
		memmove(data, buf, n);
		data += n;
		*data = 0;
		m += nr;
	}
}

void
windormant(Window *w)
{
	if(w->addr != nil){
		fsclose(w->addr);
		w->addr = nil;
	}
	if(w->body != nil){
		fsclose(w->body);
		w->body = nil;
	}
	if(w->data != nil){
		fsclose(w->data);
		w->data = nil;
	}
}


int
windel(Window *w, int sure)
{
	if(sure) {
		fswrite(w->ctl, "delete\n", 7);
		// fsync(w->ctl);
	}
	else if(fswrite(w->ctl, "del\n", 4) != 4) {
		// fsync(w->ctl);
		return 0;
	}
	/* event proc will die due to read error from event file */
	windormant(w);
	fsclose(w->ctl);
	w->ctl = nil;
	fsclose(w->event);
	w->event = nil;
	return 1;
}

void
winclean(Window *w)
{
	// int fd;
	// if(w->body)
	// 	Bflush(w->body);
	ctlprint(w->ctl, "clean\n");
}

int
winsetaddr(Window *w, char *addr, int errok)
{
	if(w->addr == nil)
		w->addr = winopenfid(w, "addr");
	if(fswrite(w->addr, addr, strlen(addr)) < 0){
		if(!errok)
			error("error writing addr(%s): %r", addr);
		return 0;
	}
	return 1;
}

int
winselect(Window *w, char *addr, int errok)
{
	if(winsetaddr(w, addr, errok)){
		ctlprint(w->ctl, "dot=addr\n");
		return 1;
	}
	return 0;
}

char*
winreadbody(Window *w, int *np)	/* can't use readfile because acme doesn't report the length */
{
	char *s;
	int m, na, n;

	if(w->body != nil)
		winclosebody(w);
	winopenbody(w, OREAD);
	s = nil;
	na = 0;
	n = 0;
	for(;;){
		if(na < n+512){
			na += 1024;
			s = realloc(s, na+1);
		}
		// jpc m = Bread(w->body, s+n, na-n);
		m = fsread(w->body, s+n, na-n);
		if(m <= 0)
			break;
		n += m;
	}
	s[n] = 0;
	winclosebody(w);
	*np = n;
	return s;
}

char*
winselection(Window *w)
{
	int m, n;
	char *buf;
	char tmp[256];
	CFid* fid;

	fid = winopenfid1(w, "rdsel", OREAD);
	if(fid == nil)
		error("can't open rdsel: %r");
	n = 0;
	buf = nil;
	for(;;){
		m = fsread(fid, tmp, sizeof tmp);
		if(m <= 0)
			break;
		buf = erealloc(buf, n+m+1);
		memmove(buf+n, tmp, m);
		n += m;
		buf[n] = '\0';
	}
	fsclose(fid);
	return buf;
}
