#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;
}
