/*	VGRFILL.c - Routine to fill an outline in a bit map.

DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! 
*****************************************************************************
*	                     NOTE CAREFULLY:                                *
*****************************************************************************
*	           This function uses ***LOTS***                            *
*	     of stack space!!! ie: count on up to about 10K                 *
*	     for every 100 levels of call nesting, with a                   *
*	     possibility of >200 levels being reached!!!                    *
*****************************************************************************
DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! DANGER! 
*/


#include "lib.h"
#include "vgr.h"


#ifdef __STDC__
void vgr_fill(int x,int y,int color);
static void _fill_y(int x,int y,int yinc);
static void _fill_x(int x,int y);
static int __fill_x(int x,int y,int xinc);
#else
void vgr_fill();
static void _fill_y();
static void _fill_x();
static int __fill_x();
#endif

static unsigned char _color, _search;
static int _set_cnt, _up_cnt, _dn_cnt, _y_ok;


void vgr_fill( x, y, color )
int x, y, color;
{
	if ( (_search = VGR_GET( x, y )) == (_color = color) )
	   return;

	_fill_y( x, y+1,  1 );
	_fill_y( x, y  , -1 );
}


static void _fill_y( x, y, yinc )
int x, y, yinc;
{
	for ( ; y >= 0 && y < VGR_VRES; y += yinc )
	   if ( _search == VGR_GET( x, y ) )
	      _fill_x( x, y );
	   else return;
}


static void _fill_x( x, y )
int x, y;
{
	int i, l, h, u, d, c;
	void _fill_y();

#ifdef DEBUG
	static int depth;
	
	putcur(0,0);
	printf("%d  ", ++depth );
	if ( constat() )
	   if ( conin() == 27 )
	   {  video_mode(3);
	      exit(1);
	   };
#endif
	_set_cnt = _up_cnt = _dn_cnt = 0;
	_y_ok = ( (y >= 1) && (y < (VGR_VRES-1)) );

	h = __fill_x( x+1, y,  1 );
	l = __fill_x( x  , y, -1 );

	/* The purpose of the following code is to prevent 
	   excessive call nesting. It can be removed, but 
	   the resulting several thousand useless function 
	   calls slow down processing considerably, as well 
	   as killing the system when SP rolls over...
	*/

	if ( !_y_ok )
	{
#ifdef DEBUG
	   depth--;
#endif
	   return;
	};

	c = _set_cnt;
	u = _up_cnt;
	d = _dn_cnt;

	if ( c != u )
	   for ( i = l+1; i <= h-1; i++ )
	      if ( _search == VGR_GET( i, y-1 ) )
	         _fill_y( i, y-1, -1 );

	if ( c != d )
	   for ( i = l+1; i <= h-1; i++ )
	      if ( _search == VGR_GET( i, y+1 ) )
	         _fill_y( i, y+1,  1 );
#ifdef DEBUG
	depth--;
#endif
}


static int __fill_x( x, y, xinc )
int x, y, xinc;
{
	for ( ; x >= 0 && x < VGR_HRES; x += xinc )
	   if ( _search == VGR_GET( x, y ) )
	   {  VGR_SET( x, y, _color ); 
	      _set_cnt++;

	      if ( _y_ok )
	      {  if ( _search == VGR_GET(x,y-1) )
	            _up_cnt++;
	         if ( _search == VGR_GET(x,y+1) )
	            _dn_cnt++;
	      };
	   } else return x;
}


