/*
	This is the only actual enemy in game and the ai is, to put it nicely, rather simple ;-);
	It gets stronger whenever it is revived, it gets more life, stronger missiles and shoots faster ;-);
	However not in this order, see the revive method for more details ;-);
	* 
	It actually has a lot of duplicate code, many methods are exactly the same as some methods
	rectangle has and those two classes should propably have another common base ;-);
*/

namespace rectangle_battle
{
	class triangle:public rectangle_battle::collision_mgr::collision_obj
	{
		private:
		int start_x, start_y, start_w, start_h;
		double inner_w, inner_h;
		kos_gfx::pvr::color col;
		
		rectangle_battle::collision_mgr::collision_obj *target;
		int distance_x, distance_y;
		
		ORIENTATION orient;
		rectangle_battle::collision_mgr::element collision_elem;
		
		kos_gfx::sound::sfx::handle missile_sfx, missile_hit_sfx;
		kos_gfx::pvr::texture_fragment normal_missile_tex, special_missile_tex;
		
		std::list<basic_missile*> missiles;
		int number_of_active_missiles, number_of_max_missiles;
		int shot_delay_counter, shot_delay;
		int current_protection_points, max_protection_points;
		
		double max_speed;
		int maximum_max_shots, min_shot_delay;
		bool use_special_missiles;
		public:
		triangle()
		{
			max_speed=1;
			maximum_max_shots=20;
			min_shot_delay=20;
			use_special_missiles=false;
			
			collision_elem=rectangle_battle::collision_mgr::register_target(this);
		};
		
		triangle(rectangle_battle::collision_mgr::collision_obj *tar,int startx, int starty, double width, double height, double inner_width, double inner_height,kos_gfx::Uint8 r, kos_gfx::Uint8 g, kos_gfx::Uint8 b,ORIENTATION ori=UP,int dist_x=50, int dist_y=50)
		{
			max_speed=1;
			use_special_missiles=false;
			
			create(tar,startx,starty,width,height,inner_width,inner_height,r,g,b,ori,dist_x,dist_y);
			
			collision_elem=rectangle_battle::collision_mgr::register_target(this);
		};
		
		void create(rectangle_battle::collision_mgr::collision_obj *tar,int startx, int starty, double width, double height, double inner_width, double inner_height,kos_gfx::Uint8 r, kos_gfx::Uint8 g, kos_gfx::Uint8 b,ORIENTATION ori=UP, int dist_x=50, int dist_y=50)
		{
			free_missiles();
			
			missile_sfx=0;
			missile_hit_sfx=0;
			
			number_of_active_missiles=0;
			number_of_max_missiles=1;
			shot_delay_counter=0;
			shot_delay=100;
			current_protection_points=0;
			max_protection_points=0;
			use_special_missiles=false;
			
			dying=false;
			dead=false;
			dmg=1;
			
			start_x=startx;
			start_y=starty;
			start_w=width;
			start_h=height;
			
			distance_x=dist_x;
			distance_y=dist_y;
			
			target=tar;
			
			position.x=start_x;
			position.y=start_y;
			w=width;
			h=height;
			inner_w=inner_width;
			inner_h=inner_height;
			orient=ori;
			col=PVR_PACK_COLOR(1,((double)r)/255,((double)g)/255,((double)b)/255);
		};
		
		~triangle()
		{
			free_missiles();
			rectangle_battle::collision_mgr::unregister_target(collision_elem);
		};
		
		void free_missiles()
		{
			for(std::list<basic_missile*>::iterator it=missiles.begin();it!=missiles.end();++it)
			{
				basic_missile *tmp=(*it);
				it=missiles.erase(it);
				--it;
				delete tmp;
				--number_of_active_missiles;
			};
		};
		
		void revive()
		{
			dying=false;
			dead=false;
			
			position.x=start_x;
			position.y=start_y;
			w=start_w;
			h=start_h;
			
			if(number_of_max_missiles<maximum_max_shots/2)
				++number_of_max_missiles;
			else if(shot_delay>2*min_shot_delay)
				shot_delay-=6;
			if(number_of_max_missiles<maximum_max_shots)
				++number_of_max_missiles;
			else if(shot_delay>min_shot_delay)
				shot_delay-=6;
			else if(!use_special_missiles)
				use_special_missiles=true;
			else
				++max_protection_points;
				
			current_protection_points=max_protection_points;
		};
		
		void set_sounds(kos_gfx::sound::sfx::handle miss,kos_gfx::sound::sfx::handle miss_hit)
		{
			missile_sfx=miss;
			missile_hit_sfx=miss_hit;
		};
		
		void set_missile_textures(kos_gfx::pvr::texture_fragment miss_tex, kos_gfx::pvr::texture_fragment special_miss_tex)
		{
			normal_missile_tex=miss_tex;
			special_missile_tex=special_miss_tex;
		};
		
