#include <u.h>
#include <libc.h>
#include <draw.h>
#include <thread.h>
#include <cursor.h>
#include <mouse.h>
#include <keyboard.h>
#include <frame.h>
#include <fcall.h>
#include <plumb.h>
#include "dat.h"
#include "fns.h"
#include "edit.h"

static char Wsequence[] = "warning: changes out of sequence\n";
static int	warned = FALSE;

/*
 * Log of changes made by editing commands.  Three reasons for this:
 * 1) We want addresses in commands to apply to old file, not file-in-change.
 * 2) It's difficult to track changes correctly as things move, e.g. ,x m$
 * 3) This gives an opportunity to optimize by merging adjacent changes.
 * It's a little bit like the Undo/Redo log in Files, but Point 3) argues for a
 * separate implementation.  To do this well, we use Replace as well as
 * Insert and Delete
 */

typedef struct Buflog Buflog;
struct Buflog
{
	short	type;		/* Replace, Filename */
	uint		q0;		/* location of change (unused in f) */
	uint		nd;		/* # runes to delete */
	uint		nr;		/* # runes in string or file name */
};

enum
{
	Buflogsize = sizeof(Buflog)/sizeof(Rune)
};

/*
 * Minstring shouldn't be very big or we will do lots of I/O for small changes.
 * Maxstring is RBUFSIZE so we can fbufalloc() once and not realloc elog.r.
 */
enum
{
	Minstring = 16,		/* distance beneath which we merge changes */
	Maxstring = RBUFSIZE	/* maximum length of change we will merge into one */
};

void
eloginit(File *f)
{
	if(f->elog.type != Empty)
		return;
	f->elog.type = Null;
	if(f->elogbuf == nil)
		f->elogbuf = emalloc(sizeof(Buffer));
	if(f->elog.r == nil)
		f->elog.r = fbufalloc();
	bufreset(f->elogbuf);
}

void
elogclose(File *f)
{
	if(f->elogbuf){
		bufclose(f->elogbuf);
		free(f->elogbuf);
		f->elogbuf = nil;
	}
}

void
elogreset(File *f)
{
	f->elog.type = Null;
	f->elog.nd = 0;
	f->elog.nr = 0;
}

void
elogterm(File *f)
{
	elogreset(f);
	if(f->elogbuf)
		bufreset(f->elogbuf);
	f->elog.type = Empty;
	fbuffree(f->elog.r);
	f->elog.r = nil;
	warned = FALSE;
}

void
elogflush(File *f)
{
	Buflog b;

	b.type = f->elog.type;
	b.q0 = f->elog.q0;
	b.nd = f->elog.nd;
	b.nr = f->elog.nr;
	switch(f->elog.type){
	default:
		warning(nil, "unknown elog type 0x%ux\n", f->elog.type);
		break;
	case Null:
		break;
	case Insert:
	case Replace:
		if(f->elog.nr > 0)
			bufinsert(f->elogbuf, f->elogbuf->nc, f->elog.r, f->elog.nr);
		/* fall through */
	case Delete:
		bufinsert(f->elogbuf, f->elogbuf->nc, (Rune*)&b, Buflogsize);
		break;
	}
	elogreset(f);
}

void
elogreplace(File *f, int q0, int q1, Rune *r, int nr)
{
	uint gap;

	if(q0==q1 && nr==0)
		return;
	eloginit(f);
	if(f->elog.type!=Null && q0<f->elog.q0){
		if(warned++ == 0)
			warning(nil, Wsequence);
		elogflush(f);
	}
	/* try to merge with previous */
	gap = q0 - (f->elog.q0+f->elog.nd);	/* gap between previous and this */
	if(f->elog.type==Replace && f->elog.nr+gap+nr<Maxstring){
		if(gap < Minstring){
			if(gap > 0){
				bufread(&f->b, f->elog.q0+f->elog.nd, f->elog.r+f->elog.nr, gap);
				f->elog.nr += gap;
			}
			f->elog.nd += gap + q1-q0;
			runemove(f->elog.r+f->elog.nr, r, nr);
			f->elog.nr += nr;
			return;
		}
	}
	elogflush(f);
	f->elog.type = Replace;
	f->elog.q0 = q0;
	f->elog.nd = q1-q0;
	f->elog.nr = nr;
	if(nr > RBUFSIZE)
		editerror("internal error: replacement string too large(%d)", nr);
	runemove(f->elog.r, r, nr);
}

void
eloginsert(File *f, int q0, Rune *r, int nr)
{
	int n;

	if(nr == 0)
		return;
	eloginit(f);
	if(f->elog.type!=Null && q0<f->elog.q0){
		if(warned++ == 0)
			warning(nil, Wsequence);
		elogflush(f);
	}
	/* try to merge with previous */
	if(f->elog.type==Insert && q0==f->elog.q0 && f->elog.nr+nr<Maxstring){
		runemove(f->elog.r+f->elog.nr, r, nr);
		f->elog.nr += nr;
		return;
	}
	while(nr > 0){
		elogflush(f);
		f->elog.type = Insert;
		f->elog.q0 = q0;
		n = nr;
		if(n > RBUFSIZE)
			n = RBUFSIZE;
		f->elog.nr = n;
		runemove(f->elog.r, r, n);
		r += n;
		nr -= n;
	}
}

