#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"

enum
{
	None = 0,
	Fore = '+',
	Back = '-'
};

enum
{
	Char,
	Line
};

int
isaddrc(int r)
{
	if(r && utfrune("0123456789+-/$.#,;", r)!=nil)
		return TRUE;
	return FALSE;
}

/*
 * quite hard: could be almost anything but white space, but we are a little conservative,
 * aiming for regular expressions of alphanumerics and no white space
 */
int
isregexc(int r)
{
	if(r == 0)
		return FALSE;
	if(isalnum(r))
		return TRUE;
	if(utfrune("^+-.*?#,;[]()$", r)!=nil)
		return TRUE;
	return FALSE;
}

Range
number(uint showerr, Text *t, Range r, int line, int dir, int size, int *evalp)
{
	uint q0, q1;

	if(size == Char){
		if(dir == Fore)
			line = r.q1+line;
		else if(dir == Back){
			if(r.q0==0 && line>0)
				r.q0 = t->file->b.nc;
			line = r.q0 - line;
		}
		if(line<0 || line>t->file->b.nc)
			goto Rescue;
		*evalp = TRUE;
		return range(line, line);
	}
	q0 = r.q0;
	q1 = r.q1;
	switch(dir){
	case None:
		q0 = 0;
		q1 = 0;
	Forward:
		while(line>0 && q1<t->file->b.nc)
			if(textreadc(t, q1++) == '\n' || q1==t->file->b.nc)
				if(--line > 0)
					q0 = q1;
		if(line > 0)
			goto Rescue;
		break;
	case Fore:
		if(q1 > 0)
			while(q1<t->file->b.nc && textreadc(t, q1-1) != '\n')
				q1++;
		q0 = q1;
		goto Forward;
	case Back:
		if(q0 < t->file->b.nc)
			while(q0>0 && textreadc(t, q0-1)!='\n')
				q0--;
		q1 = q0;
		while(line>0 && q0>0){
			if(textreadc(t, q0-1) == '\n'){
				if(--line >= 0)
					q1 = q0;
			}
			--q0;
		}
		if(line > 0)
			goto Rescue;
		while(q0>0 && textreadc(t, q0-1)!='\n')
			--q0;
	}
	*evalp = TRUE;
	return range(q0, q1);

    Rescue:
	if(showerr)
		warning(nil, "address out of range\n");
	*evalp = FALSE;
	return r;
}


Range
regexp(uint showerr, Text *t, Range lim, Range r, Rune *pat, int dir, int *foundp)
{
	int found;
	Rangeset sel;
	int q;

	if(pat[0] == '\0' && rxnull()){
		if(showerr)
			warning(nil, "no previous regular expression\n");
		*foundp = FALSE;
		return r;
	}
	if(pat[0] && rxcompile(pat) == FALSE){
		*foundp = FALSE;
		return r;
	}
	if(dir == Back)
		found = rxbexecute(t, r.q0, &sel);
	else{
		if(lim.q0 < 0)
			q = Infinity;
		else
			q = lim.q1;
		found = rxexecute(t, nil, r.q1, q, &sel);
	}
	if(!found && showerr)
		warning(nil, "no match for regexp\n");
	*foundp = found;
	return sel.r[0];
}

Range
address(uint showerr, Text *t, Range lim, Range ar, void *a, uint q0, uint q1, int (*getc)(void*, uint),  int *evalp, uint *qp)
{
	int dir, size, npat;
	int prevc, c, nc, n;
	uint q;
	Rune *pat;
	Range r, nr;

	r = ar;
	q = q0;
	dir = None;
	size = Line;
	c = 0;
	while(q < q1){
		prevc = c;
		c = (*getc)(a, q++);
		switch(c){
		default:
			*qp = q-1;
			return r;
		case ';':
			ar = r;
			/* fall through */
		case ',':
			if(prevc == 0)	/* lhs defaults to 0 */
				r.q0 = 0;
			if(q>=q1 && t!=nil && t->file!=nil)	/* rhs defaults to $ */
				r.q1 = t->file->b.nc;
			else{
				nr = address(showerr, t, lim, ar, a, q, q1, getc, evalp, &q);
				r.q1 = nr.q1;
			}
			*qp = q;
			return r;
		case '+':
		case '-':
			if(*evalp && (prevc=='+' || prevc=='-'))
				if((nc=(*getc)(a, q))!='#' && nc!='/' && nc!='?')
					r = number(showerr, t, r, 1, prevc, Line, evalp);	/* do previous one */
			dir = c;
			break;
		case '.':
		case '$':
			if(q != q0+1){
				*qp = q-1;
				return r;
			}
			if(*evalp)
				if(c == '.')
					r = ar;
				else
					r = range(t->file->b.nc, t->file->b.nc);
			if(q < q1)
				dir = Fore;
			else
				dir = None;
			break;
		case '#':
			if(q==q1 || (c=(*getc)(a, q++))<'0' || '9'<c){
				*qp = q-1;
				return r;
			}
			size = Char;
			/* fall through */
		case '0': case '1': case '2': case '3': case '4':
		case '5': case '6': case '7': case '8': case '9':
			n = c -'0';
			while(q<q1){
				c = (*getc)(a, q++);
				if(c<'0' || '9'<c){
					q--;
					break;
				}
				n = n*10+(c-'0');
			}
			if(*evalp)
				r = number(showerr, t, r, n, dir, size, evalp);
			dir = None;
			size = Line;
			break;
		case '?':
			dir = Back;
			/* fall through */
		case '/':
			npat = 0;
			pat = nil;
			while(q<q1){
				c = (*getc)(a, q++);
				switch(c){
				case '\n':
					--q;
					goto out;
				case '\\':
					pat = runerealloc(pat, npat+1);
					pat[npat++] = c;
					if(q == q1)
						goto out;
					c = (*getc)(a, q++);
					break;
				case '/':
					goto out;
				}
				pat = runerealloc(pat, npat+1);
				pat[npat++] = c;
			}
		    out:
			pat = runerealloc(pat, npat+1);
			pat[npat] = 0;
			if(*evalp)
				r = regexp(showerr, t, lim, r, pat, dir, evalp);
			free(pat);
			dir = None;
			size = Line;
			break;
		}
	}
	if(*evalp && dir != None)
		r = number(showerr, t, r, 1, dir, Line, evalp);	/* do previous one */
	*qp = q;
	return r;
}
