#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 Rune Lheader[] = {
	'N', 'e', 'w', ' ',
	'C', 'u', 't', ' ',
	'P', 'a', 's', 't', 'e', ' ',
	'S', 'n', 'a', 'r', 'f', ' ',
	'S', 'o', 'r', 't', ' ',
	'Z', 'e', 'r', 'o', 'x', ' ',
	'D', 'e', 'l', 'c', 'o', 'l', ' ',
	0
};

void
colinit(Column *c, Rectangle r)
{
	Rectangle r1;
	Text *t;

	draw(screen, r, display->white, nil, ZP);
	c->r = r;
	c->w = nil;
	c->nw = 0;
	t = &c->tag;
	t->w = nil;
	t->col = c;
	r1 = r;
	r1.max.y = r1.min.y + font->height;
	textinit(t, fileaddtext(nil, t), r1, &reffont, tagcols);
	t->what = Columntag;
	r1.min.y = r1.max.y;
	r1.max.y += Border;
	draw(screen, r1, display->black, nil, ZP);
	textinsert(t, 0, Lheader, 38, TRUE);
	textsetselect(t, t->file->b.nc, t->file->b.nc);
	draw(screen, t->scrollr, colbutton, nil, colbutton->r.min);
	c->safe = TRUE;
}

Window*
coladd(Column *c, Window *w, Window *clone, int y)
{
	Rectangle r, r1;
	Window *v;
	int i, j, minht, t;

	v = nil;
	r = c->r;
	r.min.y = c->tag.fr.r.max.y+Border;
	if(y<r.min.y && c->nw>0){	/* steal half of last window by default */
		v = c->w[c->nw-1];
		y = v->body.fr.r.min.y+Dy(v->body.fr.r)/2;
	}
	/* look for window we'll land on */
	for(i=0; i<c->nw; i++){
		v = c->w[i];
		if(y < v->r.max.y)
			break;
	}
	if(c->nw > 0){
		if(i < c->nw)
			i++;	/* new window will go after v */
		/*
		 * if v's too small, grow it first.
		 */
		minht = v->tag.fr.font->height+Border+1;
		j = 0;
		while(!c->safe || v->body.fr.maxlines<=3 || Dy(v->body.all) <= minht){
			if(++j > 10){
fprint(2, "oops: dy=%d\n", Dy(v->body.all));
				break;
			}
			colgrow(c, v, 1);
		}
		if(i == c->nw)
			t = c->r.max.y;
		else
			t = c->w[i]->r.min.y-Border;
		y = v->body.all.min.y+Dy(v->body.all)/2;
		if(t - y < minht)
			y = t - minht;
		if(y < v->body.all.min.y)
			y = v->body.all.min.y;
		r = v->r;
		r.max.y = t;
		draw(screen, r, textcols[BACK], nil, ZP);
		r1 = r;
		y = min(y, t-(v->tag.fr.font->height*v->taglines+v->body.fr.font->height+Border+1));
		r1.max.y = min(y, v->body.fr.r.min.y+v->body.fr.nlines*v->body.fr.font->height);
		r1.min.y = winresize(v, r1, FALSE, FALSE);
		r1.max.y = r1.min.y+Border;
		draw(screen, r1, display->black, nil, ZP);
		r.min.y = r1.max.y;
	}
	if(w == nil){
		w = emalloc(sizeof(Window));
		w->col = c;
		draw(screen, r, textcols[BACK], nil, ZP);
		wininit(w, clone, r);
	}else{
		w->col = c;
		winresize(w, r, FALSE, TRUE);
	}
	w->tag.col = c;
	w->tag.row = c->row;
	w->body.col = c;
	w->body.row = c->row;
	c->w = realloc(c->w, (c->nw+1)*sizeof(Window*));
	memmove(c->w+i+1, c->w+i, (c->nw-i)*sizeof(Window*));
	c->nw++;
	c->w[i] = w;
	savemouse(w);
	/* near but not on the button */
	moveto(mousectl, addpt(w->tag.scrollr.max, Pt(3, 3)));
	barttext = &w->body;
	c->safe = TRUE;
	return w;
}

