#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;
	noflush = 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();
	noflush = 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;
}

