/* $VER: WBStars_plot.c 2.0b5 (18 Jan 1998)
*/

#include <exec/types.h>
#include <exec/memory.h>
#include <intuition/intuition.h>
#include <proto/exec.h>
#include <clib/alib_protos.h>
#include <clib/macros.h>

#include "WBStars_plot.h"

struct Flake
{
	struct Flake	*next;
	struct Flake	*last;
	int	x;
	int	y;
	int	sticky;
	int	dir;
	char	drawn;
	char	color;
	char	plane;
	char	plane_cnt;
};

void	NewFlake( void );
void	ClearFlake(struct Flake *f);

void		*pool		= NULL;
struct Flake	*Flakes		= NULL;
int 		Flake_cnt	= 0;
int		winddir		= 0;

void	InitObjects()
{
	pool=CreatePool(MEMF_ANY,2000,2000);
}

void	NewFlake()
{
	struct Flake	*f;

	if( pool && ((Max_Objects<0)||(Flake_cnt<Max_Objects)) && (f=(struct Flake*)AllocPooled(pool,sizeof(struct Flake))) )
	{
		f->next		= Flakes;
		if( Flakes!=NULL ) Flakes->last	= f;
		f->last		= NULL;
		f->x		= RangeRand(width);
		f->y		= 0;
		f->sticky	= 0;
		f->drawn	= FALSE;
		f->plane	= RangeRand(Planes)+1;
		f->plane_cnt	= 0;
		Flakes		= f;
		Flake_cnt++;
	}
}

void	ClearFlake(struct Flake *f)
{
	if( f->next!=NULL ) f->next->last=f->last;
	if( f->last!=NULL )
	{
		f->last->next=f->next;
	}
	else
	{
		Flakes=f->next;
	}
	FreePooled( pool, f, sizeof(struct Flake) );
	Flake_cnt--;
}

void	ClearObjects()
{
	while( Flakes!=NULL )
	{
		ClearPixel(Flakes->x,Flakes->y,Flakes->color);

		Flakes=Flakes->next;
	}
	DeletePool(pool);
	Flake_cnt=0;
}

void	PlotObjects()
{
	struct Flake	*f;
	struct Flake	*next;
	int		newx;
	int		newy;
	int		addx;
	char		v_flut;
	char		color;

	if(RangeRand(500)==0) winddir=Wind*(RangeRand(5)-2);

	if(RangeRand(few_Flakes)==0) NewFlake();

	LockPlotArea();

	for(f=Flakes; f!=NULL; f=next)
	{
		next= f->next;

		if( ((f->plane_cnt++)%f->plane)==0 )
		{
			if( (!(f->sticky) || (Max_Stick>=0)) &! (f->sticky%Check_Stick) )
			{
				if( (RangeRand((V_Flutter)+100)<100) || f->sticky )
				{
					newy	= f->y +1;
					v_flut	= FALSE;
				}
				else
				{
					newy	= f->y;
					v_flut	= TRUE;
				}
	
				if(winddir)
				{
					if( f->dir==0 )
					{
						addx	= SIGN(winddir)*SIGN(RangeRand(ABS(winddir)+1)-ABS(winddir));
					}
					else
					{
						addx	= RangeRand(2)*SIGN(f->dir);
					}
				}
				else
				{
					if( f->dir==0 )
					{
						addx	= RangeRand(3) -1;
					}
					else
					{
						addx	= RangeRand(2)*SIGN(f->dir);
					}
				}

				newx		= f->x +addx;
	
	
				if( (newy>=height) || (newx<0) || (newx>=width) )
				{
					if(f->drawn) ClearPixel(f->x,f->y,f->color);
					ClearFlake(f);
				}
				else
				{
					if( (color=SetPixel(newx,newy,Force))!=-1 )
					{
						if(f->drawn) ClearPixel(f->x,f->y,f->color);
						f->x		= newx;
						f->y		= newy;
						f->sticky	= 0;
						f->drawn	= TRUE;
						f->dir		= addx;
						f->color	= color;
					}
					else
					{
						if( !v_flut )
						{
							f->dir		= 0;
							if( (color=SetPixel(f->x,newy,Force))!=-1 )
							{
								if(f->drawn) ClearPixel(f->x,f->y,f->color);
								f->y		= newy;
								f->sticky	= 0;
								f->drawn	= TRUE;
								f->color	= color;
							}
							else
							{
								if( !f->drawn )
								{
									ClearFlake(f);
								}
								else
								{
									if( Remember || Test1Pixel(f->x,f->y) )
									{
										if( ((f->sticky++)>Max_Stick) && (Max_Stick>=0) )
										{
											ClearPixel(f->x,f->y,f->color);
											ClearFlake(f);
										}
									}
									else
									{
										ClearFlake(f);
									}
								}
							}
						}
					}
				}
			}else	f->sticky++;
		}
	}
	UnlockPlotArea();
}
