// Common, group Parsing
// Copyright Alexander Liss

#include <string.h>
#include "strtokens.h"
#include "strblocks.h"


		// StrBlocks


int StrBlocks::parse(const char * str)
{
	int g=0;
	g=data.set(str);
	if(g) return 1;
	return start();
}

int StrBlocks::parse(const char * d,int s)
{
	int g=0;
	g=data.set(d,s);
	if(g) return 1;
	return start();
}

int StrBlocks::translate_parse(const char * str,const char *from,char to)
{
	int g=0;
	g=data.set(str);
	if(g) return 1;
	g=translate_char(data.data,from,to);
	if(g) return 2;
	return start();
}

int StrBlocks::shrink_parse(const char * str,const char *from,char to,bool drop_ends)
{
	int g=0;
	g=data.set(str);
	if(g) return 1;
	g=shrink_char(data.data,from,to,drop_ends);
	if(g) return 2;
	return start();
}

int StrBlocks::get_next(int& z,StrBuffer& dest)
{
	if(shift_buffer.data_size<=0)
	{
		z=-1;
		return 1;
	}

	if(have_block)
	{
		z=next_index;
		int r=block_data[z].before.data_size;
		dest.set(shift_buffer.data+r,next_after-r);
		shift_buffer.shift(next_after+block_data[z].after.data_size);
		have_block=false;
		next_index=-1;
		next_after=0;
		return 0;
	}

	int g=0,index=-1,before=shift_buffer.data_size,after=-1;

	for(int i=0;i<block_data.in_object();++i)
	{
		int b=0,a=0;
		g=match(b,a,block_data[i]);
		
		if(!g && b<before)
		{
			index=i;
			before=b;
			after=a;
		}
	}

	if(index==-1)
	{
		dest.set(shift_buffer);
		shift_buffer.shift(shift_buffer.data_size);
	}
	else if(before>0)
	{
		z=-1;
		next_index=index;
		next_after=after-before;
		have_block=true;
		dest.set(shift_buffer.data,before);
		shift_buffer.shift(before);
	}
	else
	{
		z=index;
		int r=block_data[z].before.data_size;
		dest.set(shift_buffer.data+r,after-r);
		shift_buffer.shift(after+block_data[z].after.data_size);
	}

	return 0;
}


int StrBlocks::start()
{
	if(!block_data.in_object()) return 1;

	shift_buffer.set(data);
	next_index=-1;
	next_after=0;
	have_block=false;
	
	return 0;
}

int StrBlocks::match(int& before,int& after, const BlockDataUnit& u)
{

	char *s=strstr(shift_buffer.data,u.before.data);

	if(!s) return 1;

	char *s1=strstr(shift_buffer.data+u.before.data_size,u.after.data);

	if(!s1) return 1;

	before=s-shift_buffer.data;
	after=s1-shift_buffer.data;

	return 0;
}