#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"

enum
{
	Slop = 100,	/* room to grow with reallocation */
};

static
void
sizecache(Buffer *b, uint n)
{
	if(n <= b->cmax)
		return;
	b->cmax = n+Slop;
	b->c = runerealloc(b->c, b->cmax);
}

static
void
addblock(Buffer *b, uint i, uint n)
{
	if(i > b->nbl)
		error("internal error: addblock");

	b->bl = realloc(b->bl, (b->nbl+1)*sizeof b->bl[0]);
	if(i < b->nbl)
		memmove(b->bl+i+1, b->bl+i, (b->nbl-i)*sizeof(Block*));
	b->bl[i] = disknewblock(disk, n);
	b->nbl++;
}

static
void
delblock(Buffer *b, uint i)
{
	if(i >= b->nbl)
		error("internal error: delblock");

	diskrelease(disk, b->bl[i]);
	b->nbl--;
	if(i < b->nbl)
		memmove(b->bl+i, b->bl+i+1, (b->nbl-i)*sizeof(Block*));
	b->bl = realloc(b->bl, b->nbl*sizeof b->bl[0]);
}

/*
 * Move cache so b->cq <= q0 < b->cq+b->cnc.
 * If at very end, q0 will fall on end of cache block.
 */

static
void
flush(Buffer *b)
{
	if(b->cdirty || b->cnc==0){
		if(b->cnc == 0)
			delblock(b, b->cbi);
		else
			diskwrite(disk, &b->bl[b->cbi], b->c, b->cnc);
		b->cdirty = FALSE;
	}
}

static
void
setcache(Buffer *b, uint q0)
{
	Block **blp, *bl;
	uint i, q;

	if(q0 > b->nc)
		error("internal error: setcache");
	/*
	 * flush and reload if q0 is not in cache.
	 */
	if(b->nc == 0 || (b->cq<=q0 && q0<b->cq+b->cnc))
		return;
	/*
	 * if q0 is at end of file and end of cache, continue to grow this block
	 */
	if(q0==b->nc && q0==b->cq+b->cnc && b->cnc<Maxblock)
		return;
	flush(b);
	/* find block */
	if(q0 < b->cq){
		q = 0;
		i = 0;
	}else{
		q = b->cq;
		i = b->cbi;
	}
	blp = &b->bl[i];
	while(q+(*blp)->u.n <= q0 && q+(*blp)->u.n < b->nc){
		q += (*blp)->u.n;
		i++;
		blp++;
		if(i >= b->nbl)
			error("block not found");
	}
	bl = *blp;
	/* remember position */
	b->cbi = i;
	b->cq = q;
	sizecache(b, bl->u.n);
	b->cnc = bl->u.n;
	/*read block*/
	diskread(disk, bl, b->c, b->cnc);
}

void
bufinsert(Buffer *b, uint q0, Rune *s, uint n)
{
	uint i, m, t, off;

	if(q0 > b->nc)
		error("internal error: bufinsert");

	while(n > 0){
		setcache(b, q0);
		off = q0-b->cq;
		if(b->cnc+n <= Maxblock){
			/* Everything fits in one block. */
			t = b->cnc+n;
			m = n;
			if(b->bl == nil){	/* allocate */
				if(b->cnc != 0)
					error("internal error: bufinsert1 cnc!=0");
				addblock(b, 0, t);
				b->cbi = 0;
			}
			sizecache(b, t);
			runemove(b->c+off+m, b->c+off, b->cnc-off);
			runemove(b->c+off, s, m);
			b->cnc = t;
			goto Tail;
		}
		/*
		 * We must make a new block.  If q0 is at
		 * the very beginning or end of this block,
		 * just make a new block and fill it.
		 */
		if(q0==b->cq || q0==b->cq+b->cnc){
			if(b->cdirty)
				flush(b);
			m = min(n, Maxblock);
			if(b->bl == nil){	/* allocate */
				if(b->cnc != 0)
					error("internal error: bufinsert2 cnc!=0");
				i = 0;
			}else{
				i = b->cbi;
				if(q0 > b->cq)
					i++;
			}
			addblock(b, i, m);
			sizecache(b, m);
			runemove(b->c, s, m);
			b->cq = q0;
			b->cbi = i;
			b->cnc = m;
			goto Tail;
		}
		/*
		 * Split the block; cut off the right side and
		 * let go of it.
		 */
		m = b->cnc-off;
		if(m > 0){
			i = b->cbi+1;
			addblock(b, i, m);
			diskwrite(disk, &b->bl[i], b->c+off, m);
			b->cnc -= m;
		}
		/*
		 * Now at end of block.  Take as much input
		 * as possible and tack it on end of block.
		 */
		m = min(n, Maxblock-b->cnc);
		sizecache(b, b->cnc+m);
		runemove(b->c+b->cnc, s, m);
		b->cnc += m;
  Tail:
		b->nc += m;
		q0 += m;
		s += m;
		n -= m;
		b->cdirty = TRUE;
	}
}

