#include "sam.h"

/*
 * Structure of Undo list:
 * 	The Undo structure follows any associated data, so the list
 *	can be read backwards: read the structure, then read whatever
 *	data is associated (insert string, file name) and precedes it.
 *	The structure includes the previous value of the modify bit
 *	and a sequence number; successive Undo structures with the
 *	same sequence number represent simultaneous changes.
 */

typedef struct Undo Undo;
typedef struct Merge Merge;

struct Undo
{
	short	type;		/* Delete, Insert, Filename, Dot, Mark */
	short	mod;		/* modify bit */
	uint	seq;		/* sequence number */
	uint	p0;		/* location of change (unused in f) */
	uint	n;		/* # runes in string or file name */
};

struct Merge
{
	File	*f;
	uint	seq;		/* of logged change */
	uint	p0;		/* location of change (unused in f) */
	uint	n;		/* # runes to delete */
	uint	nbuf;		/* # runes to insert */
	Rune	buf[RBUFSIZE];
};

enum
{
	Maxmerge = 50,
	Undosize = sizeof(Undo)/sizeof(Rune),
};

static Merge	merge;

File*
fileopen(void)
{
	File *f;

	f = emalloc(sizeof(File));
	f->dot.f = f;
	f->ndot.f = f;
	f->seq = 0;
	f->mod = FALSE;
	f->unread = TRUE;
	Strinit0(&f->name);
	return f;
}

int
fileisdirty(File *f)
{
	return f->seq != f->cleanseq;
}

static void
wrinsert(Buffer *delta, int seq, int mod, uint p0, Rune *s, uint ns)
{
	Undo u;

	u.type = Insert;
	u.mod = mod;
	u.seq = seq;
	u.p0 = p0;
	u.n = ns;
	bufinsert(delta, delta->nc, s, ns);
	bufinsert(delta, delta->nc, (Rune*)&u, Undosize);
}

static void
wrdelete(Buffer *delta, int seq, int mod, uint p0, uint p1)
{
	Undo u;

	u.type = Delete;
	u.mod = mod;
	u.seq = seq;
	u.p0 = p0;
	u.n = p1 - p0;
	bufinsert(delta, delta->nc, (Rune*)&u, Undosize);
}

void
flushmerge(void)
{
	File *f;

	f = merge.f;
	if(f == nil)
		return;
	if(merge.seq != f->seq)
		panic("flushmerge seq mismatch");
	if(merge.n != 0)
		wrdelete(&f->epsilon, f->seq, TRUE, merge.p0, merge.p0+merge.n);
	if(merge.nbuf != 0)
		wrinsert(&f->epsilon, f->seq, TRUE, merge.p0+merge.n, merge.buf, merge.nbuf);
	merge.f = nil;
	merge.n = 0;
	merge.nbuf = 0;
}

void
mergeextend(File *f, uint p0)
{
	uint mp0n;

	mp0n = merge.p0+merge.n;
	if(mp0n != p0){
		bufread(&f->b, mp0n, merge.buf+merge.nbuf, p0-mp0n);
		merge.nbuf += p0-mp0n;
		merge.n = p0-merge.p0;
	}
}

/*
 * like fileundelete, but get the data from arguments
 */
void
loginsert(File *f, uint p0, Rune *s, uint ns)
{
	if(f->rescuing)
		return;
	if(ns == 0)
		return;
	if(ns<0 || ns>STRSIZE)
		panic("loginsert");
	if(f->seq < seq)
		filemark(f);
	if(p0 < f->hiposn)
		error(Esequence);

	if(merge.f != f
	|| p0-(merge.p0+merge.n)>Maxmerge			/* too far */
	|| merge.nbuf+((p0+ns)-(merge.p0+merge.n))>RBUFSIZE)	/* too long */
		flushmerge();

	if(ns>=RBUFSIZE){
		if(!(merge.n == 0 && merge.nbuf == 0 && merge.f == nil))
			panic("loginsert bad merge state");
		wrinsert(&f->epsilon, f->seq, TRUE, p0, s, ns);
	}else{
		if(merge.f != f){
			merge.f = f;
			merge.p0 = p0;
			merge.seq = f->seq;
		}
		mergeextend(f, p0);

		/* append string to merge */
		runemove(merge.buf+merge.nbuf, s, ns);
		merge.nbuf += ns;
	}

	f->hiposn = p0;
	if(!f->unread && !f->mod)
		state(f, Dirty);
}