void
colclose(Column *c, Window *w, int dofree)
{
	Rectangle r;
	int i;

	/* w is locked */
	if(!c->safe)
		colgrow(c, w, 1);
	for(i=0; i<c->nw; i++)
		if(c->w[i] == w)
			goto Found;
	error("can't find window");
  Found:
	r = w->r;
	w->tag.col = nil;
	w->body.col = nil;
	w->col = nil;
	restoremouse(w);
	if(dofree){
		windelete(w);
		winclose(w);
	}
	memmove(c->w+i, c->w+i+1, (c->nw-i)*sizeof(Window*));
	c->nw--;
	c->w = realloc(c->w, c->nw*sizeof(Window*));
	if(c->nw == 0){
		draw(screen, r, display->white, nil, ZP);
		return;
	}
	if(i == c->nw){		/* extend last window down */
		w = c->w[i-1];
		r.min.y = w->r.min.y;
		r.max.y = c->r.max.y;
	}else{			/* extend next window up */
		w = c->w[i];
		r.max.y = w->r.max.y;
	}
	draw(screen, r, textcols[BACK], nil, ZP);
	if(c->safe)
		winresize(w, r, FALSE, TRUE);
}

void
colcloseall(Column *c)
{
	int i;
	Window *w;

	if(c == activecol)
		activecol = nil;
	textclose(&c->tag);
	for(i=0; i<c->nw; i++){
		w = c->w[i];
		winclose(w);
	}
	c->nw = 0;
	free(c->w);
	free(c);
	clearmouse();
}

void
colmousebut(Column *c)
{
	moveto(mousectl, divpt(addpt(c->tag.scrollr.min, c->tag.scrollr.max), 2));
}

void
colresize(Column *c, Rectangle r)
{
	int i;
	Rectangle r1, r2;
	Window *w;

	clearmouse();
	r1 = r;
	r1.max.y = r1.min.y + c->tag.fr.font->height;
	textresize(&c->tag, r1, TRUE);
	draw(screen, c->tag.scrollr, colbutton, nil, colbutton->r.min);
	r1.min.y = r1.max.y;
	r1.max.y += Border;
	draw(screen, r1, display->black, nil, ZP);
	r1.max.y = r.max.y;
	for(i=0; i<c->nw; i++){
		w = c->w[i];
		w->maxlines = 0;
		if(i == c->nw-1)
			r1.max.y = r.max.y;
		else
			r1.max.y = r1.min.y+(Dy(w->r)+Border)*Dy(r)/Dy(c->r);
		if(Dy(r1) < Border+font->height)
			r1.max.y = r1.min.y + Border+font->height;
		r2 = r1;
		r2.max.y = r2.min.y+Border;
		draw(screen, r2, display->black, nil, ZP);
		r1.min.y = r2.max.y;
		r1.min.y = winresize(w, r1, FALSE, i==c->nw-1);
	}
	c->r = r;
}

static
int
colcmp(const void *a, const void *b)
{
	Rune *r1, *r2;
	int i, nr1, nr2;

	r1 = (*(Window**)a)->body.file->name;
	nr1 = (*(Window**)a)->body.file->nname;
	r2 = (*(Window**)b)->body.file->name;
	nr2 = (*(Window**)b)->body.file->nname;
	for(i=0; i<nr1 && i<nr2; i++){
		if(*r1 != *r2)
			return *r1-*r2;
		r1++;
		r2++;
	}
	return nr1-nr2;
}

void
colsort(Column *c)
{
	int i, y;
	Rectangle r, r1, *rp;
	Window **wp, *w;

	if(c->nw == 0)
		return;
	clearmouse();
	rp = emalloc(c->nw*sizeof(Rectangle));
	wp = emalloc(c->nw*sizeof(Window*));
	memmove(wp, c->w, c->nw*sizeof(Window*));
	qsort(wp, c->nw, sizeof(Window*), colcmp);
	for(i=0; i<c->nw; i++)
		rp[i] = wp[i]->r;
	r = c->r;
	r.min.y = c->tag.fr.r.max.y;
	draw(screen, r, textcols[BACK], nil, ZP);
	y = r.min.y;
	for(i=0; i<c->nw; i++){
		w = wp[i];
		r.min.y = y;
		if(i == c->nw-1)
			r.max.y = c->r.max.y;
		else
			r.max.y = r.min.y+Dy(w->r)+Border;
		r1 = r;
		r1.max.y = r1.min.y+Border;
		draw(screen, r1, display->black, nil, ZP);
		r.min.y = r1.max.y;
		y = winresize(w, r, FALSE, i==c->nw-1);
	}
	free(rp);
	free(c->w);
	c->w = wp;
}