void
bufdelete(Buffer *b, uint q0, uint q1)
{
	uint m, n, off;

	if(!(q0<=q1 && q0<=b->nc && q1<=b->nc))
		error("internal error: bufdelete");
	while(q1 > q0){
		setcache(b, q0);
		off = q0-b->cq;
		if(q1 > b->cq+b->cnc)
			n = b->cnc - off;
		else
			n = q1-q0;
		m = b->cnc - (off+n);
		if(m > 0)
			runemove(b->c+off, b->c+off+n, m);
		b->cnc -= n;
		b->cdirty = TRUE;
		q1 -= n;
		b->nc -= n;
	}
}

static int
bufloader(void *v, uint q0, Rune *r, int nr)
{
	bufinsert(v, q0, r, nr);
	return nr;
}

uint
loadfile(int fd, uint q0, int *nulls, int(*f)(void*, uint, Rune*, int), void *arg)
{
	char *p;
	Rune *r;
	int l, m, n, nb, nr;
	uint q1;

	p = emalloc((Maxblock+UTFmax+1)*sizeof p[0]);
	r = runemalloc(Maxblock);
	m = 0;
	n = 1;
	q1 = q0;
	/*
	 * At top of loop, may have m bytes left over from
	 * last pass, possibly representing a partial rune.
	 */
	while(n > 0){
		n = read(fd, p+m, Maxblock);
		if(n < 0){
			warning(nil, "read error in Buffer.load");
			break;
		}
		m += n;
		p[m] = 0;
		l = m;
		if(n > 0)
			l -= UTFmax;
		cvttorunes(p, l, r, &nb, &nr, nulls);
		memmove(p, p+nb, m-nb);
		m -= nb;
		q1 += (*f)(arg, q1, r, nr);
	}
	free(p);
	free(r);
	return q1-q0;
}

uint
bufload(Buffer *b, uint q0, int fd, int *nulls)
{
	if(q0 > b->nc)
		error("internal error: bufload");
	return loadfile(fd, q0, nulls, bufloader, b);
}

void
bufread(Buffer *b, uint q0, Rune *s, uint n)
{
	uint m;

	if(!(q0<=b->nc && q0+n<=b->nc))
		error("bufread: internal error");

	while(n > 0){
		setcache(b, q0);
		m = min(n, b->cnc-(q0-b->cq));
		runemove(s, b->c+(q0-b->cq), m);
		q0 += m;
		s += m;
		n -= m;
	}
}

void
bufreset(Buffer *b)
{
	int i;

	b->nc = 0;
	b->cnc = 0;
	b->cq = 0;
	b->cdirty = 0;
	b->cbi = 0;
	/* delete backwards to avoid n² behavior */
	for(i=b->nbl-1; --i>=0; )
		delblock(b, i);
}

void
bufclose(Buffer *b)
{
	bufreset(b);
	free(b->c);
	b->c = nil;
	b->cnc = 0;
	free(b->bl);
	b->bl = nil;
	b->nbl = 0;
}