void
logdelete(File *f, uint p0, uint p1)
{
	if(f->rescuing)
		return;
	if(p0 == p1)
		return;
	if(f->seq < seq)
		filemark(f);
	if(p0 < f->hiposn)
		error(Esequence);

	if(merge.f != f
	|| p0-(merge.p0+merge.n)>Maxmerge			/* too far */
	|| merge.nbuf+(p0-(merge.p0+merge.n))>RBUFSIZE){	/* too long */
		flushmerge();
		merge.f = f;
		merge.p0 = p0;
		merge.seq = f->seq;
	}

	mergeextend(f, p0);

	/* add to deletion */
	merge.n = p1-merge.p0;

	f->hiposn = p1;
	if(!f->unread && !f->mod)
		state(f, Dirty);
}

/*
 * like fileunsetname, but get the data from arguments
 */
void
logsetname(File *f, String *s)
{
	Undo u;
	Buffer *delta;

	if(f->rescuing)
		return;

	if(f->unread){	/* This is setting initial file name */
		filesetname(f, s);
		return;
	}

	if(f->seq < seq)
		filemark(f);

	/* undo a file name change by restoring old name */
	delta = &f->epsilon;
	u.type = Filename;
	u.mod = TRUE;
	u.seq = f->seq;
	u.p0 = 0;	/* unused */
	u.n = s->n;
	if(s->n)
		bufinsert(delta, delta->nc, s->s, s->n);
	bufinsert(delta, delta->nc, (Rune*)&u, Undosize);
	if(!f->unread && !f->mod)
		state(f, Dirty);
}

#ifdef NOTEXT
File*
fileaddtext(File *f, Text *t)
{
	if(f == nil){
		f = emalloc(sizeof(File));
		f->unread = TRUE;
	}
	f->text = realloc(f->text, (f->ntext+1)*sizeof(Text*));
	f->text[f->ntext++] = t;
	f->curtext = t;
	return f;
}

void
filedeltext(File *f, Text *t)
{
	int i;

	for(i=0; i<f->ntext; i++)
		if(f->text[i] == t)
			goto Found;
	panic("can't find text in filedeltext");

    Found:
	f->ntext--;
	if(f->ntext == 0){
		fileclose(f);
		return;
	}
	memmove(f->text+i, f->text+i+1, (f->ntext-i)*sizeof(Text*));
	if(f->curtext == t)
		f->curtext = f->text[0];
}
#endif

void
fileinsert(File *f, uint p0, Rune *s, uint ns)
{
	if(p0 > f->b.nc)
		panic("internal error: fileinsert");
	if(f->seq > 0)
		fileuninsert(f, &f->delta, p0, ns);
	bufinsert(&f->b, p0, s, ns);
	if(ns)
		f->mod = TRUE;
}

void
fileuninsert(File *f, Buffer *delta, uint p0, uint ns)
{
	Undo u;

	/* undo an insertion by deleting */
	u.type = Delete;
	u.mod = f->mod;
	u.seq = f->seq;
	u.p0 = p0;
	u.n = ns;
	bufinsert(delta, delta->nc, (Rune*)&u, Undosize);
}

void
filedelete(File *f, uint p0, uint p1)
{
	if(!(p0<=p1 && p0<=f->b.nc && p1<=f->b.nc))
		panic("internal error: filedelete");
	if(f->seq > 0)
		fileundelete(f, &f->delta, p0, p1);
	bufdelete(&f->b, p0, p1);
	if(p1 > p0)
		f->mod = TRUE;
}

