/*
	This enables me to draw text with help of the pvr, with all its merits(zooming, rotation(not implemented by now, due to excessive laziness ;-)), whatever ;-));
	Ok, i admit it, the only advantage i actually implemented is the ability to zoom ;-);
	It can eighter use the built in bios font or a bitmap font provided in the following format:
	8 rows of 16 equally sized characters each ;-);.
	A big thank you to speud and BlackAura for this 8 year old topic at dcemulation ;-)
	http://www.dcemulation.org/phpBB/viewtopic.php?f=29&t=45823&view=next
*/

namespace kos_gfx
{
	namespace pvr
	{
		namespace font
		{
			kos_gfx::pvr::texture_fragment default_font;
			
			int char_w, char_h;
			
			void init(kos_gfx::pvr::texture_fragment buffer, bool use_bios_font=true)
			{
				default_font=buffer;
				char_w=buffer.w/16;
				char_h=buffer.h/8;
				
				//renders the bios font to the texture_fragment;
				//has very odd results if you use a twiddled texture, so better dont try this ;-);
				if(use_bios_font)
				{
					char_w=12;
					char_h=24;
					
					if(buffer.w<192 || buffer.h<192)
					{
						printf("Font texture too small, text rendering wont work\n");
						return;
					};
					
					kos_gfx::Uint16 *target=(kos_gfx::Uint16*)default_font.tex.tex;
					target+=default_font.x;
					target+=default_font.y*default_font.tex.w;
					
					for(int y=0;y<8;++y)
					{
						kos_gfx::Uint16 *target_tmp=target;
						for(int x=0;x<16;++x)
						{
							bfont_draw(target_tmp,default_font.tex.w,0,y*16+x);
							target_tmp+=char_w;
						};
						target+=default_font.tex.w*char_h;
					};
				};
			};
			
			void shutdown()
			{
				//nothing here, exists just in case it might be needed sometime ;-);
			};
			
			void draw(std::string txt, int x, int y, int char_width=char_w, int char_height=char_h, int spacing=4, bool centered=false, kos_gfx::pvr::color col=PVR_PACK_COLOR(1,1,1,1))
			{
				//Create and send a header, this one does not change, therefore there is no need to send it more than once per string ;-);
				//The list may change so, therefore a recreation is needed upon calling this function, propably suboptimal, sorry ;-);
				pvr_poly_hdr_t hdr;
				pvr_poly_cxt_t cxt;
				pvr_vertex_t vertex;
				
				pvr_poly_cxt_txr(&cxt,kos_gfx::pvr::active_list_type,PVR_TXRFMT_ARGB4444 | PVR_TXRFMT_NONTWIDDLED,default_font.tex.w,default_font.tex.h,default_font.tex.tex,PVR_FILTER_NONE);
				pvr_poly_compile(&hdr,&cxt);
				pvr_prim(&hdr,sizeof(hdr));
				
				x=centered?(x-txt.size()*(char_width+spacing)/2):x;
				
				int original_x=x;
				
				for(int i=0;i<txt.size();++i)
				{
					if(txt[i]=='\n')
					{
						y+=(char_h+char_h/2);
						x=original_x;
						continue;
					};
					
					kos_gfx::math::vector2d<> char_pos(default_font.x+(txt[i]%16)*char_w,default_font.y+(txt[i]/16)*char_h);
				
					float u_min=char_pos.x/(float)default_font.tex.w;
					float u_max=(char_pos.x+char_w)/(float)default_font.tex.w;
					float v_min=char_pos.y/(float)default_font.tex.h;
					float v_max=(char_pos.y+char_h)/(float)default_font.tex.h;
						
					vertex.flags=PVR_CMD_VERTEX;
					vertex.x=x;
					vertex.y=y;
					vertex.z=kos_gfx::pvr::z_val;
					vertex.u=u_min;
					vertex.v=v_min;
					vertex.argb=col;
					vertex.oargb=0;
				
					pvr_prim(&vertex,sizeof(vertex));
				
					vertex.x+=char_width;
					vertex.u=u_max;
					pvr_prim(&vertex,sizeof(vertex));
				
					vertex.y+=char_height;
					vertex.v=v_max;
					pvr_prim(&vertex,sizeof(vertex));
				
					vertex.x-=char_width;
					vertex.u=u_min;
					pvr_prim(&vertex,sizeof(vertex));
				
					vertex.flags=PVR_CMD_VERTEX_EOL;
					vertex.y-=char_height;
					vertex.v=v_min;
					pvr_prim(&vertex,sizeof(vertex));
				
					++kos_gfx::pvr::z_val;
					
					//move right to draw the next character ;-);
					x+=(char_width+spacing);
				};
			};
			
			//propably a very suboptimal conversion, however it seems to work good enough ;-);
			void draw(unsigned int number, int x, int y,int char_width=char_w, int char_height=char_h, int spacing=4, bool centered=false,bool right_aligned=false,kos_gfx::pvr::color col=PVR_PACK_COLOR(1,1,1,1))
			{
				std::string tmp;
				tmp.reserve(20);
				do
				{
					tmp=char('0'+number%10)+tmp;
					number/=10;
				}
				while(number!=0);
				draw(tmp,x-(right_aligned?tmp.size()*(spacing+char_width):0),y,char_width,char_height,spacing,centered,col);
			};
			
		};
		
	};
};
