/******************************************************************************
*******************************************************************************

	Space Impakto DS
	relminator
	http://rel.betterwebber.com


	Cbullet class


*******************************************************************************
******************************************************************************/


#include <nds.h>

#include "Cvector2df32.h"
#include "cearn_atan.h"
#include "Cglsprite.h"
#include "Cobject.h"
#include "Cgl2d.h"


#ifndef Cbullet__H
#define Cbullet__H

#define  MAX_BULLETS 512
#define  MAX_BULLETS_M1 511

#define  BRAD_PI 16384 

#define  B_MIN_X (-20 << 12)
#define  B_MIN_Y (-20 << 12)
#define  B_MAX_X (256 << 12)
#define  B_MAX_Y (192 << 12)



static const int FRICTION = (0.0042) * (1 << 12);
static const int INVFRICTION = (0.968) * (1 << 12);

enum E_BULLET_TYPE
{
	EB_NORMAL = 1,
	EB_ACCEL,
	EB_INVACCEL 
};


class Cbullet : public Cobject
{
	public:
	
	Cbullet();
	Cbullet(int _x, int _y);
	
	
	void update();
	void set_state(E_BULLET_TYPE _state);
	void (*do_state)(Cbullet *b);	
	
	s32				speed;
	s32 			dx_old;
	s32 			dy_old;
	
	s32 			gx;			// gravity
	s32				gy;
	
	s32 			x_accel;	// acceleration
	s32				y_accel;
	
	int 			counter;
	int 			energy;
	int 			delay;		// for changing behavior. ie: normal to target (note that EB_NORMAL can be targeting at start via turret)
	E_BULLET_TYPE	state;		// normal, accelerator or inv accelerator
	bool			smart;		// targeting or not (after counter == delay); 			
	s32 			rotation;	// for gl2d rotate
	int				death_ID;
	
	Cvector2df32	*target;
};

class Cbullet_array
{

	public:
	inline Cbullet_array();
	
	inline void update();
	inline void render_bullets(Cglsprite *sprites);
	inline void draw_aabb(Cgl2d &gl2d);
	
	int		active_bullets;
	int 	num_bullets;
	Cbullet p_bullets[MAX_BULLETS];
	
};


Cbullet_array::Cbullet_array()
{
	active_bullets = 0;
	num_bullets = MAX_BULLETS;
}

void Cbullet_array::update()
{
	// update bullets
	active_bullets = 0;
	for (int i=0; i < MAX_BULLETS; i++)
	{
		if (p_bullets[i].active) 
		{
			p_bullets[i].update();
			active_bullets++;
		}
	}
	
}
void Cbullet_array::render_bullets(Cglsprite *sprites)
{
	
	for (int i=0; i < MAX_BULLETS; i++)
	{
		if (p_bullets[i].active) sprites[p_bullets[i].start_frame + p_bullets[i].frame].render(p_bullets[i].x >> 12, p_bullets[i].y >> 12);
	}

}

void Cbullet_array::draw_aabb(Cgl2d &gl2d)
{
	
	for (int i=0; i < MAX_BULLETS; i++)
	{
		if (p_bullets[i].active)
		{
			int x1 = p_bullets[i].box.x1;
			int y1 = p_bullets[i].box.y1;
			int x2 = p_bullets[i].box.x2;
			int y2 = p_bullets[i].box.y2;
			gl2d.box(x1, y1, x2, y2, ARGB16(1,31,0,0));
		}
	}

}

#endif
