namespace rectangle_battle
{
	/*
		What you are about to experience is nothing you should show your children, your parents, your grantparents
		or generally anyone frail of heart ;-);
		If you happen to eat or drink at this moment, better stop eighter this or reading this code.
		If someone is sleeping nearby, be aware that your shrieks of pain might disturb them and if you are emotinally
		unstable the last source code you read will most certainly be the last one that did not cause nightmares.
		You are still reading? Well, I warned you: This, my friends, is the hellish shower of magic numbers, 
		the code of doom, the epitome of awefulness:
		
		TL/DR: There is some really ugly code down here ;-)
	*/
	class virtual_keyboard
	{
		private:
		kos_gfx::pvr::texture_fragment keyboard, selector_small,selector_big;
		kos_gfx::math::vector2d<int> selector_positions[28]; //at least organize those aweful magic number in some way ;-);
		int pos_y;
		bool active, appearing, disappearing;
		int selection;
		
		std::string *txt;
		unsigned int max_length;
		
		int player_id;
		public:
		virtual_keyboard():active(false),appearing(false),disappearing(false),txt(NULL),max_length(10),selection(0),player_id(0)
		{};
		virtual_keyboard(kos_gfx::pvr::texture_fragment kb_tex,kos_gfx::pvr::texture_fragment sel_small_tex,kos_gfx::pvr::texture_fragment sel_big_tex,std::string *str, int max_str_length=10, int pl_id=0)
		{
			keyboard=kb_tex;
			selector_small=sel_small_tex;
			selector_big=sel_big_tex;
			
			txt=str;
			max_length=max_str_length;
			
			pos_y=kos_gfx::pvr::SCREEN_HEIGHT;
			active=false;
			appearing=false;
			disappearing=false;
			
			player_id=pl_id;
			
			selection=0;
			
			//You have been warned ;-);
			for(int i=0;i<26;++i)
				selector_positions[i]=kos_gfx::math::vector2d<int>((i<13?12:9)+(i%13)*(i<13?47:48),i>12?48:1);
			selector_positions[26]=kos_gfx::math::vector2d<int>(153,92);
			selector_positions[27]=kos_gfx::math::vector2d<int>(291,92);
		};
		
		void update()
		{
			if(disappearing)
			{
				pos_y+=2;
				if(pos_y>kos_gfx::pvr::SCREEN_HEIGHT)
					disappearing=false;
			}
			else if(appearing)
			{
				if(pos_y>(kos_gfx::pvr::SCREEN_HEIGHT-keyboard.w)) //width is height, due to the damn rotation ;-);
					pos_y-=2;
				else
				{
					active=true;
					appearing=false;
				};
			}
			else if(active)
			{
				if(kos_gfx::input::controllers[player_id].clicked_buttons&kos_gfx::input::BUTTON_LEFT)
				{
					--selection;
				}
				else if(kos_gfx::input::controllers[player_id].clicked_buttons&kos_gfx::input::BUTTON_RIGHT)
				{
					++selection;
				}
				else if(kos_gfx::input::controllers[player_id].clicked_buttons&kos_gfx::input::BUTTON_UP)
				{
					selection-=selection==27?8:13;
				}
				else if(kos_gfx::input::controllers[player_id].clicked_buttons&kos_gfx::input::BUTTON_DOWN)
				{
					selection+=13;
					selection=selection>26?(selection<32?26:27):selection;
				};
				selection=selection<0?0:selection>27?27:selection;
				
				if(selection<26 && txt->size()<max_length &&
				kos_gfx::input::controllers[player_id].clicked_buttons&kos_gfx::input::BUTTON_A)
				{
					txt->push_back((char)((txt->size()==0?'A':'a')+selection));
					kos_gfx::input::reset(player_id);
				};

				if(txt->size()!=0 && ((selection==27 &&
				kos_gfx::input::controllers[player_id].clicked_buttons&kos_gfx::input::BUTTON_A)
				|| kos_gfx::input::controllers[player_id].clicked_buttons&kos_gfx::input::BUTTON_B))
				{
					txt->erase(txt->size()-1);
					kos_gfx::input::reset(player_id);
				};
				
				if(kos_gfx::input::controllers[player_id].clicked_buttons&kos_gfx::input::BUTTON_START
				||
				(kos_gfx::input::controllers[player_id].clicked_buttons&kos_gfx::input::BUTTON_A && selection==26) //This should be the confirm button ;-) aweful, sorry ;-);
				)
				{
					disappearing=true;
					active=false;
					
					kos_gfx::input::reset(player_id);
				};
			}
			else if(kos_gfx::input::controllers[player_id].clicked_buttons&kos_gfx::input::BUTTON_B)
					appearing=true;
		};
		
		void draw()
		{
			if(active || appearing || disappearing)
			{
				kos_gfx::pvr::draw(keyboard,keyboard.h/2-keyboard.w/2,pos_y-(keyboard.h/2-keyboard.w/2),keyboard.w,keyboard.h,kos_gfx::math::PI/2); //The keyboard is rotated by 90 degrees in the texture, due to space constraints ;_;;
				//due to the rotation happening abround the images center, the coordinates have to be changed slightly ;-)
				//I told you this is ugly ;-);
				kos_gfx::pvr::draw(selection<26?selector_small:selector_big,selector_positions[selection].x,pos_y+selector_positions[selection].y);
			};
		};
	};
	
