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