void
colgrow(Column *c, Window *w, int but)
{
	Rectangle r, cr;
	int i, j, k, l, y1, y2, *nl, *ny, tot, nnl, onl, dnl, h;
	Window *v;

	for(i=0; i<c->nw; i++)
		if(c->w[i] == w)
			goto Found;
	error("can't find window");

  Found:
	cr = c->r;
	if(but < 0){	/* make sure window fills its own space properly */
		r = w->r;
		if(i==c->nw-1 || c->safe==FALSE)
			r.max.y = cr.max.y;
		else
			r.max.y = c->w[i+1]->r.min.y-Border;
		winresize(w, r, FALSE, TRUE);
		return;
	}
	cr.min.y = c->w[0]->r.min.y;
	if(but == 3){	/* full size */
		if(i != 0){
			v = c->w[0];
			c->w[0] = w;
			c->w[i] = v;
		}
		draw(screen, cr, textcols[BACK], nil, ZP);
		winresize(w, cr, FALSE, TRUE);
		for(i=1; i<c->nw; i++)
			c->w[i]->body.fr.maxlines = 0;
		c->safe = FALSE;
		return;
	}
	/* store old #lines for each window */
	onl = w->body.fr.maxlines;
	nl = emalloc(c->nw * sizeof(int));
	ny = emalloc(c->nw * sizeof(int));
	tot = 0;
	for(j=0; j<c->nw; j++){
		l = c->w[j]->taglines-1 + c->w[j]->body.fr.maxlines;
		nl[j] = l;
		tot += l;
	}
	/* approximate new #lines for this window */
	if(but == 2){	/* as big as can be */
		memset(nl, 0, c->nw * sizeof(int));
		goto Pack;
	}
	nnl = min(onl + max(min(5, w->taglines-1+w->maxlines), onl/2), tot);
	if(nnl < w->taglines-1+w->maxlines)
		nnl = (w->taglines-1+w->maxlines+nnl)/2;
	if(nnl == 0)
		nnl = 2;
	dnl = nnl - onl;
	/* compute new #lines for each window */
	for(k=1; k<c->nw; k++){
		/* prune from later window */
		j = i+k;
		if(j<c->nw && nl[j]){
			l = min(dnl, max(1, nl[j]/2));
			nl[j] -= l;
			nl[i] += l;
			dnl -= l;
		}
		/* prune from earlier window */
		j = i-k;
		if(j>=0 && nl[j]){
			l = min(dnl, max(1, nl[j]/2));
			nl[j] -= l;
			nl[i] += l;
			dnl -= l;
		}
	}
    Pack:
	/* pack everyone above */
	y1 = cr.min.y;
	for(j=0; j<i; j++){
		v = c->w[j];
		r = v->r;
		r.min.y = y1;
		r.max.y = y1+Dy(v->tagtop);
		if(nl[j])
			r.max.y += 1 + nl[j]*v->body.fr.font->height;
		r.min.y = winresize(v, r, c->safe, FALSE);
		r.max.y += Border;
		draw(screen, r, display->black, nil, ZP);
		y1 = r.max.y;
	}
	/* scan to see new size of everyone below */
	y2 = c->r.max.y;
	for(j=c->nw-1; j>i; j--){
		v = c->w[j];
		r = v->r;
		r.min.y = y2-Dy(v->tagtop);
		if(nl[j])
			r.min.y -= 1 + nl[j]*v->body.fr.font->height;
		r.min.y -= Border;
		ny[j] = r.min.y;
		y2 = r.min.y;
	}
	/* compute new size of window */
	r = w->r;
	r.min.y = y1;
	r.max.y = y2;
	h = w->body.fr.font->height;
	if(Dy(r) < Dy(w->tagtop)+1+h+Border)
		r.max.y = r.min.y + Dy(w->tagtop)+1+h+Border;
	/* draw window */
	winresize(w, r, c->safe, TRUE);
	if(i < c->nw-1){
		r.min.y = r.max.y;
		r.max.y += Border;
		draw(screen, r, display->black, nil, ZP);
		for(j=i+1; j<c->nw; j++)
			ny[j] -= (y2-r.max.y);
	}
	/* pack everyone below */
	y1 = r.max.y;
	for(j=i+1; j<c->nw; j++){
		v = c->w[j];
		r = v->r;
		r.min.y = y1;
		r.max.y = y1+Dy(v->tagtop);
		if(nl[j])
			r.max.y += 1 + nl[j]*v->body.fr.font->height;
		y1 = winresize(v, r, c->safe, j+1==c->nw);
		if(j < c->nw-1){	/* no border on last window */
			r.min.y = y1;
			r.max.y += Border;
			draw(screen, r, display->black, nil, ZP);
			y1 = r.max.y;
		}
	}
/*
	r = w->r;
	r.min.y = y1;
	r.max.y = c->r.max.y;
	draw(screen, r, textcols[BACK], nil, ZP);
*/
	free(nl);
	free(ny);
	c->safe = TRUE;
	winmousebut(w);
}