void
fileundelete(File *f, Buffer *delta, uint p0, uint p1)
{
	Undo u;
	Rune *buf;
	uint i, n;

	/* undo a deletion by inserting */
	u.type = Insert;
	u.mod = f->mod;
	u.seq = f->seq;
	u.p0 = p0;
	u.n = p1-p0;
	buf = fbufalloc();
	for(i=p0; i<p1; i+=n){
		n = p1 - i;
		if(n > RBUFSIZE)
			n = RBUFSIZE;
		bufread(&f->b, i, buf, n);
		bufinsert(delta, delta->nc, buf, n);
	}
	fbuffree(buf);
	bufinsert(delta, delta->nc, (Rune*)&u, Undosize);

}

int
filereadc(File *f, uint q)
{
	Rune r;

	if(q >= f->b.nc)
		return -1;
	bufread(&f->b, q, &r, 1);
	return r;
}

void
filesetname(File *f, String *s)
{
	if(!f->unread)	/* This is setting initial file name */
		fileunsetname(f, &f->delta);
	Strduplstr(&f->name, s);
	sortname(f);
	f->unread = TRUE;
}

void
fileunsetname(File *f, Buffer *delta)
{
	String s;
	Undo u;

	/* undo a file name change by restoring old name */
	u.type = Filename;
	u.mod = f->mod;
	u.seq = f->seq;
	u.p0 = 0;	/* unused */
	Strinit(&s);
	Strduplstr(&s, &f->name);
	fullname(&s);
	u.n = s.n;
	if(s.n)
		bufinsert(delta, delta->nc, s.s, s.n);
	bufinsert(delta, delta->nc, (Rune*)&u, Undosize);
	Strclose(&s);
}

void
fileunsetdot(File *f, Buffer *delta, Range dot)
{
	Undo u;

	u.type = Dot;
	u.mod = f->mod;
	u.seq = f->seq;
	u.p0 = dot.p1;
	u.n = dot.p2 - dot.p1;
	bufinsert(delta, delta->nc, (Rune*)&u, Undosize);
}

void
fileunsetmark(File *f, Buffer *delta, Range mark)
{
	Undo u;

	u.type = Mark;
	u.mod = f->mod;
	u.seq = f->seq;
	u.p0 = mark.p1;
	u.n = mark.p2 - mark.p1;
	bufinsert(delta, delta->nc, (Rune*)&u, Undosize);
}

uint
fileload(File *f, uint p0, int fd, int *nulls)
{
	if(f->seq > 0)
		panic("undo in file.load unimplemented");
	return bufload(&f->b, p0, fd, nulls);
}

int
fileupdate(File *f, int notrans, int toterm)
{
	uint p1, p2;
	int mod;

	if(f->rescuing)
		return FALSE;

	flushmerge();

	/*
	 * fix the modification bit
	 * subtle point: don't save it away in the log.
	 *
	 * if another change is made, the correct f->mod
	 * state is saved  in the undo log by filemark
	 * when setting the dot and mark.
	 *
	 * if the change is undone, the correct state is
	 * saved from f in the fileun... routines.
	 */
	mod = f->mod;
	f->mod = f->prevmod;
	if(f == cmd)
		notrans = TRUE;
	else{
		fileunsetdot(f, &f->delta, f->prevdot);
		fileunsetmark(f, &f->delta, f->prevmark);
	}
	f->dot = f->ndot;
	fileundo(f, FALSE, !notrans, &p1, &p2, toterm);
	f->mod = mod;

	if(f->delta.nc == 0)
		f->seq = 0;

	if(f == cmd)
		return FALSE;

	if(f->mod){
		f->closeok = 0;
		quitok = 0;
	}else
		f->closeok = 1;
	return TRUE;
}

long
prevseq(Buffer *b)
{
	Undo u;
	uint up;

	up = b->nc;
	if(up == 0)
		return 0;
	up -= Undosize;
	bufread(b, up, (Rune*)&u, Undosize);
	return u.seq;
}

long
undoseq(File *f, int isundo)
{
	if(isundo)
		return f->seq;

	return prevseq(&f->epsilon);
}

