#include "sam.h"
/*
 * GROWDATASIZE must be big enough that all errors go out as Hgrowdata's,
 * so they will be scrolled into visibility in the ~~sam~~ window (yuck!).
 */
#define	GROWDATASIZE	50	/* if size is <= this, send data with grow */

void	rcut(List*, Posn, Posn);
int	rterm(List*, Posn);
void	rgrow(List*, Posn, Posn);

static	Posn	growpos;
static	Posn	grown;
static	Posn	shrinkpos;
static	Posn	shrunk;

/*
 * rasp routines inform the terminal of changes to the file.
 *
 * a rasp is a list of spans within the file, and an indication
 * of whether the terminal knows about the span.
 *
 * optimize by coalescing multiple updates to the same span
 * if it is not known by the terminal.
 *
 * other possible optimizations: flush terminal's rasp by cut everything,
 * insert everything if rasp gets too large.
 */

/*
 * only called for initial load of file
 */
void
raspload(File *f)
{
	if(f->rasp == nil)
		return;
	grown = f->b.nc;
	growpos = 0;
	if(f->b.nc)
		rgrow(f->rasp, 0, f->b.nc);
	raspdone(f, 1);
}

void
raspstart(File *f)
{
	if(f->rasp == nil)
		return;
	grown = 0;
	shrunk = 0;
	outbuffered = 1;
}

void
raspdone(File *f, int toterm)
{
	if(f->dot.r.p1 > f->b.nc)
		f->dot.r.p1 = f->b.nc;
	if(f->dot.r.p2 > f->b.nc)
		f->dot.r.p2 = f->b.nc;
	if(f->mark.p1 > f->b.nc)
		f->mark.p1 = f->b.nc;
	if(f->mark.p2 > f->b.nc)
		f->mark.p2 = f->b.nc;
	if(f->rasp == nil)
		return;
	if(grown)
		outTsll(Hgrow, f->tag, growpos, grown);
	else if(shrunk)
		outTsll(Hcut, f->tag, shrinkpos, shrunk);
	if(toterm)
		outTs(Hcheck0, f->tag);
	outflush();
	outbuffered = 0;
	if(f == cmd){
		cmdpt += cmdptadv;
		cmdptadv = 0;
	}
}

void
raspflush(File *f)
{
	if(grown){
		outTsll(Hgrow, f->tag, growpos, grown);
		grown = 0;
	}
	else if(shrunk){
		outTsll(Hcut, f->tag, shrinkpos, shrunk);
		shrunk = 0;
	}
	outflush();
}

void
raspdelete(File *f, uint p1, uint p2, int toterm)
{
	long n;

	n = p2 - p1;
	if(n == 0)
		return;

	if(p2 <= f->dot.r.p1){
		f->dot.r.p1 -= n;
		f->dot.r.p2 -= n;
	}
	if(p2 <= f->mark.p1){
		f->mark.p1 -= n;
		f->mark.p2 -= n;
	}

	if(f->rasp == nil)
		return;

	if(f==cmd && p1<cmdpt){
		if(p2 <= cmdpt)
			cmdpt -= n;
		else
			cmdpt = p1;
	}
	if(toterm){
		if(grown){
			outTsll(Hgrow, f->tag, growpos, grown);
			grown = 0;
		}else if(shrunk && shrinkpos!=p1 && shrinkpos!=p2){
			outTsll(Hcut, f->tag, shrinkpos, shrunk);
			shrunk = 0;
		}
		if(!shrunk || shrinkpos==p2)
			shrinkpos = p1;
		shrunk += n;
	}
	rcut(f->rasp, p1, p2);
}

void
raspinsert(File *f, uint p1, Rune *buf, uint n, int toterm)
{
	Range r;

	if(n == 0)
		return;

	if(p1 < f->dot.r.p1){
		f->dot.r.p1 += n;
		f->dot.r.p2 += n;
	}
	if(p1 < f->mark.p1){
		f->mark.p1 += n;
		f->mark.p2 += n;
	}


	if(f->rasp == nil)
		return;
	if(f==cmd && p1<cmdpt)
		cmdpt += n;
	if(toterm){
		if(shrunk){
			outTsll(Hcut, f->tag, shrinkpos, shrunk);
			shrunk = 0;
		}
		if(n>GROWDATASIZE || !rterm(f->rasp, p1)){
			rgrow(f->rasp, p1, n);
			if(grown && growpos+grown!=p1 && growpos!=p1){
				outTsll(Hgrow, f->tag, growpos, grown);
				grown = 0;
			}
			if(!grown)
				growpos = p1;
			grown += n;
		}else{
			if(grown){
				outTsll(Hgrow, f->tag, growpos, grown);
				grown = 0;
			}
			rgrow(f->rasp, p1, n);
			r = rdata(f->rasp, p1, n);
			if(r.p1!=p1 || r.p2!=p1+n)
				panic("rdata in toterminal");
			outTsllS(Hgrowdata, f->tag, p1, n, tmprstr(buf, n));
		}
	}else{
		rgrow(f->rasp, p1, n);
		r = rdata(f->rasp, p1, n);
		if(r.p1!=p1 || r.p2!=p1+n)
			panic("rdata in toterminal");
	}
}