void
elogdelete(File *f, int q0, int q1)
{
	if(q0 == q1)
		return;
	eloginit(f);
	if(f->elog.type!=Null && q0<f->elog.q0+f->elog.nd){
		if(warned++ == 0)
			warning(nil, Wsequence);
		elogflush(f);
	}
	/* try to merge with previous */
	if(f->elog.type==Delete && f->elog.q0+f->elog.nd==q0){
		f->elog.nd += q1-q0;
		return;
	}
	elogflush(f);
	f->elog.type = Delete;
	f->elog.q0 = q0;
	f->elog.nd = q1-q0;
}

#define tracelog 0
void
elogapply(File *f)
{
	Buflog b;
	Rune *buf;
	uint i, n, up, mod;
	uint tq0, tq1;
	Buffer *log;
	Text *t;
	int owner;

	elogflush(f);
	log = f->elogbuf;
	t = f->curtext;

	buf = fbufalloc();
	mod = FALSE;

	owner = 0;
	if(t->w){
		owner = t->w->owner;
		if(owner == 0)
			t->w->owner = 'E';
	}

	/*
	 * The edit commands have already updated the selection in t->q0, t->q1,
	 * but using coordinates relative to the unmodified buffer.  As we apply the log,
	 * we have to update the coordinates to be relative to the modified buffer.
	 * Textinsert and textdelete will do this for us; our only work is to apply the
	 * convention that an insertion at t->q0==t->q1 is intended to select the 
	 * inserted text.
	 */

	/*
	 * We constrain the addresses in here (with textconstrain()) because
	 * overlapping changes will generate bogus addresses.   We will warn
	 * about changes out of sequence but proceed anyway; here we must
	 * keep things in range.
	 */

	while(log->nc > 0){
		up = log->nc-Buflogsize;
		bufread(log, up, (Rune*)&b, Buflogsize);
		switch(b.type){
		default:
			fprint(2, "elogapply: 0x%ux\n", b.type);
			abort();
			break;

		case Replace:
			if(tracelog)
				warning(nil, "elog replace %d %d (%d %d)\n",
					b.q0, b.q0+b.nd, t->q0, t->q1);
			if(!mod){
				mod = TRUE;
				filemark(f);
			}
			textconstrain(t, b.q0, b.q0+b.nd, &tq0, &tq1);
			textdelete(t, tq0, tq1, TRUE);
			up -= b.nr;
			for(i=0; i<b.nr; i+=n){
				n = b.nr - i;
				if(n > RBUFSIZE)
					n = RBUFSIZE;
				bufread(log, up+i, buf, n);
				textinsert(t, tq0+i, buf, n, TRUE);
			}
			if(t->q0 == b.q0 && t->q1 == b.q0)
				t->q1 += b.nr;
			break;

		case Delete:
			if(tracelog)
				warning(nil, "elog delete %d %d (%d %d)\n",
					b.q0, b.q0+b.nd, t->q0, t->q1);
			if(!mod){
				mod = TRUE;
				filemark(f);
			}
			textconstrain(t, b.q0, b.q0+b.nd, &tq0, &tq1);
			textdelete(t, tq0, tq1, TRUE);
			break;

		case Insert:
			if(tracelog)
				warning(nil, "elog insert %d %d (%d %d)\n",
					b.q0, b.q0+b.nr, t->q0, t->q1);
			if(!mod){
				mod = TRUE;
				filemark(f);
			}
			textconstrain(t, b.q0, b.q0, &tq0, &tq1);
			up -= b.nr;
			for(i=0; i<b.nr; i+=n){
				n = b.nr - i;
				if(n > RBUFSIZE)
					n = RBUFSIZE;
				bufread(log, up+i, buf, n);
				textinsert(t, tq0+i, buf, n, TRUE);
			}
			if(t->q0 == b.q0 && t->q1 == b.q0)
				t->q1 += b.nr;
			break;

/*		case Filename:
			f->seq = u.seq;
			fileunsetname(f, epsilon);
			f->mod = u.mod;
			up -= u.n;
			free(f->name);
			if(u.n == 0)
				f->name = nil;
			else
				f->name = runemalloc(u.n);
			bufread(delta, up, f->name, u.n);
			f->nname = u.n;
			break;
*/
		}
		bufdelete(log, up, log->nc);
	}
	fbuffree(buf);
	elogterm(f);
	
	/*
	 * Bad addresses will cause bufload to crash, so double check.
	 * If changes were out of order, we expect problems so don't complain further.
	 */
	if(t->q0 > f->b.nc || t->q1 > f->b.nc || t->q0 > t->q1){
		if(!warned)
			warning(nil, "elogapply: can't happen %d %d %d\n", t->q0, t->q1, f->b.nc);
		t->q1 = min(t->q1, f->b.nc);
		t->q0 = min(t->q0, t->q1);
	}

	if(t->w)
		t->w->owner = owner;
}
