--[[ Matches ]]
--
local function match_tostr(self)
	local spans = proxy[self].spans;
	local s_start, s_end = spans[0][1], spans[0][2];
	if s_end <= s_start then
		return string.format("Match (%d..%d, empty)", s_start, s_end - 1);
	end;
	return string.format("Match (%d..%d): %s", s_start, s_end - 1, utf8_sub(spans.input, s_start, s_end));
end;

local function new_match(span_arr, group_id, re, str)
	span_arr.source, span_arr.input = re, str;
	local object = newproxy(true);
	local object_mt = getmetatable(object);
	object_mt.__metatable = lockmsg;
	object_mt.__index = setmetatable(span_arr, match_m);
	object_mt.__tostring = match_tostr;

	proxy[object] = { name = "Match", spans = span_arr, group_id = group_id };
	return object;
end;

match_m.group = check_re('Match', 'group', function(self, group_id)
	local span = self.spans[type(group_id) == "number" and group_id or self.group_id[group_id]];
	if not span then
		return nil;
	end;
	return utf8_sub(self.spans.input, span[1], span[2]);
end);

match_m.span = check_re('Match', 'span', function(self, group_id)
	local span = self.spans[type(group_id) == "number" and group_id or self.group_id[group_id]];
	if not span then
		return nil;
	end;
	return span[1], span[2] - 1;
end);

match_m.groups = check_re('Match', 'groups', function(self)
	local spans = self.spans;
	if spans.n > 0 then
		local ret = table.create(spans.n);
		for i = 0, spans.n do
			local v = spans[i];
			if v then
				ret[i] = utf8_sub(spans.input, v[1], v[2]);
			end;
		end;
		return table.unpack(ret, 1, spans.n);
	end;
	return utf8_sub(spans.input, spans[0][1], spans[0][2]);
end);

match_m.groupdict = check_re('Match', 'groupdict', function(self)
	local spans = self.spans;
	local ret = { };
	for k, v in pairs(self.group_id) do
		v = spans[v];
		if v then
			ret[k] = utf8_sub(spans.input, v[1], v[2]);
		end;
	end;
	return ret;
end);

match_m.grouparr = check_re('Match', 'groupdict', function(self)
	local spans = self.spans;
	local ret = table.create(spans.n);
	for i = 0, spans.n do
		local v = spans[i];
		if v then
			ret[i] = utf8_sub(spans.input, v[1], v[2]);
		end;
	end;
	ret.n = spans.n;
	return ret;
end);
