#include <v_lib.h>

#define MAX_WIDTH	1024
#define MAX_HEIGHT	1024

u32_t width, height,num_frames,frame;

u8_t samples[MAX_WIDTH * MAX_HEIGHT * 4];
#define pset(x,y,r,g,b) \
	{ \
		u8_t rc = CLAMP_FLOAT_TO_BYTE(r); \
		u8_t gc = CLAMP_FLOAT_TO_BYTE(g); \
		u8_t bc = CLAMP_FLOAT_TO_BYTE(b); \
		u8_t *ptr = samples + (((x) + (y) * width)<<2); \
		*(ptr++) = rc; *(ptr++) = gc; *(ptr++) = bc; \
	}

#define clear_frame() memZero(samples,width*height*4)

/*
 * PGEN
 */
vec_t sinewave_radial(vec2_t center,vec2_t point,vec_t wavelen,vec_t spd,vec_t curtime)
{
	vec_t dphase;
	vec2_t dist;
	vec2Sub(dist,center,point);
	dphase = 2 * M_PI * vec2Abs(dist) / wavelen;
	return sin(dphase - spd * curtime);
}

#define NUM_WAVES	5
vec2_t wave_centers[NUM_WAVES] =
{
	{128,128},
	{20,20},
	{236,20},
	{20,236},
	{236,236}
};

vec_t wave_len[NUM_WAVES] = {20,40,40,40,40};
vec_t wave_spd[NUM_WAVES] = {-1,2,2,2,2};
vec_t waves[NUM_WAVES];

void calc_waves(vec2_t curpoint,vec_t curtime)
{
	u32_t i;
	for(i=0;i<NUM_WAVES;i++)
		waves[i] = sinewave_radial(
			wave_centers[i],curpoint,wave_len[i],wave_spd[i],curtime);
}
		
void pgen(u32_t x,u32_t y,vec2_t curpoint)
{
	vec_t r,g,b;
	calc_waves(curpoint,0.03 * frame);
	r = 50 * waves[0] + 30 * waves[1] + 30 * waves[2] - 20 * waves[3] - 20 * waves[4];
	g = 30 * waves[0] + 40 * waves[1] + 40 * waves[2] + 40 * waves[3] + 40 * waves[4];
	b = 50 * waves[0] - 30 * waves[1] - 30 * waves[2] + 20 * waves[3] + 20 * waves[4];
	pset(x,y,r+128,g+128,b+128);
}

void gen_frame(void)
{
	u32_t x,y;
	vec2_t v;
	clear_frame();
	for(y=0;y<height;y++)
		for(x=0;x<width;x++)
		{
			vec2Set(v,x,y);
			pgen(x,y,v);
		}
}
	
int main()
{
	width = 64;
	height = 64;
	num_frames = 300;
	logStartConsoleLog();
	logUpperLevel(LOG_TRACE);
	conPrintf("Generating %u frames ...\n",num_frames);
	for(frame = 0;frame < num_frames;frame++)
	{
		char buf[256];
		gen_frame();
		logFormatString(buf,"frame%04u.tga",frame);
		tgaSave(buf,width,height,samples);
		conPrintf("frame %u done ...\n",frame);
	}
	return 0;
}
