#include <u.h>
#include <libc.h>
#include <draw.h>
#include <thread.h>
#include <cursor.h>
#include <mouse.h>
#include <keyboard.h>
#include <frame.h>
#include <fcall.h>
#include <plumb.h>
#include "dat.h"
#include "fns.h"

static	Point		prevmouse;
static	Window	*mousew;

Range
range(int q0, int q1)
{
	Range r;

	r.q0 = q0;
	r.q1 = q1;
	return r;
}

Runestr
runestr(Rune *r, uint n)
{
	Runestr rs;

	rs.r = r;
	rs.nr = n;
	return rs;
}

void
cvttorunes(char *p, int n, Rune *r, int *nb, int *nr, int *nulls)
{
	uchar *q;
	Rune *s;
	int j, w;

	/*
	 * Always guaranteed that n bytes may be interpreted
	 * without worrying about partial runes.  This may mean
	 * reading up to UTFmax-1 more bytes than n; the caller
	 * knows this.  If n is a firm limit, the caller should
	 * set p[n] = 0.
	 */
	q = (uchar*)p;
	s = r;
	for(j=0; j<n; j+=w){
		if(*q < Runeself){
			w = 1;
			*s = *q++;
		}else{
			w = chartorune(s, (char*)q);
			q += w;
		}
		if(*s)
			s++;
		else if(nulls)
			*nulls = TRUE;
	}
	*nb = (char*)q-p;
	*nr = s-r;
}

void
error(char *s)
{
	fprint(2, "acme: %s: %r\n", s);
	abort();
}

Window*
errorwin1(Rune *dir, int ndir, Rune **incl, int nincl)
{
	Window *w;
	Rune *r;
	int i, n;
	static Rune Lpluserrors[] = { '+', 'E', 'r', 'r', 'o', 'r', 's', 0 };

	r = runemalloc(ndir+8);
	if((n = ndir) != 0){
		runemove(r, dir, ndir);
		r[n++] = L'/';
	}
	runemove(r+n, Lpluserrors, 7);
	n += 7;
	w = lookfile(r, n);
	if(w == nil){
		if(row.ncol == 0)
			if(rowadd(&row, nil, -1) == nil)
				error("can't create column to make error window");
		w = coladd(row.col[row.ncol-1], nil, nil, -1);
		w->filemenu = FALSE;
		winsetname(w, r, n);
	}
	free(r);
	for(i=nincl; --i>=0; ){
		n = runestrlen(incl[i]);
		r = runemalloc(n);
		runemove(r, incl[i], n);
		winaddincl(w, r, n);
	}
	w->autoindent = globalautoindent;
	return w;
}

/* make new window, if necessary; return with it locked */
Window*
errorwin(Mntdir *md, int owner)
{
	Window *w;

	for(;;){
		if(md == nil)
			w = errorwin1(nil, 0, nil, 0);
		else
			w = errorwin1(md->dir, md->ndir, md->incl, md->nincl);
		winlock(w, owner);
		if(w->col != nil)
			break;
		/* window was deleted too fast */
		winunlock(w);
	}
	return w;
}

typedef struct Warning Warning;

struct Warning{
	Mntdir *md;
	Buffer buf;
	Warning *next;
};

static Warning *warnings;

static
void
addwarningtext(Mntdir *md, Rune *r, int nr)
{
	Warning *warn;
	
	for(warn = warnings; warn; warn=warn->next){
		if(warn->md == md){
			bufinsert(&warn->buf, warn->buf.nc, r, nr);
			return;
		}
	}
	warn = emalloc(sizeof(Warning));
	warn->next = warnings;
	warn->md = md;
	if(md)
		fsysincid(md);
	warnings = warn;
	bufinsert(&warn->buf, 0, r, nr);
	nbsendp(cwarn, 0);
}

/* called while row is locked */
void
flushwarnings(void)
{
	Warning *warn, *next;
	Window *w;
	Text *t;
	int owner, nr, q0, n;
	Rune *r;

	for(warn=warnings; warn; warn=next) {
		w = errorwin(warn->md, 'E');
		t = &w->body;
		owner = w->owner;
		if(owner == 0)
			w->owner = 'E';
		wincommit(w, t);
		/*
		 * Most commands don't generate much output. For instance,
		 * Edit ,>cat goes through /dev/cons and is already in blocks
		 * because of the i/o system, but a few can.  Edit ,p will
		 * put the entire result into a single hunk.  So it's worth doing
		 * this in blocks (and putting the text in a buffer in the first
		 * place), to avoid a big memory footprint.
		 */
		r = fbufalloc();
		q0 = t->file->b.nc;
		for(n = 0; n < warn->buf.nc; n += nr){
			nr = warn->buf.nc - n;
			if(nr > RBUFSIZE)
				nr = RBUFSIZE;
			bufread(&warn->buf, n, r, nr);
			textbsinsert(t, t->file->b.nc, r, nr, TRUE, &nr);
		}
		textshow(t, q0, t->file->b.nc, 1);
		free(r);
		winsettag(t->w);
		textscrdraw(t);
		w->owner = owner;
		w->dirty = FALSE;
		winunlock(w);
		bufclose(&warn->buf);
		next = warn->next;
		if(warn->md)
			fsysdelid(warn->md);
		free(warn);
	}
	warnings = nil;
}