	//Humankinds persistency never ceases to amaze me ;-);
	//another piece of ugly code, quickly, escape ;-);
	//written in about 10 minutes right after getting up in the morning, dont expect it to be even slightly readable ;-);
	//returns the selected vmu or -1(if an error occured or the user canceled the dialog ;-));
	int vmu_selection(kos_gfx::pvr::texture_fragment bg, kos_gfx::pvr::texture_fragment vmu_active, kos_gfx::pvr::texture_fragment vmu_inactive, int player_id=0)
	{
		//Find first VMU ;-);
		int selected_vmu=0;
		do
		{
			++selected_vmu;
			selected_vmu%=4;
			
			if(selected_vmu==0 && !kos_gfx::storage::vmus[selected_vmu].connected())
				return -1; //No VMUs found, why was this called? ;-);
		}
		while(!kos_gfx::storage::vmus[selected_vmu].connected());
		
		do
		{
			kos_gfx::input::update();
			
			if(kos_gfx::input::controllers[player_id].clicked_buttons&kos_gfx::input::BUTTON_LEFT)
			{
				int old=selected_vmu;
				do
				{
					--selected_vmu;
					selected_vmu=selected_vmu<0?3:selected_vmu;
						
					if(selected_vmu==old)
						return old; //no other vmus left ;-);
				}
				while(!kos_gfx::storage::vmus[selected_vmu].connected());
			};
				
			if(kos_gfx::input::controllers[player_id].clicked_buttons&kos_gfx::input::BUTTON_RIGHT)
			{
				int old=selected_vmu;
				do
				{
					++selected_vmu;
					selected_vmu%=4;
						
					if(selected_vmu==old)
						return old; //no other vmus left ;-);
				}
				while(!kos_gfx::storage::vmus[selected_vmu].connected());
			};
			
			if(kos_gfx::input::controllers[player_id].clicked_buttons&kos_gfx::input::BUTTON_B)
				return -1;
			
			kos_gfx::pvr::begin_drawing();
				kos_gfx::pvr::draw(bg,0,0);
				for(int i=0;i<4;++i)
				{
					if(kos_gfx::storage::vmus[i].connected())
						kos_gfx::pvr::draw(selected_vmu==i?vmu_active:vmu_inactive,150+i*90,140);
				};
			kos_gfx::pvr::end_drawing();
		}
		while(!(kos_gfx::input::controllers[player_id].clicked_buttons&kos_gfx::input::BUTTON_A
		||kos_gfx::input::controllers[player_id].clicked_buttons&kos_gfx::input::BUTTON_START));
		
		return selected_vmu;
	};
	
	class highscore_entry:public game_state
	{
		private:
		kos_gfx::pvr::texture tex;
		
		kos_gfx::pvr::texture_fragment bg;
		rectangle_battle::virtual_keyboard keybd;
		
		int player_id;
		std::string name;
		rectangle_battle::highscore *highscore_list;
		
		public:
		highscore_entry(std::string filename,rectangle_battle::highscore *list,int pl_id=0)
		{
			tex=kos_gfx::pvr::load_png_texture(filename);
			bg=kos_gfx::pvr::texture_fragment(tex,0,0,640,480);
			
			kos_gfx::pvr::texture_fragment keyboard_tex(tex,876,0,148,640);
			kos_gfx::pvr::texture_fragment sel_small_tex(tex,487,487,50,50);
			kos_gfx::pvr::texture_fragment sel_big_tex(tex,0,488,147,47);
			keybd=rectangle_battle::virtual_keyboard(keyboard_tex,sel_small_tex,sel_big_tex, &name,10,pl_id);
			
			kos_gfx::pvr::font::init(kos_gfx::pvr::texture_fragment(tex,672,672,192,192));
			
			player_id=pl_id;
			name="Red";
			highscore_list=list;
			
			kos_gfx::input::emulate_dpad=true;
		};
		
		~highscore_entry()
		{
			highscore_list->insert_new(rectangle_battle::rectangle::points,name);
			//Try to save to the file that was previously loaded(if any), if this fails and more than one vmu is present, ask the user which one to use, otherwise save to the only one present. If no vmu exists, dont save ;_;;
			if(!highscore_list->save())
			{
				kos_gfx::storage::init();
				switch(kos_gfx::storage::number_of_vmus)
				{
					case 0:
						break;
					case 1:
					{
						for(int i=0;i<4;++i)
						{
							if(highscore_list->save(i))
								break;
						};
						break;
					};
					default:
					{
						highscore_list->save(vmu_selection(
							kos_gfx::pvr::texture_fragment(tex,0,1024-480,640,480),
							kos_gfx::pvr::texture_fragment(tex,774,889,74,113),
							kos_gfx::pvr::texture_fragment(tex,950,911,74,113),
							player_id
							));
						break;
					};
				};
				kos_gfx::storage::shutdown();
			};
			
			rectangle_battle::rectangle::points=0;
			kos_gfx::input::emulate_dpad=false;
			
			kos_gfx::pvr::free_texture(tex);
		};
		
		GAME_STATE update(GAME_STATE current_state, GAME_STATE next_state)
		{
			keybd.update();
			if(kos_gfx::input::controllers[player_id].clicked_buttons&kos_gfx::input::BUTTON_START
			||kos_gfx::input::controllers[player_id].clicked_buttons&kos_gfx::input::BUTTON_A)
			{
				return next_state;
			};
			return current_state;
		};
		
		void draw()
		{
			kos_gfx::pvr::draw(bg,0,0);
			kos_gfx::pvr::font::draw(name,320,228,12,24,2,true);
			keybd.draw();
		};
	};
};