void
fileundo(File *f, int isundo, int canredo, uint *q0p, uint *q1p, int flag)
{
	Undo u;
	Rune *buf;
	uint i, n, up;
	uint stop;
	Buffer *delta, *epsilon;

	if(isundo){
		/* undo; reverse delta onto epsilon, seq decreases */
		delta = &f->delta;
		epsilon = &f->epsilon;
		stop = f->seq;
	}else{
		/* redo; reverse epsilon onto delta, seq increases */
		delta = &f->epsilon;
		epsilon = &f->delta;
		stop = 0;	/* don't know yet */
	}

	raspstart(f);
	while(delta->nc > 0){
		up = delta->nc-Undosize;
		bufread(delta, up, (Rune*)&u, Undosize);
		if(isundo){
			if(u.seq < stop){
				f->seq = u.seq;
				raspdone(f, flag);
				return;
			}
		}else{
			if(stop == 0)
				stop = u.seq;
			if(u.seq > stop){
				raspdone(f, flag);
				return;
			}
		}
		switch(u.type){
		default:
			panic("undo unknown u.type");
			break;

		case Delete:
			f->seq = u.seq;
			if(canredo)
				fileundelete(f, epsilon, u.p0, u.p0+u.n);
			f->mod = u.mod;
			bufdelete(&f->b, u.p0, u.p0+u.n);
			raspdelete(f, u.p0, u.p0+u.n, flag);
			*q0p = u.p0;
			*q1p = u.p0;
			break;

		case Insert:
			f->seq = u.seq;
			if(canredo)
				fileuninsert(f, epsilon, u.p0, u.n);
			f->mod = u.mod;
			up -= u.n;
			buf = fbufalloc();
			for(i=0; i<u.n; i+=n){
				n = u.n - i;
				if(n > RBUFSIZE)
					n = RBUFSIZE;
				bufread(delta, up+i, buf, n);
				bufinsert(&f->b, u.p0+i, buf, n);
				raspinsert(f, u.p0+i, buf, n, flag);
			}
			fbuffree(buf);
			*q0p = u.p0;
			*q1p = u.p0+u.n;
			break;

		case Filename:
			f->seq = u.seq;
			if(canredo)
				fileunsetname(f, epsilon);
			f->mod = u.mod;
			up -= u.n;

			Strinsure(&f->name, u.n+1);
			bufread(delta, up, f->name.s, u.n);
			f->name.s[u.n] = 0;
			f->name.n = u.n;
			fixname(&f->name);
			sortname(f);
			break;
		case Dot:
			f->seq = u.seq;
			if(canredo)
				fileunsetdot(f, epsilon, f->dot.r);
			f->mod = u.mod;
			f->dot.r.p1 = u.p0;
			f->dot.r.p2 = u.p0 + u.n;
			break;
		case Mark:
			f->seq = u.seq;
			if(canredo)
				fileunsetmark(f, epsilon, f->mark);
			f->mod = u.mod;
			f->mark.p1 = u.p0;
			f->mark.p2 = u.p0 + u.n;
			break;
		}
		bufdelete(delta, up, delta->nc);
	}
	if(isundo)
		f->seq = 0;
	raspdone(f, flag);
}

void
filereset(File *f)
{
	bufreset(&f->delta);
	bufreset(&f->epsilon);
	f->seq = 0;
}

void
fileclose(File *f)
{
	Strclose(&f->name);
	bufclose(&f->b);
	bufclose(&f->delta);
	bufclose(&f->epsilon);
	if(f->rasp)
		listfree(f->rasp);
	free(f);
}

void
filemark(File *f)
{

	if(f->unread)
		return;
	if(f->epsilon.nc)
		bufdelete(&f->epsilon, 0, f->epsilon.nc);

	if(f != cmd){
		f->prevdot = f->dot.r;
		f->prevmark = f->mark;
		f->prevseq = f->seq;
		f->prevmod = f->mod;
	}

	f->ndot = f->dot;
	f->seq = seq;
	f->hiposn = 0;
}