void
warning(Mntdir *md, char *s, ...)
{
	Rune *r;
	va_list arg;

	va_start(arg, s);
	r = runevsmprint(s, arg);
	va_end(arg);
	if(r == nil)
		error("runevsmprint failed");
	addwarningtext(md, r, runestrlen(r));
}

int
runeeq(Rune *s1, uint n1, Rune *s2, uint n2)
{
	if(n1 != n2)
		return FALSE;
	return memcmp(s1, s2, n1*sizeof(Rune)) == 0;
}

uint
min(uint a, uint b)
{
	if(a < b)
		return a;
	return b;
}

uint
max(uint a, uint b)
{
	if(a > b)
		return a;
	return b;
}

char*
runetobyte(Rune *r, int n)
{
	char *s;

	if(r == nil)
		return nil;
	s = emalloc(n*UTFmax+1);
	setmalloctag(s, getcallerpc(&r));
	snprint(s, n*UTFmax+1, "%.*S", n, r);
	return s;
}

Rune*
bytetorune(char *s, int *ip)
{
	Rune *r;
	int nb, nr;

	nb = strlen(s);
	r = runemalloc(nb+1);
	cvttorunes(s, nb, r, &nb, &nr, nil);
	r[nr] = '\0';
	*ip = nr;
	return r;
}

int
isalnum(Rune c)
{
	/*
	 * Hard to get absolutely right.  Use what we know about ASCII
	 * and assume anything above the Latin control characters is
	 * potentially an alphanumeric.
	 */
	if(c <= ' ')
		return FALSE;
	if(0x7F<=c && c<=0xA0)
		return FALSE;
	if(utfrune("!\"#$%&'()*+,-./:;<=>?@[\\]^`{|}~", c))
		return FALSE;
	return TRUE;
}

int
rgetc(void *v, uint n)
{
	return ((Rune*)v)[n];
}

int
tgetc(void *a, uint n)
{
	Text *t;

	t = a;
	if(n >= t->file->b.nc)
		return 0;
	return textreadc(t, n);
}

Rune*
skipbl(Rune *r, int n, int *np)
{
	while(n>0 && (*r==' ' || *r=='\t' || *r=='\n')){
		--n;
		r++;
	}
	*np = n;
	return r;
}

Rune*
findbl(Rune *r, int n, int *np)
{
	while(n>0 && *r!=' ' && *r!='\t' && *r!='\n'){
		--n;
		r++;
	}
	*np = n;
	return r;
}

void
savemouse(Window *w)
{
	prevmouse = mouse->xy;
	mousew = w;
}

void
restoremouse(Window *w)
{
	if(mousew!=nil && mousew==w)
		moveto(mousectl, prevmouse);
	mousew = nil;
}

void
clearmouse()
{
	mousew = nil;
}

char*
estrdup(char *s)
{
	char *t;

	t = strdup(s);
	if(t == nil)
		error("strdup failed");
	setmalloctag(t, getcallerpc(&s));
	return t;
}

void*
emalloc(uint n)
{
	void *p;

	p = malloc(n);
	if(p == nil){
		fprint(2, "allocating %d from %lux: %r\n", n, getcallerpc(&n));
		*(int*)0=0;
		error("malloc failed");
	}
	setmalloctag(p, getcallerpc(&n));
	memset(p, 0, n);
	return p;
}

void*
erealloc(void *p, uint n)
{
	p = realloc(p, n);
	if(p == nil){
		fprint(2, "reallocating %d: %r\n", n);
		error("realloc failed");
	}
	setmalloctag(p, getcallerpc(&n));
	return p;
}

/*
 * Heuristic city.
 */
Window*
makenewwindow(Text *t)
{
	Column *c;
	Window *w, *bigw, *emptyw;
	Text *emptyb;
	int i, y, el;

	if(activecol)
		c = activecol;
	else if(seltext && seltext->col)
		c = seltext->col;
	else if(t && t->col)
		c = t->col;
	else{
		if(row.ncol==0 && rowadd(&row, nil, -1)==nil)
			error("can't make column");
		c = row.col[row.ncol-1];
	}
	activecol = c;
	if(t==nil || t->w==nil || c->nw==0)
		return coladd(c, nil, nil, -1);

	/* find biggest window and biggest blank spot */
	emptyw = c->w[0];
	bigw = emptyw;
	for(i=1; i<c->nw; i++){
		w = c->w[i];
		/* use >= to choose one near bottom of screen */
		if(w->body.fr.maxlines >= bigw->body.fr.maxlines)
			bigw = w;
		if(w->body.fr.maxlines-w->body.fr.nlines >= emptyw->body.fr.maxlines-emptyw->body.fr.nlines)
			emptyw = w;
	}
	emptyb = &emptyw->body;
	el = emptyb->fr.maxlines-emptyb->fr.nlines;
	/* if empty space is big, use it */
	if(el>15 || (el>3 && el>(bigw->body.fr.maxlines-1)/2))
		y = emptyb->fr.r.min.y+emptyb->fr.nlines*font->height;
	else{
		/* if this window is in column and isn't much smaller, split it */
		if(t->col==c && Dy(t->w->r)>2*Dy(bigw->r)/3)
			bigw = t->w;
		y = (bigw->r.min.y + bigw->r.max.y)/2;
	}
	w = coladd(c, nil, nil, y);
	if(w->body.fr.maxlines < 2)
		colgrow(w->col, w, 1);
	return w;
}