		void move_to(double new_x, double new_y)
		{
			position.x=new_x>kos_gfx::pvr::TITLE_SAFE_LEFT?
				(new_x+w>kos_gfx::pvr::TITLE_SAFE_RIGHT?kos_gfx::pvr::TITLE_SAFE_RIGHT-w:new_x)
				:kos_gfx::pvr::TITLE_SAFE_LEFT;
			position.y=new_y>kos_gfx::pvr::TITLE_SAFE_TOP?
				(new_y+h>kos_gfx::pvr::TITLE_SAFE_BOTTOM?kos_gfx::pvr::TITLE_SAFE_BOTTOM-h:new_y)
				:position.y<kos_gfx::pvr::TITLE_SAFE_TOP?new_y:kos_gfx::pvr::TITLE_SAFE_TOP; //make sure it may fly towards the screen if spawned from above ;-); I copied this comment from the xbox version ;_; how lazy can you get? ;-);
		};
		
		void move(double mx,double my)
		{
			velocity.x=mx;
			velocity.y=my;
			move_to(position.x+mx,position.y+my);
		};
		
		void hit(rectangle_battle::collision_mgr::collision_obj *other)
		{
			double dmg=other->damage();
			
			//Triangles are way too primitive to collect items ;-);
			if(dmg<0)
				return;
			
			if(missile_hit_sfx!=0)
				kos_gfx::sound::sfx::play(missile_hit_sfx);
				
            if(dmg>2) //yeah, triangles are mean bastards with special protection ;-);
				dmg=2;
			else
				rectangle_battle::rectangle::points+=dmg*number_of_max_missiles;

			if(current_protection_points>0)
            {
				current_protection_points-=dmg;
				if(current_protection_points < 0)
				{
					w+=current_protection_points;
					h+=current_protection_points;
				};
			}
			else
			{
				w-=dmg;
				h-=dmg;
			};
			
			h=h<1?1:h;
			w=w<1?1:w;

			if(w<inner_w)
			{
				dead=true;
				rectangle_battle::rectangle::points+=2*number_of_max_missiles;
			};
		};
		
		void shoot()
		{
			if(number_of_active_missiles<number_of_max_missiles)
			{
				if(missile_sfx!=0)
					kos_gfx::sound::sfx::play(missile_sfx);
					
				if(use_special_missiles)
				{
					missiles.push_back(new basic_missile(special_missile_tex,
						position.x+(w/2)-5,position.y+(orient==UP?-20:h+20),10,10,velocity.x/4,velocity.y/4+(orient==UP?-2:2),0.2,2));
				}
				else
				{
					missiles.push_back(new basic_missile(normal_missile_tex,
						position.x+(w/2)-5,position.y+(orient==UP?-20:h+20),10,10,velocity.x/4,velocity.y/4+(orient==UP?-2:2),0.2));
				};
				++number_of_active_missiles;
			};
		};
		
		void update_missiles()
		{
			for(std::list<basic_missile*>::iterator it=missiles.begin();it!=missiles.end();++it)
			{
				if((*it)->dead)
				{
					basic_missile *tmp=(*it);
					it=missiles.erase(it);
					--it;
					delete tmp;
					--number_of_active_missiles;
				}
				else
					(*it)->update();
			};
		};
		
		void update()
		{
			update_missiles();
			
			if(dead)
				return;
				
			double mx=0, my=0;
			kos_gfx::math::vector2d<> tar_cent=target->center();
			
			if(tar_cent.x-(position.x+w/2)>distance_x)
				mx=max_speed;
			else if((position.x+w/2)-tar_cent.x>distance_x)
				mx=-max_speed;
				
			if(tar_cent.y-(position.y+h/2)>2*distance_y)
				my=max_speed;
			else if(tar_cent.y-(position.y+h/2)<distance_y)
				my=-max_speed;
			
			move(mx,my);
			
			++shot_delay_counter;
            shot_delay_counter%=shot_delay;
            if(shot_delay_counter==0)
                shoot();
		};
		
		void draw_missiles()
		{
			for(std::list<basic_missile*>::iterator it=missiles.begin();it!=missiles.end();++it)
			{
				(*it)->draw();
			};
		};
		
		void draw()
		{
			draw_missiles();
			
			if(dead)
				return;
				
			if(orient==DOWN)
			{
				kos_gfx::pvr::draw_triangle(position.x,position.y,position.x+w,position.y,position.x+w/2,position.y+h,110,110,110);
				kos_gfx::pvr::draw_triangle(position.x+w/2-inner_w/2,position.y,position.x+w/2+inner_w/2,position.y,position.x+w/2,position.y+inner_h,col);
			}
			else
			{
				kos_gfx::pvr::draw_triangle(position.x+w/2,position.y,position.x+w,position.y+h,position.x,position.y+h,110,110,110);
				kos_gfx::pvr::draw_triangle(position.x+w/2,position.y+h-inner_h,position.x+w/2+inner_w/2,position.y+h,position.x+w/2-inner_w/2,position.y+h,col);
			};
		};
	};
};