void
coldragwin(Column *c, Window *w, int but)
{
	Rectangle r;
	int i, b;
	Point p, op;
	Window *v;
	Column *nc;

	clearmouse();
	setcursor(mousectl, &boxcursor);
	b = mouse->buttons;
	op = mouse->xy;
	while(mouse->buttons == b)
		readmouse(mousectl);
	setcursor(mousectl, nil);
	if(mouse->buttons){
		while(mouse->buttons)
			readmouse(mousectl);
		return;
	}

	for(i=0; i<c->nw; i++)
		if(c->w[i] == w)
			goto Found;
	error("can't find window");

  Found:
/* TAG - force recompute tag size (if in auto-expand mode) on mouse op. */
	w->taglines = 1;
/* END TAG */
	p = mouse->xy;
	if(abs(p.x-op.x)<5 && abs(p.y-op.y)<5){
		colgrow(c, w, but);
		winmousebut(w);
		return;
	}
	/* is it a flick to the right? */
	if(abs(p.y-op.y)<10 && p.x>op.x+30 && rowwhichcol(c->row, p)==c)
		p.x = op.x+Dx(w->r);	/* yes: toss to next column */
	nc = rowwhichcol(c->row, p);
	if(nc!=nil && nc!=c){
		colclose(c, w, FALSE);
		coladd(nc, w, nil, p.y);
		winmousebut(w);
		return;
	}
	if(i==0 && c->nw==1)
		return;			/* can't do it */
	if((i>0 && p.y<c->w[i-1]->r.min.y) || (i<c->nw-1 && p.y>w->r.max.y)
	|| (i==0 && p.y>w->r.max.y)){
		/* shuffle */
		colclose(c, w, FALSE);
		coladd(c, w, nil, p.y);
		winmousebut(w);
		return;
	}
	if(i == 0)
		return;
	v = c->w[i-1];
	if(p.y < v->tagtop.max.y)
		p.y = v->tagtop.max.y;
	if(p.y > w->r.max.y-Dy(w->tagtop)-Border)
		p.y = w->r.max.y-Dy(w->tagtop)-Border;
	r = v->r;
	r.max.y = p.y;
	if(r.max.y > v->body.fr.r.min.y){
		r.max.y -= (r.max.y-v->body.fr.r.min.y)%v->body.fr.font->height;
		if(v->body.fr.r.min.y == v->body.fr.r.max.y)
			r.max.y++;
	}
	r.min.y = winresize(v, r, c->safe, FALSE);
	r.max.y = r.min.y+Border;
	draw(screen, r, display->black, nil, ZP);
	r.min.y = r.max.y;
	if(i == c->nw-1)
		r.max.y = c->r.max.y;
	else
		r.max.y = c->w[i+1]->r.min.y-Border;
	winresize(w, r, c->safe, TRUE);
	c->safe = TRUE;
    	winmousebut(w);
}

Text*
colwhich(Column *c, Point p)
{
	int i;
	Window *w;

	if(!ptinrect(p, c->r))
		return nil;
	if(ptinrect(p, c->tag.all))
		return &c->tag;
	for(i=0; i<c->nw; i++){
		w = c->w[i];
		if(ptinrect(p, w->r)){
			if(ptinrect(p, w->tagtop) || ptinrect(p, w->tag.fr.r))
				return &w->tag;
			if(ptinrect(p, w->body.scrollr) || ptinrect(p, w->body.fr.r))
				return &w->body;
			return nil;
		}
	}
	return nil;
}

int
colclean(Column *c)
{
	int i, clean;

	clean = TRUE;
	for(i=0; i<c->nw; i++)
		clean &= winclean(c->w[i], TRUE);
	return clean;
}