#define	M	0x80000000L
#define	P(i)	r->posnptr[i]
#define	T(i)	(P(i)&M)	/* in terminal */
#define	L(i)	(P(i)&~M)	/* length of this piece */

void
rcut(List *r, Posn p1, Posn p2)
{
	Posn p, x;
	int i;

	if(p1 == p2)
		panic("rcut 0");
	for(p=0,i=0; i<r->nused && p+L(i)<=p1; p+=L(i++))
		;
	if(i == r->nused)
		panic("rcut 1");
	if(p < p1){	/* chop this piece */
		if(p+L(i) < p2){
			x = p1-p;
			p += L(i);
		}else{
			x = L(i)-(p2-p1);
			p = p2;
		}
		if(T(i))
			P(i) = x|M;
		else
			P(i) = x;
		i++;
	}
	while(i<r->nused && p+L(i)<=p2){
		p += L(i);
		dellist(r, i);
	}
	if(p < p2){
		if(i == r->nused)
			panic("rcut 2");
		x = L(i)-(p2-p);
		if(T(i))
			P(i) = x|M;
		else
			P(i) = x;
	}
	/* can we merge i and i-1 ? */
	if(i>0 && i<r->nused && T(i-1)==T(i)){
		x = L(i-1)+L(i);
		dellist(r, i--);
		if(T(i))
			P(i)=x|M;
		else
			P(i)=x;
	}
}

void
rgrow(List *r, Posn p1, Posn n)
{
	Posn p;
	int i;

	if(n == 0)
		panic("rgrow 0");
	for(p=0,i=0; i<r->nused && p+L(i)<=p1; p+=L(i++))
		;
	if(i == r->nused){	/* stick on end of file */
		if(p!=p1)
			panic("rgrow 1");
		if(i>0 && !T(i-1))
			P(i-1)+=n;
		else
			inslist(r, i, n);
	}else if(!T(i))		/* goes in this empty piece */
		P(i)+=n;
	else if(p==p1 && i>0 && !T(i-1))	/* special case; simplifies life */
		P(i-1)+=n;
	else if(p==p1)
		inslist(r, i, n);
	else{			/* must break piece in terminal */
		inslist(r, i+1, (L(i)-(p1-p))|M);
		inslist(r, i+1, n);
		P(i) = (p1-p)|M;
	}
}

int
rterm(List *r, Posn p1)
{
	Posn p;
	int i;

	for(p = 0,i = 0; i<r->nused && p+L(i)<=p1; p+=L(i++))
		;
	if(i==r->nused && (i==0 || !T(i-1)))
		return 0;
	return T(i);
}

Range
rdata(List *r, Posn p1, Posn n)
{
	Posn p;
	int i;
	Range rg;

	if(n==0)
		panic("rdata 0");
	for(p = 0,i = 0; i<r->nused && p+L(i)<=p1; p+=L(i++))
		;
	if(i==r->nused)
		panic("rdata 1");
	if(T(i)){
		n-=L(i)-(p1-p);
		if(n<=0){
			rg.p1 = rg.p2 = p1;
			return rg;
		}
		p+=L(i++);
		p1 = p;
	}
	if(T(i) || i==r->nused)
		panic("rdata 2");
	if(p+L(i)<p1+n)
		n = L(i)-(p1-p);
	rg.p1 = p1;
	rg.p2 = p1+n;
	if(p!=p1){
		inslist(r, i+1, L(i)-(p1-p));
		P(i)=p1-p;
		i++;
	}
	if(L(i)!=n){
		inslist(r, i+1, L(i)-n);
		P(i)=n;
	}
	P(i)|=M;
	/* now i is set; can we merge? */
	if(i<r->nused-1 && T(i+1)){
		P(i)=(n+=L(i+1))|M;
		dellist(r, i+1);
	}
	if(i>0 && T(i-1)){
		P(i)=(n+L(i-1))|M;
		dellist(r, i-1);
	}
	return rg;
}

