#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>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
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
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){
		/* rasp and buffer are in sync; sync with wire if needed */
		if(needoutflush())
			raspflush(f);
		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;
}
