- Cleanups
[supertux.git] / src / leveleditor.cpp
index 2e24e8e..2dab421 100644 (file)
 //  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 
 #include <map>
 //  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 
 #include <map>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <math.h>
-#include <errno.h>
+#include <typeinfo>
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
+#include <cmath>
+#include <cerrno>
+#include <algorithm>
+#include <iostream>
 #include <unistd.h>
 #include <unistd.h>
-#include <SDL.h>
-#include <SDL_image.h>
-#include "leveleditor.h"
 
 
-#include "screen.h"
+#include "SDL.h"
+#include "SDL_image.h"
+
+#include "leveleditor.h"
+#include "video/screen.h"
 #include "defines.h"
 #include "defines.h"
-#include "globals.h"
-#include "setup.h"
-#include "menu.h"
-#include "level.h"
+#include "app/globals.h"
+#include "app/setup.h"
+#include "sector.h"
+#include "tilemap.h"
 #include "gameloop.h"
 #include "badguy.h"
 #include "gameloop.h"
 #include "badguy.h"
+#include "player.h"
 #include "scene.h"
 #include "scene.h"
-#include "button.h"
 #include "tile.h"
 #include "tile.h"
+#include "tile_manager.h"
 #include "resources.h"
 #include "resources.h"
-#include "music_manager.h"
+#include "background.h"
+#include "camera.h"
 
 /* definitions to aid development */
 
 
 /* definitions to aid development */
 
 
 #define MOUSE_LEFT_MARGIN 80
 #define MOUSE_RIGHT_MARGIN (560-32)
 
 #define MOUSE_LEFT_MARGIN 80
 #define MOUSE_RIGHT_MARGIN (560-32)
-/* right_margin should noticed that the cursor is 32 pixels,
-   so it should subtract that value */
-#define MOUSE_POS_SPEED 20
+
+/* scolling speed */
+#define KEYBOARD_SPEED 140
+#define MOUSE_SPEED    40
 
 /* look */
 #define SELECT_W 2 // size of the selections lines
 #define SELECT_CLR 0, 255, 0, 255  // lines color (R, G, B, A)
 
 
 /* look */
 #define SELECT_W 2 // size of the selections lines
 #define SELECT_CLR 0, 255, 0, 255  // lines color (R, G, B, A)
 
-/* own declerations */
-/* crutial ones (main loop) */
-int le_init();
-void le_quit();
-int le_load_level_subset(char *filename);
-void le_drawlevel();
-void le_drawinterface();
-void le_checkevents();
-void le_change(float x, float y, int tm, unsigned int c);
-void le_testlevel();
-void le_showhelp();
-void le_set_defaults(void);
-void le_activate_bad_guys(void);
-void le_goto_level(int levelnb);
-void le_highlight_selection();
-
-void apply_level_settings_menu();
-void update_subset_settings_menu();
-void save_subset_settings_menu();
-
-struct TileOrObject
+/* Frames per second: */
+
+#define FPS (1000 / 25)
+
+enum { TM_IA, TM_BG, TM_FG };
+
+LevelEditor::LevelEditor()
 {
 {
-  TileOrObject() : tile(0), obj(NULL) { is_tile = true; };
-
-  void Tile(unsigned int set_to) { tile = set_to; is_tile = true; }
-  void Object(GameObject* pobj) { obj = pobj; is_tile = false; }
-  //Returns true for a tile
-  bool IsTile() { return is_tile; };
-  //Returns true for a GameObject
-  bool IsObject() { return !is_tile; };
-  void Init() { tile = 0; obj = NULL; is_tile = true; };
-
-  bool is_tile; //true for tile (false for object)
-  unsigned int tile;
-  GameObject* obj;
-};
-
-/* leveleditor internals */
-static string_list_type level_subsets;
-static bool le_level_changed;  /* if changes, ask for saving, when quiting*/
-static bool show_minimap;
-static bool show_selections;
-static bool le_help_shown;
-static int pos_x, cursor_x, cursor_y, fire;
-static int le_level;
-static World* le_world;
-static LevelSubset* le_level_subset;
-static int le_show_grid;
-static int le_frame;
-static Surface* le_selection;
-static int done;
-static TileOrObject le_current;
-static bool le_mouse_pressed[2];
-static bool le_mouse_clicked[2];
-static Button* le_save_level_bt;
-static Button* le_exit_bt;
-static Button* le_test_level_bt;
-static Button* le_next_level_bt;
-static Button* le_previous_level_bt;
-static Button* le_move_right_bt;
-static Button* le_move_left_bt;
-static Button* le_rubber_bt;
-static Button* le_select_mode_one_bt;
-static Button* le_select_mode_two_bt;
-static Button* le_settings_bt;
-static Button* le_tilegroup_bt;
-static Button* le_objects_bt;
-static ButtonPanel* le_tilemap_panel;
-static Menu* leveleditor_menu;
-static Menu* subset_load_menu;
-static Menu* subset_new_menu;
-static Menu* subset_settings_menu;
-static Menu* level_settings_menu;
-static Menu* select_tilegroup_menu;
-static Menu* select_objects_menu;
-static Timer select_tilegroup_menu_effect;
-static Timer select_objects_menu_effect;
-typedef std::map<std::string, ButtonPanel*> ButtonPanelMap;
-static ButtonPanelMap tilegroups_map;
-static ButtonPanelMap objects_map;
-static std::string cur_tilegroup;
-static std::string cur_objects;
-
-static square selection;
-static int le_selection_mode;
-static SDL_Event event;
-TileMapType active_tm;
-
-int leveleditor(char* filename)
+  level_subsets = FileSystem::dsubdirs("/levels", "level1.stl");
+  le_level_subset = new LevelSubset;
+
+  le_level = NULL;
+  le_levelnb = 1;
+  selected_game_object = NULL;
+
+  active_tm = TM_IA;
+  le_show_grid = true;
+  show_selections = true;
+
+  pos_x = pos_y = 0;
+
+  done = 0;
+  le_frame = 0;        /* support for frames in some tiles, like waves and bad guys */
+  le_level_changed = false;
+  le_help_shown = false;
+
+  le_mouse_pressed[LEFT] = false;
+  le_mouse_pressed[RIGHT] = false;
+
+  le_mouse_clicked[LEFT] = false;
+  le_mouse_clicked[RIGHT] = false;
+
+  le_selection = new Surface(datadir + "/images/leveleditor/select.png", true);
+
+  select_tilegroup_menu_effect.init(false);
+  select_objects_menu_effect.init(false);
+  display_level_info.init(false);
+
+  /* Load buttons */
+  le_save_level_bt = new Button("/images/icons/save.png","Save level", SDLK_F6,screen->w-64,32);
+  le_exit_bt = new Button("/images/icons/exit.png","Exit", SDLK_F10,screen->w-32,32);
+  le_next_level_bt = new Button("/images/icons/next.png","Next level", SDLK_PAGEUP,screen->w-64,0);
+  le_previous_level_bt = new Button("/images/icons/previous.png","Previous level",SDLK_PAGEDOWN,screen->w-32,0);
+  le_rubber_bt = new Button("/images/icons/rubber.png","Rubber",SDLK_DELETE,screen->w-32,48);
+  le_select_mode_one_bt = new Button ("/images/icons/select-mode1.png","Select single tile",SDLK_F3,screen->w-64,48);
+  le_select_mode_two_bt = new Button("/images/icons/select-mode2.png","Select multiple tiles",SDLK_F3,screen->w-64,48);
+  le_test_level_bt = new Button("/images/icons/test-level.png","Test level",SDLK_F4,screen->w-64,screen->h - 64);
+  le_settings_bt = new Button("/images/icons/settings.png","Level settings",SDLK_F5,screen->w-32,screen->h - 64);
+  le_move_left_bt = new Button("/images/icons/left.png","Move left",SDLK_LEFT,screen->w-80-16,0);
+  le_move_right_bt = new Button("/images/icons/right.png","Move right",SDLK_RIGHT,screen->w-80,0);
+  le_move_up_bt = new Button("/images/icons/up.png","Move up",SDLK_UP,screen->w-80,16);
+  le_move_down_bt = new Button("/images/icons/down.png","Move down",SDLK_DOWN,screen->w-80,32);
+  le_tilegroup_bt = new Button("/images/icons/tilegroup.png","Select Tilegroup", SDLK_F7,screen->w-64,64);
+  le_objects_bt = new Button("/images/icons/objects.png","Select Objects", SDLK_F8,screen->w-64,80);
+  le_object_select_bt = new Button("/images/icons/select-one.png","Select an Object", SDLK_s, screen->w - 64, screen->h-98);
+  le_object_properties_bt = new Button("/images/icons/properties.png","Edit object properties", SDLK_p, screen->w - 32, screen->h-98);
+  le_object_properties_bt->set_active(false);
+
+  mouse_select_object = new MouseCursor(datadir + "/images/status/select-cursor.png",1);
+  mouse_select_object->set_mid(16,16);
+
+  le_tilemap_panel = new ButtonPanel(screen->w-64,screen->h-32,32,32);
+  le_tilemap_panel->set_button_size(32,10);
+  le_tilemap_panel->additem(new Button("/images/icons/bkgrd.png","Background",SDLK_b,0,0),TM_BG);
+  le_tilemap_panel->additem(new Button("/images/icons/intact.png","Interactive",SDLK_i,0,0), TM_IA);
+  le_tilemap_panel->additem(new Button("/images/icons/frgrd.png","Foreground",SDLK_f,0,0),TM_FG);
+  le_tilemap_panel->highlight_last(true);
+  le_tilemap_panel->set_last_clicked(TM_IA);
+
+  le_current.Init();
+
+  init_menus();
+
+  SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL);
+}
+
+LevelEditor::~LevelEditor()
 {
 {
-  int last_time, now_time, i;
+  SDL_EnableKeyRepeat(0, 0);    // disables key repeating
+
+  unload_level();
+  delete le_selection;
+  delete leveleditor_menu;
+  delete subset_load_menu;
+  delete subset_new_menu;
+  delete subset_settings_menu;
+  delete level_settings_menu;
+  delete select_tilegroup_menu;
+  delete select_objects_menu;
+  delete le_save_level_bt;
+  delete le_exit_bt;
+  delete le_test_level_bt;
+  delete le_next_level_bt;
+  delete le_previous_level_bt;
+  delete le_move_right_bt;
+  delete le_move_left_bt;
+  delete le_move_up_bt;
+  delete le_move_down_bt;
+  delete le_rubber_bt;
+  delete le_select_mode_one_bt;
+  delete le_select_mode_two_bt;
+  delete le_settings_bt;
+  delete le_tilegroup_bt;
+  delete le_objects_bt;
+  delete le_tilemap_panel;
+  delete le_object_select_bt;
+  delete le_object_properties_bt;
+  delete mouse_select_object;
 
 
-  le_level = 1;
+  delete le_level_subset;
+  le_level_subset = 0;
 
 
-  if(le_init() != 0)
-    return 1;
+  for(ButtonPanelMap::iterator i = tilegroups_map.begin();
+      i != tilegroups_map.end(); ++i)
+  {
+    delete i->second;
+  }
+  for(ButtonPanelMap::iterator i = objects_map.begin();
+      i != objects_map.end(); ++i)
+  {
+    delete i->second;
+  }
+}
 
 
-  /* Clear screen: */
+int LevelEditor::run(char* filename)
+{
+  int last_time, now_time, i;
+  DrawingContext context;
 
 
-  clearscreen(0, 0, 0);
-  updatescreen();
+  le_level = NULL;
+  le_levelnb = 1;
 
 
-  music_manager->halt_music();
+  SoundManager::get()->halt_music();
 
   while (SDL_PollEvent(&event))
   {}
 
   if(filename != NULL)
 
   while (SDL_PollEvent(&event))
   {}
 
   if(filename != NULL)
-    if(le_load_level_subset(filename))
+    if(load_level_subset(filename))
       return 1;
 
   while(true)
       return 1;
 
   while(true)
@@ -178,7 +215,7 @@ int leveleditor(char* filename)
     last_time = SDL_GetTicks();
     le_frame++;
 
     last_time = SDL_GetTicks();
     le_frame++;
 
-    le_checkevents();
+    checkevents();
 
     if(Menu::current() == select_tilegroup_menu)
     {
 
     if(Menu::current() == select_tilegroup_menu)
     {
@@ -200,27 +237,25 @@ int leveleditor(char* filename)
         select_objects_menu->set_pos(screen->w - 64,82,-0.5,0.5);
     }
 
         select_objects_menu->set_pos(screen->w - 64,82,-0.5,0.5);
     }
 
-    if(le_world != NULL)
+    if(le_level != NULL)
     {
       /* making events results to be in order */
     {
       /* making events results to be in order */
-      if(pos_x < 0)
-        pos_x = 0;
-      if(pos_x > (le_world->get_level()->width * 32) - screen->w)
-        pos_x = (le_world->get_level()->width * 32) - screen->w;
 
       /* draw the level */
 
       /* draw the level */
-      le_drawlevel();
+      context.set_translation(Vector(pos_x, pos_y));
+      drawlevel(context);
     }
     else
     }
     else
-      clearscreen(0, 0, 0);
+      fillrect(0, 0, screen->w, screen->h, 0, 0, 0);
 
     /* draw editor interface */
 
     /* draw editor interface */
-    le_drawinterface();
+    context.set_translation(Vector(0, 0));
+    drawinterface(context);
 
     Menu* menu = Menu::current();
     if(menu)
     {
 
     Menu* menu = Menu::current();
     if(menu)
     {
-      menu->draw();
+      menu->draw(context);
       menu->action();
 
       if(menu == leveleditor_menu)
       menu->action();
 
       if(menu == leveleditor_menu)
@@ -228,7 +263,7 @@ int leveleditor(char* filename)
         switch (leveleditor_menu->check())
         {
         case MNID_RETURNLEVELEDITOR:
         switch (leveleditor_menu->check())
         {
         case MNID_RETURNLEVELEDITOR:
-          if(le_world != NULL)
+          if(le_level != NULL)
             Menu::set_current(0);
           else
             Menu::set_current(leveleditor_menu);
             Menu::set_current(0);
           else
             Menu::set_current(leveleditor_menu);
@@ -295,7 +330,7 @@ int leveleditor(char* filename)
         default:
           if(i >= 1)
           {
         default:
           if(i >= 1)
           {
-            if(le_load_level_subset(level_subsets.item[i-1]))
+            if(load_level_subset(subset_load_menu->item[i+1].text))
               return 1;
           }
           break;
               return 1;
           }
           break;
@@ -315,7 +350,7 @@ int leveleditor(char* filename)
             LevelSubset::create(subset_new_menu->get_item_by_id(MNID_SUBSETNAME).input);
             le_level_subset->load(subset_new_menu->get_item_by_id(MNID_SUBSETNAME).input);
             leveleditor_menu->get_item_by_id(MNID_SUBSETSETTINGS).kind = MN_GOTO;
             LevelSubset::create(subset_new_menu->get_item_by_id(MNID_SUBSETNAME).input);
             le_level_subset->load(subset_new_menu->get_item_by_id(MNID_SUBSETNAME).input);
             leveleditor_menu->get_item_by_id(MNID_SUBSETSETTINGS).kind = MN_GOTO;
-            le_goto_level(1);
+            goto_level(1);
             subset_new_menu->get_item_by_id(MNID_SUBSETNAME).change_input("");
 
             Menu::set_current(subset_settings_menu);
             subset_new_menu->get_item_by_id(MNID_SUBSETNAME).change_input("");
 
             Menu::set_current(subset_settings_menu);
@@ -340,11 +375,10 @@ int leveleditor(char* filename)
       }
     }
 
       }
     }
 
-    mouse_cursor->draw();
+    MouseCursor::current()->draw(context);
 
     if(done)
     {
 
     if(done)
     {
-      le_quit();
       return 0;
     }
 
       return 0;
     }
 
@@ -355,18 +389,18 @@ int leveleditor(char* filename)
     if (now_time < last_time + FPS)
       SDL_Delay(last_time + FPS - now_time);   /* delay some time */
 
     if (now_time < last_time + FPS)
       SDL_Delay(last_time + FPS - now_time);   /* delay some time */
 
-    flipscreen();
+    context.do_drawing();
   }
 
   return done;
 }
 
   }
 
   return done;
 }
 
-int le_load_level_subset(char *filename)
+int LevelEditor::load_level_subset(const char *filename)
 {
   le_level_subset->load(filename);
   leveleditor_menu->get_item_by_id(MNID_SUBSETSETTINGS).kind = MN_GOTO;
 {
   le_level_subset->load(filename);
   leveleditor_menu->get_item_by_id(MNID_SUBSETSETTINGS).kind = MN_GOTO;
-  le_level = 1;
-  le_goto_level(1);
+  le_levelnb = 1;
+  goto_level(le_levelnb);
 
   //GameSession* session = new GameSession(datadir + "/levels/" + le_level_subset->name + "/level1.stl", 0, ST_GL_DEMO_GAME);
 
 
   //GameSession* session = new GameSession(datadir + "/levels/" + le_level_subset->name + "/level1.stl", 0, ST_GL_DEMO_GAME);
 
@@ -375,9 +409,9 @@ int le_load_level_subset(char *filename)
   return 0;
 }
 
   return 0;
 }
 
-void le_init_menus()
+void LevelEditor::init_menus()
 {
 {
-  int i;
+  int i = 0;
 
   leveleditor_menu = new Menu();
   subset_load_menu = new Menu();
 
   leveleditor_menu = new Menu();
   subset_load_menu = new Menu();
@@ -401,9 +435,9 @@ void le_init_menus()
   subset_load_menu->additem(MN_LABEL, "Load Level Subset", 0, 0);
   subset_load_menu->additem(MN_HL, "", 0, 0);
 
   subset_load_menu->additem(MN_LABEL, "Load Level Subset", 0, 0);
   subset_load_menu->additem(MN_HL, "", 0, 0);
 
-  for(i = 0; i < level_subsets.num_items; ++i)
+  for(std::set<std::string>::iterator it = level_subsets.begin(); it != level_subsets.end(); ++it)
   {
   {
-    subset_load_menu->additem(MN_ACTION,level_subsets.item[i],0,0, i+1);
+    subset_load_menu->additem(MN_ACTION,(*it),0,0, i+1);
   }
   subset_load_menu->additem(MN_HL,"",0,0);
   subset_load_menu->additem(MN_BACK,"Back",0,0);
   }
   subset_load_menu->additem(MN_HL,"",0,0);
   subset_load_menu->additem(MN_BACK,"Back",0,0);
@@ -433,22 +467,22 @@ void le_init_menus()
   level_settings_menu->additem(MN_STRINGSELECT,"Bg-Image",0,0,MNID_BGIMG);
   level_settings_menu->additem(MN_STRINGSELECT,"Particle",0,0,MNID_PARTICLE);
   level_settings_menu->additem(MN_NUMFIELD,    "Length  ",0,0,MNID_LENGTH);
   level_settings_menu->additem(MN_STRINGSELECT,"Bg-Image",0,0,MNID_BGIMG);
   level_settings_menu->additem(MN_STRINGSELECT,"Particle",0,0,MNID_PARTICLE);
   level_settings_menu->additem(MN_NUMFIELD,    "Length  ",0,0,MNID_LENGTH);
+  level_settings_menu->additem(MN_NUMFIELD,    "Height  ",0,0,MNID_HEIGHT);
   level_settings_menu->additem(MN_NUMFIELD,    "Time    ",0,0,MNID_TIME);
   level_settings_menu->additem(MN_NUMFIELD,    "Gravity ",0,0,MNID_GRAVITY);
   level_settings_menu->additem(MN_NUMFIELD,    "Bg-Img-Speed",0,0,MNID_BGSPEED);
   level_settings_menu->additem(MN_NUMFIELD,    "Time    ",0,0,MNID_TIME);
   level_settings_menu->additem(MN_NUMFIELD,    "Gravity ",0,0,MNID_GRAVITY);
   level_settings_menu->additem(MN_NUMFIELD,    "Bg-Img-Speed",0,0,MNID_BGSPEED);
-  level_settings_menu->additem(MN_NUMFIELD,    "Top Red    ",0,0,MNID_TopRed);
-  level_settings_menu->additem(MN_NUMFIELD,    "Top Green  ",0,0,MNID_TopGreen);
-  level_settings_menu->additem(MN_NUMFIELD,    "Top Blue   ",0,0,MNID_TopBlue);
-  level_settings_menu->additem(MN_NUMFIELD,    "Bottom Red ",0,0,MNID_BottomRed);
+  level_settings_menu->additem(MN_NUMFIELD,    "Top Red     ",0,0,MNID_TopRed);
+  level_settings_menu->additem(MN_NUMFIELD,    "Top Green   ",0,0,MNID_TopGreen);
+  level_settings_menu->additem(MN_NUMFIELD,    "Top Blue    ",0,0,MNID_TopBlue);
+  level_settings_menu->additem(MN_NUMFIELD,    "Bottom Red  ",0,0,MNID_BottomRed);
   level_settings_menu->additem(MN_NUMFIELD,    "Bottom Green",0,0,MNID_BottomGreen);
   level_settings_menu->additem(MN_NUMFIELD,    "Bottom Green",0,0,MNID_BottomGreen);
-  level_settings_menu->additem(MN_NUMFIELD,    "Bottom Blue",0,0,MNID_BottomBlue);
+  level_settings_menu->additem(MN_NUMFIELD,    "Bottom Blue ",0,0,MNID_BottomBlue);
   level_settings_menu->additem(MN_HL,"",0,0);
   level_settings_menu->additem(MN_ACTION,"Apply Changes",0,0,MNID_APPLY);
 
   select_tilegroup_menu->arrange_left = true;
   select_tilegroup_menu->additem(MN_LABEL,"Tilegroup",0,0);
   select_tilegroup_menu->additem(MN_HL,"",0,0);
   level_settings_menu->additem(MN_HL,"",0,0);
   level_settings_menu->additem(MN_ACTION,"Apply Changes",0,0,MNID_APPLY);
 
   select_tilegroup_menu->arrange_left = true;
   select_tilegroup_menu->additem(MN_LABEL,"Tilegroup",0,0);
   select_tilegroup_menu->additem(MN_HL,"",0,0);
-  select_tilegroup_menu->additem(MN_ACTION,"asd",0,0);
   std::set<TileGroup>* tilegroups = TileManager::tilegroups();
   int tileid = 1;
   for(std::set<TileGroup>::iterator it = tilegroups->begin();
   std::set<TileGroup>* tilegroups = TileManager::tilegroups();
   int tileid = 1;
   for(std::set<TileGroup>::iterator it = tilegroups->begin();
@@ -462,29 +496,18 @@ void le_init_menus()
       for(std::vector<int>::const_iterator sit = (*it).tiles.begin();
           sit != (*it).tiles.end(); ++sit, ++i)
       {
       for(std::vector<int>::const_iterator sit = (*it).tiles.begin();
           sit != (*it).tiles.end(); ++sit, ++i)
       {
-        std::string imagefile = "/images/tilesets/" ;
-        bool only_editor_image = false;
-        if(!TileManager::instance()->get(*sit)->filenames.empty())
-        {
-          imagefile += TileManager::instance()->get(*sit)->filenames[0];
-        }
-        else if(!TileManager::instance()->get(*sit)->editor_filenames.empty())
-        {
-          imagefile += TileManager::instance()->get(*sit)->editor_filenames[0];
-          only_editor_image = true;
-        }
+        Tile& tile = TileManager::instance()->get(*sit);
+        Surface* image;
+        if(tile.editor_images.size() > 0)
+          image = tile.editor_images[0];
+        else if(tile.images.size() > 0)
+          image = tile.images[0];
         else
         else
-        {
-          imagefile += "notile.png";
-        }
-        Button* button = new Button(imagefile, it->name, SDLKey(SDLK_a + i),
+          // TODO use some notile image...
+          image = 0;
+
+        Button* button = new Button(image, it->name, SDLKey(SDLK_a + i),
                                     0, 0, 32, 32);
                                     0, 0, 32, 32);
-        if(!only_editor_image)
-          if(!TileManager::instance()->get(*sit)->editor_filenames.empty())
-          {
-            imagefile = "/images/tilesets/" + TileManager::instance()->get(*sit)->editor_filenames[0];
-            button->add_icon(imagefile,32,32);
-          }
         tilegroups_map[it->name]->additem(button, *sit);
       }
     }
         tilegroups_map[it->name]->additem(button, *sit);
       }
     }
@@ -493,414 +516,366 @@ void le_init_menus()
   select_objects_menu->arrange_left = true;
   select_objects_menu->additem(MN_LABEL,"Objects",0,0);
   select_objects_menu->additem(MN_HL,"",0,0);
   select_objects_menu->arrange_left = true;
   select_objects_menu->additem(MN_LABEL,"Objects",0,0);
   select_objects_menu->additem(MN_HL,"",0,0);
+  // TODO fix this
   select_objects_menu->additem(MN_ACTION,"BadGuys",0,0,1);
   objects_map["BadGuys"] = new ButtonPanel(screen->w - 64,96, 64, 318);
 
   for(int i = 0; i < NUM_BadGuyKinds; ++i)
   {
   select_objects_menu->additem(MN_ACTION,"BadGuys",0,0,1);
   objects_map["BadGuys"] = new ButtonPanel(screen->w - 64,96, 64, 318);
 
   for(int i = 0; i < NUM_BadGuyKinds; ++i)
   {
-    BadGuy bad_tmp(0,0,BadGuyKind(i),false);
-    objects_map["BadGuys"]->additem(new Button("", "BadGuy",(SDLKey)(i+'a'),0,0,32,32),1000000+i);
-    objects_map["BadGuys"]->manipulate_button(i)->set_game_object(new BadGuy(objects_map["BadGuys"]->manipulate_button(i)->get_pos().x,objects_map["BadGuys"]->manipulate_button(i)->get_pos().y,BadGuyKind(i),false));
+//    BadGuy bad_tmp(BadGuyKind(i), 0, 0);
+//    objects_map["BadGuys"]->additem(new Button(0, "BadGuy",(SDLKey)(i+'a'),0,0,32,32),1000000+i);
+/* FIXME: maybe addbutton should already have a parameter for the surface
+    objects_map["BadGuys"]->manipulate_button(i)->set_drawable(new
+        BadGuy(BadGuyKind(i),
+          objects_map["BadGuys"]->manipulate_button(i)->get_pos().x,
+          objects_map["BadGuys"]->manipulate_button(i)->get_pos().y
+          ));*/
   }
 
   select_objects_menu->additem(MN_HL,"",0,0);
 
 }
 
   }
 
   select_objects_menu->additem(MN_HL,"",0,0);
 
 }
 
-int le_init()
-{
-
-
-  level_subsets = dsubdirs("/levels", "level1.stl");
-  le_level_subset = new LevelSubset;
-
-  le_world = NULL;
-
-  active_tm = TM_IA;
-  le_show_grid = true;
-  show_selections = true;
-  scroll_x = 0;
-
-  fire = DOWN;
-  done = 0;
-  le_frame = 0;        /* support for frames in some tiles, like waves and bad guys */
-  le_level_changed = false;
-  le_help_shown = false;
-
-  le_mouse_pressed[LEFT] = false;
-  le_mouse_pressed[RIGHT] = false;
-
-  le_mouse_clicked[LEFT] = false;
-  le_mouse_clicked[RIGHT] = false;
-
-  le_selection = new Surface(datadir + "/images/leveleditor/select.png", USE_ALPHA);
-
-  select_tilegroup_menu_effect.init(false);
-  select_objects_menu_effect.init(false);
-
-  /* Load buttons */
-  le_save_level_bt = new Button("/images/icons/save.png","Save level", SDLK_F6,screen->w-64,32);
-  le_exit_bt = new Button("/images/icons/exit.png","Exit", SDLK_F9,screen->w-32,32);
-  le_next_level_bt = new Button("/images/icons/up.png","Next level", SDLK_PAGEUP,screen->w-64,0);
-  le_previous_level_bt = new Button("/images/icons/down.png","Previous level",SDLK_PAGEDOWN,screen->w-32,0);
-  le_rubber_bt = new Button("/images/icons/rubber.png","Rubber",SDLK_DELETE,screen->w-32,48);
-  le_select_mode_one_bt = new Button ("/images/icons/select-mode1.png","Select single tile",SDLK_F3,screen->w-64,48);
-  le_select_mode_two_bt = new Button("/images/icons/select-mode2.png","Select multiple tiles",SDLK_F3,screen->w-64,48);
-  le_test_level_bt = new Button("/images/icons/test-level.png","Test level",SDLK_F4,screen->w-64,screen->h - 64);
-  le_settings_bt = new Button("/images/icons/settings.png","Level settings",SDLK_F5,screen->w-32,screen->h - 64);
-  le_move_left_bt = new Button("/images/icons/left.png","Move left",SDLK_LEFT,0,0);
-  le_move_right_bt = new Button("/images/icons/right.png","Move right",SDLK_RIGHT,screen->w-80,0);
-  le_tilegroup_bt = new Button("/images/icons/tilegroup.png","Select Tilegroup", SDLK_F7,screen->w-64,64);
-  le_objects_bt = new Button("/images/icons/objects.png","Select Objects", SDLK_F8,screen->w-64,80);
-
-  le_tilemap_panel = new ButtonPanel(screen->w-64,screen->h-32,32,32);
-  le_tilemap_panel->set_button_size(32,10);
-  le_tilemap_panel->additem(new Button("/images/icons/bkgrd.png","Background",SDLK_b,0,0),TM_BG);
-  le_tilemap_panel->additem(new Button("/images/icons/intact.png","Interactive",SDLK_i,0,0),TM_IA);
-  le_tilemap_panel->additem(new Button("/images/icons/frgrd.png","Foreground",SDLK_f,0,0),TM_FG);
-  le_tilemap_panel->highlight_last(true);
-  le_tilemap_panel->set_last_clicked(TM_IA);
-
-  le_current.Init();
-
-  le_init_menus();
-
-  SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL);
-
-
-  return 0;
-}
-
-void update_level_settings_menu()
+void LevelEditor::update_level_settings_menu()
 {
   char str[80];
 {
   char str[80];
-  int i;
-
-  level_settings_menu->get_item_by_id(MNID_NAME).change_input(le_world->get_level()->name.c_str());
-  level_settings_menu->get_item_by_id(MNID_AUTHOR).change_input(le_world->get_level()->author.c_str());
-
-  string_list_copy(level_settings_menu->get_item_by_id(MNID_SONG).list, dfiles("music/",NULL, "-fast"));
-  string_list_copy(level_settings_menu->get_item_by_id(MNID_BGIMG).list, dfiles("images/background",NULL, NULL));
-  string_list_add_item(level_settings_menu->get_item_by_id(MNID_BGIMG).list,"");
-  string_list_add_item(level_settings_menu->get_item_by_id(MNID_PARTICLE).list,"");
-  string_list_add_item(level_settings_menu->get_item_by_id(MNID_PARTICLE).list,"snow");
-  string_list_add_item(level_settings_menu->get_item_by_id(MNID_PARTICLE).list,"clouds");
-
-  if((i = string_list_find(level_settings_menu->get_item_by_id(MNID_SONG).list,le_world->get_level()->song_title.c_str())) != -1)
-    level_settings_menu->get_item_by_id(MNID_SONG).list->active_item = i;
-  if((i = string_list_find(level_settings_menu->get_item_by_id(MNID_BGIMG).list,le_world->get_level()->bkgd_image.c_str())) != -1)
-    level_settings_menu->get_item_by_id(MNID_BGIMG).list->active_item = i;
-  if((i = string_list_find(level_settings_menu->get_item_by_id(MNID_PARTICLE).list,le_world->get_level()->particle_system.c_str())) != -1)
-    level_settings_menu->get_item_by_id(MNID_PARTICLE).list->active_item = i;
-
-  sprintf(str,"%d",le_world->get_level()->width);
+  std::set<std::string>::iterator it;
+
+  level_settings_menu->get_item_by_id(MNID_NAME).change_input(le_level->name.c_str());
+  level_settings_menu->get_item_by_id(MNID_AUTHOR).change_input(le_level->author.c_str());
+
+  level_settings_menu->get_item_by_id(MNID_SONG).list.first = FileSystem::dfiles("music/",NULL, "-fast");
+  level_settings_menu->get_item_by_id(MNID_BGIMG).list.first = FileSystem::dfiles("images/background",NULL, NULL);
+  level_settings_menu->get_item_by_id(MNID_BGIMG).list.first.insert("");
+  level_settings_menu->get_item_by_id(MNID_PARTICLE).list.first.insert("");
+  level_settings_menu->get_item_by_id(MNID_PARTICLE).list.first.insert("snow");
+  level_settings_menu->get_item_by_id(MNID_PARTICLE).list.first.insert("clouds");
+
+  if((it = level_settings_menu->get_item_by_id(MNID_SONG).list.first.find(le_level->get_sector("main")->song_title)) != level_settings_menu->get_item_by_id(MNID_SONG).list.first.end())
+    level_settings_menu->get_item_by_id(MNID_SONG).list.second = it;
+  if((it = level_settings_menu->get_item_by_id(MNID_BGIMG).list.first.find(le_level->get_sector("main")->background->get_image())) != level_settings_menu->get_item_by_id(MNID_BGIMG).list.first.end())
+    level_settings_menu->get_item_by_id(MNID_BGIMG).list.second = it;
+/*  if((i = string_list_find(level_settings_menu->get_item_by_id(MNID_PARTICLE).list,le_level->get_sector("main")->particlesystem.c_str())) != -1)
+    level_settings_menu->get_item_by_id(MNID_PARTICLE).list->active_item = i;*/
+
+  sprintf(str,"%d",static_cast<int>(le_level->get_sector("main")->solids->get_width()));
   level_settings_menu->get_item_by_id(MNID_LENGTH).change_input(str);
   level_settings_menu->get_item_by_id(MNID_LENGTH).change_input(str);
-  sprintf(str,"%d",le_world->get_level()->time_left);
+  sprintf(str,"%d", static_cast<int>(le_level->get_sector("main")->solids->get_height()));
+  level_settings_menu->get_item_by_id(MNID_HEIGHT).change_input(str);
+  sprintf(str,"%d",le_level->time_left);
   level_settings_menu->get_item_by_id(MNID_TIME).change_input(str);
   level_settings_menu->get_item_by_id(MNID_TIME).change_input(str);
-  sprintf(str,"%2.0f",le_world->get_level()->gravity);
+  sprintf(str,"%2.0f",le_level->get_sector("main")->gravity);
   level_settings_menu->get_item_by_id(MNID_GRAVITY).change_input(str);
   level_settings_menu->get_item_by_id(MNID_GRAVITY).change_input(str);
-  sprintf(str,"%d",le_world->get_level()->bkgd_speed);
+  sprintf(str,"%2.2f", le_level->get_sector("main")->background->get_speed());
   level_settings_menu->get_item_by_id(MNID_BGSPEED).change_input(str);
   level_settings_menu->get_item_by_id(MNID_BGSPEED).change_input(str);
-  sprintf(str,"%d",le_world->get_level()->bkgd_top.red);
+  sprintf(str,"%d",le_level->get_sector("main")->background->get_gradient_top().red);
   level_settings_menu->get_item_by_id(MNID_TopRed).change_input(str);
   level_settings_menu->get_item_by_id(MNID_TopRed).change_input(str);
-  sprintf(str,"%d",le_world->get_level()->bkgd_top.green);
+  sprintf(str,"%d",le_level->get_sector("main")->background->get_gradient_top().green);
   level_settings_menu->get_item_by_id(MNID_TopGreen).change_input(str);
   level_settings_menu->get_item_by_id(MNID_TopGreen).change_input(str);
-  sprintf(str,"%d",le_world->get_level()->bkgd_top.blue);
+  sprintf(str,"%d",le_level->get_sector("main")->background->get_gradient_top().blue);
   level_settings_menu->get_item_by_id(MNID_TopBlue).change_input(str);
   level_settings_menu->get_item_by_id(MNID_TopBlue).change_input(str);
-  sprintf(str,"%d",le_world->get_level()->bkgd_bottom.red);
+  sprintf(str,"%d",le_level->get_sector("main")->background->get_gradient_bottom().red);
   level_settings_menu->get_item_by_id(MNID_BottomRed).change_input(str);
   level_settings_menu->get_item_by_id(MNID_BottomRed).change_input(str);
-  sprintf(str,"%d",le_world->get_level()->bkgd_bottom.green);
+  sprintf(str,"%d",le_level->get_sector("main")->background->get_gradient_bottom().green);
   level_settings_menu->get_item_by_id(MNID_BottomGreen).change_input(str);
   level_settings_menu->get_item_by_id(MNID_BottomGreen).change_input(str);
-  sprintf(str,"%d",le_world->get_level()->bkgd_bottom.blue);
+  sprintf(str,"%d",le_level->get_sector("main")->background->get_gradient_bottom().blue);
   level_settings_menu->get_item_by_id(MNID_BottomBlue).change_input(str);
 }
 
   level_settings_menu->get_item_by_id(MNID_BottomBlue).change_input(str);
 }
 
-void update_subset_settings_menu()
+void LevelEditor::update_subset_settings_menu()
 {
   subset_settings_menu->item[2].change_input(le_level_subset->title.c_str());
   subset_settings_menu->item[3].change_input(le_level_subset->description.c_str());
 }
 
 {
   subset_settings_menu->item[2].change_input(le_level_subset->title.c_str());
   subset_settings_menu->item[3].change_input(le_level_subset->description.c_str());
 }
 
-void apply_level_settings_menu()
+void LevelEditor::apply_level_settings_menu()
 {
   int i;
   i = false;
 {
   int i;
   i = false;
+  le_level_changed = true;
 
 
-  le_world->get_level()->name = level_settings_menu->get_item_by_id(MNID_NAME).input;
-  le_world->get_level()->author = level_settings_menu->get_item_by_id(MNID_AUTHOR).input;
+  le_level->name = level_settings_menu->get_item_by_id(MNID_NAME).input;
+  le_level->author = level_settings_menu->get_item_by_id(MNID_AUTHOR).input;
 
 
-  if(le_world->get_level()->bkgd_image.compare(string_list_active(level_settings_menu->get_item_by_id(MNID_BGIMG).list)) != 0)
+  if(le_level->get_sector("main")->background->get_image().compare((*level_settings_menu->get_item_by_id(MNID_BGIMG).list.second)) != 0)
   {
   {
-    le_world->get_level()->bkgd_image = string_list_active(level_settings_menu->get_item_by_id(MNID_BGIMG).list);
+    le_level->get_sector("main")->background->set_image((*level_settings_menu->get_item_by_id(MNID_BGIMG).list.second), atoi(level_settings_menu->get_item_by_id(MNID_BGSPEED).input));
     i = true;
   }
 
     i = true;
   }
 
-  if(le_world->get_level()->particle_system.compare(string_list_active(level_settings_menu->get_item_by_id(MNID_PARTICLE).list)) != 0)
+/*  if(le_level->get_sector("main")->particlesystem.compare(string_list_active(level_settings_menu->get_item_by_id(MNID_PARTICLE).list)) != 0)
   {
   {
-    le_world->get_level()->particle_system = string_list_active(level_settings_menu->get_item_by_id(MNID_PARTICLE).list);
-  }
+    le_level->->get_sector("main")->particlesystem = string_list_active(level_settings_menu->get_item_by_id(MNID_PARTICLE).list);
+  }*/
 
 
-  if(i)
+/*  if(i)
   {
   {
-    le_world->get_level()->load_gfx();
-  }
-
-  le_world->get_level()->song_title = string_list_active(level_settings_menu->get_item_by_id(MNID_SONG).list);
-
-  le_world->get_level()->change_size(atoi(level_settings_menu->get_item_by_id(MNID_LENGTH).input));
-  le_world->get_level()->time_left = atoi(level_settings_menu->get_item_by_id(MNID_TIME).input);
-  le_world->get_level()->gravity = atof(level_settings_menu->get_item_by_id(MNID_GRAVITY).input);
-  le_world->get_level()->bkgd_speed = atoi(level_settings_menu->get_item_by_id(MNID_BGSPEED).input);
-  le_world->get_level()->bkgd_top.red = atoi(level_settings_menu->get_item_by_id(MNID_TopRed).input);
-  le_world->get_level()->bkgd_top.green = atoi(level_settings_menu->get_item_by_id(MNID_TopGreen).input);
-  le_world->get_level()->bkgd_top.blue = atoi(level_settings_menu->get_item_by_id(MNID_TopBlue).input);
-  le_world->get_level()->bkgd_bottom.red = atoi(level_settings_menu->get_item_by_id(MNID_BottomRed).input);
-  le_world->get_level()->bkgd_bottom.green = atoi(level_settings_menu->get_item_by_id(MNID_BottomGreen).input);
-  le_world->get_level()->bkgd_bottom.blue = atoi(level_settings_menu->get_item_by_id(MNID_BottomBlue).input);
+    le_level->load_gfx();
+  }*/
+
+  le_level->get_sector("main")->song_title = (*level_settings_menu->get_item_by_id(MNID_SONG).list.second);
+
+  le_level->get_sector("main")->solids->resize(
+      atoi(level_settings_menu->get_item_by_id(MNID_LENGTH).input),
+      atoi(level_settings_menu->get_item_by_id(MNID_HEIGHT).input));
+  le_level->time_left = atoi(level_settings_menu->get_item_by_id(MNID_TIME).input);
+  le_level->get_sector("main")->gravity = atof(level_settings_menu->get_item_by_id(MNID_GRAVITY).input);
+  le_level->get_sector("main")->background->set_gradient(Color(
+      atoi(level_settings_menu->get_item_by_id(MNID_TopRed).input),
+      atoi(level_settings_menu->get_item_by_id(MNID_TopGreen).input),
+      atoi(level_settings_menu->get_item_by_id(MNID_TopBlue).input)), Color(
+      atoi(level_settings_menu->get_item_by_id(MNID_BottomRed).input),
+      atoi(level_settings_menu->get_item_by_id(MNID_BottomGreen).input),
+      atoi(level_settings_menu->get_item_by_id(MNID_BottomBlue).input)));
 }
 
 }
 
-void save_subset_settings_menu()
+void LevelEditor::save_subset_settings_menu()
 {
   le_level_subset->title = subset_settings_menu->item[2].input;
   le_level_subset->description = subset_settings_menu->item[3].input;
   le_level_subset->save();
 {
   le_level_subset->title = subset_settings_menu->item[2].input;
   le_level_subset->description = subset_settings_menu->item[3].input;
   le_level_subset->save();
+  le_level_changed = false;
 }
 
 }
 
-void le_unload_level()
+void LevelEditor::unload_level()
 {
   if(le_level_changed)
   {
 {
   if(le_level_changed)
   {
-    le_drawlevel();
-    le_drawinterface();
     char str[1024];
     char str[1024];
-    sprintf(str,"Save changes to level %d of %s?",le_level,le_level_subset->name.c_str());
-    if(confirm_dialog(str))
+    // TODO get level number
+    sprintf(str,"Save changes to level %d of %s?", 0/*le_level*/,le_level_subset->name.c_str());
+    Surface* surf = new Surface(le_level->get_sector("main")->background->get_image(), false);
+    if(confirm_dialog(surf, str))
     {
     {
-      le_world->get_level()->save(le_level_subset->name.c_str(),le_level);
+      le_level->save(le_level_subset->get_level_filename(le_levelnb));
     }
     }
+    if(surf != NULL)
+      delete surf;
   }
 
   }
 
-  delete le_world;
-  le_level_changed = false;  
-}
-
-void le_goto_level(int levelnb)
-{
-  le_unload_level();
-  le_world = new World(le_level_subset->name, levelnb);
+  delete le_level;
+  le_level_changed = false;
 }
 
 }
 
-void le_quit(void)
+void LevelEditor::goto_level(int levelnb)
 {
 {
-  SDL_EnableKeyRepeat(0, 0);    // disables key repeating
-
-  le_unload_level();
-  delete le_selection;
-  delete leveleditor_menu;
-  delete subset_load_menu;
-  delete subset_new_menu;
-  delete subset_settings_menu;
-  delete level_settings_menu;
-  delete select_tilegroup_menu;
-  delete select_objects_menu;
-  delete le_save_level_bt;
-  delete le_exit_bt;
-  delete le_test_level_bt;
-  delete le_next_level_bt;
-  delete le_previous_level_bt;
-  delete le_move_right_bt;
-  delete le_move_left_bt;
-  delete le_rubber_bt;
-  delete le_select_mode_one_bt;
-  delete le_select_mode_two_bt;
-  delete le_settings_bt;
-  delete le_tilegroup_bt;
-  delete le_objects_bt;
-  delete le_tilemap_panel;
-
-  delete le_level_subset;
-  le_level_subset = 0;
-
-  for(ButtonPanelMap::iterator i = tilegroups_map.begin();
-      i != tilegroups_map.end(); ++i)
-  {
-    delete i->second;
-  }
-  for(ButtonPanelMap::iterator i = objects_map.begin();
-      i != objects_map.end(); ++i)
-  {
-    delete i->second;
-  }
+  unload_level();
+  le_level = new Level();
+  le_level->load(le_level_subset->get_level_filename(levelnb));
+  display_level_info.start(2500);
+  le_levelnb = levelnb;
 }
 
 }
 
-void le_drawminimap()
+void LevelEditor::drawminimap()
 {
 {
-  if(le_world == NULL)
-    return;
+#if 0
+//  if(le_level == NULL)
+//    return;
 
   int mini_tile_width;
 
   int mini_tile_width;
-  if(screen->w - 64 > le_world->get_level()->width * 4)
+  if((unsigned)screen->w - 64 > le_level->get_sector("main")->solids->get_width() * 4)
     mini_tile_width = 4;
     mini_tile_width = 4;
-  else if(screen->w - 64 > le_world->get_level()->width * 2)
+  else if((unsigned)screen->w - 64 > le_level->get_sector("main")->solids->get_width() * 2)
     mini_tile_width = 2;
   else
     mini_tile_width = 1;
     mini_tile_width = 2;
   else
     mini_tile_width = 1;
-  int left_offset = (screen->w - 64 - le_world->get_level()->width*mini_tile_width) / 2;
+  int left_offset = (screen->w - 64 - le_level->get_sector("main")->solids->get_width()*mini_tile_width) / 2;
+
+  int mini_tile_height;
+  if((unsigned)screen->h > le_level->get_sector("main")->solids->get_height() * 4)
+    mini_tile_height = 4;
+  else if((unsigned)screen->h > le_level->get_sector("main")->solids->get_height() * 2)
+    mini_tile_height = 2;
+  else
+    mini_tile_height = 1;
 
 
-  for (int y = 0; y < 15; ++y)
-    for (int x = 0; x < le_world->get_level()->width; ++x)
+  for (unsigned int y = 0; y < le_level->get_sector("main")->solids->get_height(); ++y)
+    for (unsigned int x = 0; x < le_level->get_sector("main")->solids->get_width(); ++x)
     {
 
     {
 
-      Tile::draw_stretched(left_offset + mini_tile_width*x, y * 4, mini_tile_width , 4, le_world->get_level()->bg_tiles[y][x]);
+      Tile::draw_stretched(left_offset + mini_tile_width*x, y * mini_tile_height,
+          mini_tile_width , mini_tile_height, le_level->bg_tiles[y * le_level->get_sector("main")->solids->get_width() + x]);
 
 
-      Tile::draw_stretched(left_offset + mini_tile_width*x, y * 4, mini_tile_width , 4, le_world->get_level()->ia_tiles[y][x]);
+      Tile::draw_stretched(left_offset + mini_tile_width*x, y * mini_tile_height,
+          mini_tile_width , mini_tile_height, le_level->ia_tiles[y * le_level->get_sector("main")->solids->get_width() + x]);
 
 
-      Tile::draw_stretched(left_offset + mini_tile_width*x, y * 4, mini_tile_width , 4, le_world->get_level()->fg_tiles[y][x]);
+      Tile::draw_stretched(left_offset + mini_tile_width*x, y * mini_tile_height,
+          mini_tile_width , mini_tile_height, le_level->fg_tiles[y + le_level->get_sector("main")->solids->get_width() + x]);
 
     }
 
 
     }
 
-  fillrect(left_offset, 0, le_world->get_level()->width*mini_tile_width, 15*4, 200, 200, 200, 128);
-
-  fillrect(left_offset + (pos_x/32)*mini_tile_width, 0, 19*mini_tile_width, 2, 200, 200, 200, 200);
-  fillrect(left_offset + (pos_x/32)*mini_tile_width, 0, 2, 15*4, 200, 200, 200, 200);
-  fillrect(left_offset + (pos_x/32)*mini_tile_width + 19*mini_tile_width - 2, 0, 2, 15*4, 200, 200, 200, 200);
-  fillrect(left_offset + (pos_x/32)*mini_tile_width, 15*4-2, 19*mini_tile_width, 2, 200, 200, 200, 200);
-
+  fillrect(left_offset, 0,
+             le_level->get_sector("main")->solids->get_width()*mini_tile_width, le_level->get_sector("main")->solids->get_height()*mini_tile_height,
+             200, 200, 200, 96);
+
+  fillrect(left_offset + (pos_x/32)*mini_tile_width, (pos_y/32)*mini_tile_height,
+             (VISIBLE_TILES_X-3)*mini_tile_width, 2,
+             200, 200, 200, 200);
+  fillrect(left_offset + (pos_x/32)*mini_tile_width, (pos_y/32)*mini_tile_height,
+             2, (VISIBLE_TILES_Y-1)*mini_tile_height,
+             200, 200, 200, 200);
+  fillrect(left_offset + (pos_x/32)*mini_tile_width + (VISIBLE_TILES_X-3)*mini_tile_width - 2, (pos_y/32)*mini_tile_height,
+             2, (VISIBLE_TILES_Y-1)*mini_tile_height,
+             200, 200, 200, 200);
+  fillrect(left_offset + (pos_x/32)*mini_tile_width, (pos_y/32)*mini_tile_height + (VISIBLE_TILES_Y-1)*mini_tile_height - 2,
+             (VISIBLE_TILES_X-3)*mini_tile_width, 2,
+             200, 200, 200, 200);
+#endif
 }
 
 }
 
-void le_drawinterface()
+void LevelEditor::drawinterface(DrawingContext &context)
 {
   int x,y;
   char str[80];
 
 {
   int x,y;
   char str[80];
 
-  if(le_world != NULL)
+  if(le_level != NULL)
   {
     /* draw a grid (if selected) */
     if(le_show_grid)
     {
   {
     /* draw a grid (if selected) */
     if(le_show_grid)
     {
-      for(x = 0; x < 19; x++)
+      for(x = 0; x < VISIBLE_TILES_X; x++)
         fillrect(x*32 - ((int)pos_x % 32), 0, 1, screen->h, 225, 225, 225,255);
         fillrect(x*32 - ((int)pos_x % 32), 0, 1, screen->h, 225, 225, 225,255);
-      for(y = 0; y < 15; y++)
-        fillrect(0, y*32, screen->w - 32, 1, 225, 225, 225,255);
+      for(y = 0; y < VISIBLE_TILES_Y; y++)
+        fillrect(0, y*32 - ((int)pos_y % 32), screen->w, 1, 225, 225, 225,255);
     }
   }
 
   if(show_minimap) // use_gl because the minimap isn't shown correctly in software mode. Any idea? FIXME Possible reasons: SDL_SoftStretch is a hack itsself || an alpha blitting issue SDL can't handle in software mode
     }
   }
 
   if(show_minimap) // use_gl because the minimap isn't shown correctly in software mode. Any idea? FIXME Possible reasons: SDL_SoftStretch is a hack itsself || an alpha blitting issue SDL can't handle in software mode
-    le_drawminimap();
+    drawminimap();
 
 
-  if(show_selections)
+  if(show_selections && MouseCursor::current() != mouse_select_object)
   {
   {
-  if(le_selection_mode == CURSOR)
-  {
-    if(le_current.IsTile())
-      le_selection->draw( cursor_x - pos_x, cursor_y);
-  }
-  else if(le_selection_mode == SQUARE)
-  {
-    int w, h;
-    le_highlight_selection();
-    /* draw current selection */
-    w = selection.x2 - selection.x1;
-    h = selection.y2 - selection.y1;
-    fillrect(selection.x1 - pos_x, selection.y1, w, SELECT_W, SELECT_CLR);
-    fillrect(selection.x1 - pos_x + w, selection.y1, SELECT_W, h, SELECT_CLR);
-    fillrect(selection.x1 - pos_x, selection.y1 + h, w, SELECT_W, SELECT_CLR);
-    fillrect(selection.x1 - pos_x, selection.y1, SELECT_W, h, SELECT_CLR);
-  }
+    if(le_selection_mode == CURSOR)
+    {
+      if(le_current.IsTile())
+        context.draw_surface(le_selection, Vector(cursor_x - pos_x, cursor_y - pos_y), LAYER_GUI);
+    }
+    else if(le_selection_mode == SQUARE)
+    {
+      int w, h;
+      highlight_selection();
+      /* draw current selection */
+      w = selection.x2 - selection.x1;
+      h = selection.y2 - selection.y1;
+      context.draw_filled_rect(Vector(selection.x1 - pos_x, selection.y1 - pos_y), Vector(w, SELECT_W), Color(SELECT_CLR), LAYER_GUI);
+      context.draw_filled_rect(Vector(selection.x1 - pos_x + w, selection.y1 - pos_y), Vector(SELECT_W, h), Color(SELECT_CLR), LAYER_GUI);
+      context.draw_filled_rect(Vector(selection.x1 - pos_x, selection.y1 - pos_y + h), Vector(w, SELECT_W), Color(SELECT_CLR), LAYER_GUI);
+      context.draw_filled_rect(Vector(selection.x1 - pos_x, selection.y1 - pos_y), Vector(SELECT_W, h), Color(SELECT_CLR), LAYER_GUI);
+    }
   }
 
 
   /* draw button bar */
   }
 
 
   /* draw button bar */
-  fillrect(screen->w - 64, 0, 64, screen->h, 50, 50, 50,255);
+  context.draw_filled_rect(Vector(screen->w - 64, 0), Vector(64, screen->h), Color(50, 50, 50,255), LAYER_GUI);
 
   if(le_current.IsTile())
   {
 
   if(le_current.IsTile())
   {
-    Tile::draw(19 * 32, 14 * 32, le_current.tile);
+//    le_level->get_sector("main")->solids->draw(context);
+
+/*screen->w - 32, screen->h - 32, le_current.tile);
     if(TileManager::instance()->get(le_current.tile)->editor_images.size() > 0)
     if(TileManager::instance()->get(le_current.tile)->editor_images.size() > 0)
-      TileManager::instance()->get(le_current.tile)->editor_images[0]->draw( 19 * 32, 14 * 32);
+      TileManager::instance()->get(le_current.tile)->editor_images[0]->draw( screen->w - 32, screen->h - 32);*/
   }
   }
-  if(le_current.IsObject())
+#if 0 // XXX FIXME TODO: Do we have a new solution for draw_on_screen()?
+  if(le_current.IsObject() && MouseCursor::current() != mouse_select_object)
   {
   {
-    le_current.obj->draw_on_screen(19 * 32, 14 * 32);
+    le_current.obj->draw_on_screen(screen->w - 32, screen->h - 32);
     le_current.obj->draw_on_screen(cursor_x,cursor_y);
   }
     le_current.obj->draw_on_screen(cursor_x,cursor_y);
   }
+#endif
+
+  if(mouse_select_object && selected_game_object != NULL)
+  {
+    fillrect(selected_game_object->base.x-pos_x,selected_game_object->base.y-pos_y,selected_game_object->base.width,3,255,0,0,255);
+    fillrect(selected_game_object->base.x-pos_x,selected_game_object->base.y-pos_y,3,selected_game_object->base.height,255,0,0,255);
+    fillrect(selected_game_object->base.x-pos_x,selected_game_object->base.y-pos_y+selected_game_object->base.height,selected_game_object->base.width,3,255,0,0,255);
+    fillrect(selected_game_object->base.x-pos_x+selected_game_object->base.width,selected_game_object->base.y-pos_y,3,selected_game_object->base.height,255,0,0,255);
+  }
 
 
-  if(le_world != NULL)
+  if(le_level != NULL)
   {
   {
-    le_save_level_bt->draw();
-    le_exit_bt->draw();
-    le_test_level_bt->draw();
-    le_next_level_bt->draw();
-    le_previous_level_bt->draw();
-    le_rubber_bt->draw();
+    le_save_level_bt->draw(context);
+    le_exit_bt->draw(context);
+    le_test_level_bt->draw(context);
+    le_next_level_bt->draw(context);
+    le_previous_level_bt->draw(context);
+    le_rubber_bt->draw(context);
     if(le_selection_mode == SQUARE)
     if(le_selection_mode == SQUARE)
-      le_select_mode_one_bt->draw();
+      le_select_mode_one_bt->draw(context);
     else if(le_selection_mode == CURSOR)
     else if(le_selection_mode == CURSOR)
-      le_select_mode_two_bt->draw();
-    le_settings_bt->draw();
-    le_move_right_bt->draw();
-    le_move_left_bt->draw();
-    le_tilegroup_bt->draw();
-    le_objects_bt->draw();
+      le_select_mode_two_bt->draw(context);
+    le_settings_bt->draw(context);
+    le_move_right_bt->draw(context);
+    le_move_left_bt->draw(context);
+    le_move_up_bt->draw(context);
+    le_move_down_bt->draw(context);
+    le_tilegroup_bt->draw(context);
+    le_objects_bt->draw(context);
     if(!cur_tilegroup.empty())
     if(!cur_tilegroup.empty())
-      tilegroups_map[cur_tilegroup]->draw();
+      tilegroups_map[cur_tilegroup]->draw(context);
     else if(!cur_objects.empty())
     {
     else if(!cur_objects.empty())
     {
-      objects_map[cur_objects]->draw();
+      objects_map[cur_objects]->draw(context);
     }
 
     }
 
-    le_tilemap_panel->draw();
+    le_tilemap_panel->draw(context);
+
+    if(!cur_objects.empty())
+    {
+      le_object_select_bt->draw(context);
+      le_object_properties_bt->draw(context);
+    }
 
 
-    sprintf(str, "%d/%d", le_level,le_level_subset->levels);
-    white_text->drawf(str, (le_level_subset->levels < 10) ? -10 : 0, 16, A_RIGHT, A_TOP, 0);
+    sprintf(str, "%d/%d", le_levelnb, le_level_subset->get_num_levels());
+    context.draw_text(white_text, str, Vector((le_level_subset->get_num_levels() < 10) ? -10 : 0, 16), LAYER_GUI);
 
     if(!le_help_shown)
 
     if(!le_help_shown)
-      white_small_text->draw("F1 for Help", 10, 430, 1);
+      context.draw_text(white_small_text, "F1 for Help", Vector(10, 430), LAYER_GUI);
+
+    if(display_level_info.check())
+      context.draw_text_center(white_text, le_level->name.c_str(), Vector(0, 0), LAYER_GUI);
   }
   else
   {
     if(!Menu::current())
   }
   else
   {
     if(!Menu::current())
-      white_small_text->draw("No Level Subset loaded - Press ESC and choose one in the menu", 10, 430, 1);
+      context.draw_text(white_small_text, "No Level Subset loaded - Press ESC and choose one in the menu", Vector(10, 430), LAYER_GUI);
     else
     else
-      white_small_text->draw("No Level Subset loaded", 10, 430, 1);
+      context.draw_text(white_small_text, "No Level Subset loaded", Vector(10, 430), LAYER_GUI);
   }
 
 }
 
   }
 
 }
 
-void le_drawlevel()
+void LevelEditor::drawlevel(DrawingContext& context)
 {
 {
-  unsigned int y,x,s;
-  Uint8 a;
+//  unsigned int y,x;
+//  Uint8 a;
 
   /* Draw the real background */
 
   /* Draw the real background */
-  if(le_world->get_level()->bkgd_image[0] != '\0')
-  {
-    s = (int)((float)pos_x * ((float)le_world->get_level()->bkgd_speed/60.)) % screen->w;
-    le_world->get_level()->img_bkgd->draw_part(s,0,0,0,
-        le_world->get_level()->img_bkgd->w - s - 32, le_world->get_level()->img_bkgd->h);
-    le_world->get_level()->img_bkgd->draw_part(0,0,screen->w - s - 32 ,0,s,
-        le_world->get_level()->img_bkgd->h);
-  }
-  else
-  {
-    drawgradient(le_world->get_level()->bkgd_top, le_world->get_level()->bkgd_bottom);
-  }
+  le_level->get_sector("main")->background->draw(context);
 
   if(le_current.IsTile())
   {
 
   if(le_current.IsTile())
   {
-    Tile::draw(cursor_x-pos_x, cursor_y,le_current.tile,128);
+//le_level->get_sector("main")->solids->draw(context);
+/*
+    Tile::draw(cursor_x-pos_x, cursor_y-pos_y,le_current.tile,128);
     if(!TileManager::instance()->get(le_current.tile)->images.empty())
     if(!TileManager::instance()->get(le_current.tile)->images.empty())
-      fillrect(cursor_x-pos_x,cursor_y,TileManager::instance()->get(le_current.tile)->images[0]->w,TileManager::instance()->get(le_current.tile)->images[0]->h,50,50,50,50);
+      fillrect(cursor_x-pos_x,cursor_y-pos_y,TileManager::instance()->get(le_current.tile)->images[0]->w,TileManager::instance()->get(le_current.tile)->images[0]->h,50,50,50,50);*/
   }
   }
+#if 0 // XXX FIXME TODO: Do we have a new solution for move_to()?
   if(le_current.IsObject())
   {
     le_current.obj->move_to(cursor_x, cursor_y);
   }
   if(le_current.IsObject())
   {
     le_current.obj->move_to(cursor_x, cursor_y);
   }
+#endif
 
   /*       clearscreen(current_level.bkgd_red, current_level.bkgd_green, current_level.bkgd_blue); */
 
 
   /*       clearscreen(current_level.bkgd_red, current_level.bkgd_green, current_level.bkgd_blue); */
 
-  for (y = 0; y < 15; ++y)
-    for (x = 0; x < 20; ++x)
+le_level->get_sector("main")->solids->draw(context);
+
+// FIXME: make tiles to be drawn semi-transparent when not selected
+#if 0
+  for (y = 0; y < VISIBLE_TILES_Y && y < (unsigned)le_level->get_section("main")->height; ++y)
+    for (x = 0; x < (unsigned)VISIBLE_TILES_X - 2; ++x)
     {
 
       if(active_tm == TM_BG)
     {
 
       if(active_tm == TM_BG)
@@ -908,63 +883,132 @@ void le_drawlevel()
       else
         a = 128;
 
       else
         a = 128;
 
-      Tile::draw(32*x - fmodf(pos_x, 32), y * 32, le_world->get_level()->bg_tiles[y][x + (int)(pos_x / 32)],a);
+      Tile::draw(32*x - fmodf(pos_x, 32), y*32 - fmodf(pos_y, 32),
+          le_level->bg_tiles[ (y + (int)(pos_y / 32)) * le_level->get_sector("main")->solids->get_width() + 
+          (x + (int)(pos_x / 32))],a);
 
       if(active_tm == TM_IA)
         a = 255;
       else
         a = 128;
 
 
       if(active_tm == TM_IA)
         a = 255;
       else
         a = 128;
 
-      Tile::draw(32*x - fmodf(pos_x, 32), y * 32, le_world->get_level()->ia_tiles[y][x + (int)(pos_x / 32)],a);
+      Tile::draw(32*x - fmodf(pos_x, 32), y*32 - fmodf(pos_y, 32),
+          le_level->ia_tiles[ (y + (int)(pos_y / 32)) * le_level->get_section("main")->width +       
+          (x + (int)(pos_x / 32))],a);
 
 
+      
       if(active_tm == TM_FG)
         a = 255;
       else
         a = 128;
 
       if(active_tm == TM_FG)
         a = 255;
       else
         a = 128;
 
-      Tile::draw(32*x - fmodf(pos_x, 32), y * 32, le_world->get_level()->fg_tiles[y][x + (int)(pos_x / 32)],a);
+      Tile::draw(32*x - fmodf(pos_x, 32), y*32 - fmodf(pos_y, 32),
+          le_level->fg_tiles[ (y + (int)(pos_y / 32)) * le_level->get_sector("main")->solids->get_width() +       
+          (x + (int)(pos_x / 32))],a);
 
       /* draw whats inside stuff when cursor is selecting those */
       /* (draw them all the time - is this the right behaviour?) */
 
       /* draw whats inside stuff when cursor is selecting those */
       /* (draw them all the time - is this the right behaviour?) */
-      Tile* edit_image = TileManager::instance()->get(le_world->get_level()->ia_tiles[y][x + (int)(pos_x / 32)]);
+      Tile* edit_image = TileManager::instance()->get(
+          le_level->ia_tiles
+          [ (y + (int)(pos_y / 32)) * le_level->get_section("main")->width + (x + (int)(pos_x / 32))]);
       if(edit_image && !edit_image->editor_images.empty())
       if(edit_image && !edit_image->editor_images.empty())
-        edit_image->editor_images[0]->draw( x * 32 - ((int)pos_x % 32), y*32);
+        edit_image->editor_images[0]->draw( x * 32 - ((int)pos_x % 32), y*32 - ((int)pos_y % 32));
 
     }
 
     }
-
+#endif
   /* Draw the Bad guys: */
   /* Draw the Bad guys: */
-  for (std::list<BadGuy*>::iterator it = le_world->bad_guys.begin(); it != le_world->bad_guys.end(); ++it)
+  for (std::vector<GameObject*>::iterator it = le_level->get_sector("main")->gameobjects.begin();
+       it != le_level->get_sector("main")->gameobjects.end(); ++it)
   {
   {
+    BadGuy* badguy = dynamic_cast<BadGuy*> (*it);
+    if(badguy == 0)
+      continue;
+    
     /* to support frames: img_bsod_left[(frame / 5) % 4] */
     /* to support frames: img_bsod_left[(frame / 5) % 4] */
-
-    scroll_x = pos_x;
-    (*it)->draw();
+    badguy->draw(context);
   }
 
   }
 
-
   /* Draw the player: */
   /* for now, the position is fixed at (100, 240) */
   /* Draw the player: */
   /* for now, the position is fixed at (100, 240) */
-  largetux.walk_right->draw( 100 - pos_x, 240);
+  largetux.walk_right->draw(context, Vector(100 - pos_x, 240 - pos_y), LAYER_OBJECTS-1);
 }
 
 }
 
-void le_change_object_properties(GameObject *pobj)
+void LevelEditor::change_object_properties(GameObject *pobj)
 {
 {
+  DrawingContext context;
+    
   Menu* object_properties_menu = new Menu();
   Menu* object_properties_menu = new Menu();
+  bool loop = true;
 
 
-  object_properties_menu->additem(MN_LABEL,pobj->type() + " Properties",0,0);
+  std::string type = typeid(pobj).name();
+  object_properties_menu->additem(MN_LABEL, type + " Properties",0,0);
   object_properties_menu->additem(MN_HL,"",0,0);
   object_properties_menu->additem(MN_HL,"",0,0);
-  /*object_properties_menu->additem(MN_TEXTFIELD,"Title",0,0,MNID_SUBSETTITLE);
-  object_properties_menu->additem(MN_TEXTFIELD,"Description",0,0,MNID_SUBSETDESCRIPTION);
-  object_properties_menu->additem(MN_HL,"",0,0);
-  object_properties_menu->additem(MN_ACTION,"Save Changes",0,0,MNID_SUBSETSAVECHANGES);*/
+
+  BadGuy* pbad = dynamic_cast<BadGuy*>(pobj);
+  if(pobj != 0)
+  {
+    object_properties_menu->additem(MN_STRINGSELECT,"Kind",0,0,1);
+    for(int i = 0; i < NUM_BadGuyKinds; ++i)
+    {
+      object_properties_menu->get_item_by_id(1).list.first.insert(
+          badguykind_to_string(static_cast<BadGuyKind>(i)));
+      if(pbad->kind == i)
+        object_properties_menu->get_item_by_id(1).list.second = object_properties_menu->get_item_by_id(1).list.first.find(badguykind_to_string(static_cast<BadGuyKind>(i)));
+    }
+    object_properties_menu->additem(MN_TOGGLE,"StayOnPlatform",pbad->stay_on_platform,0,2);
+  }
+
   object_properties_menu->additem(MN_HL,"",0,0);
   object_properties_menu->additem(MN_HL,"",0,0);
-  object_properties_menu->additem(MN_BACK,"Apply",0,0);
+  object_properties_menu->additem(MN_ACTION,"Ok",0,0,3);
+
+  Menu::set_current(object_properties_menu);
+
+  while(loop)
+  {
+    SDL_Event event;
+
+    while (SDL_PollEvent(&event))
+    {
+      object_properties_menu->event(event);
+    }
 
 
+    //cap_screen->draw(0,0);
+
+    object_properties_menu->draw(context);
+    object_properties_menu->action();
+
+    switch (object_properties_menu->check())
+    {
+    case 3:
+      {
+      BadGuy* pbad = dynamic_cast<BadGuy*>(pobj);
+      if(pbad != 0) {
+        BadGuy* pbad = dynamic_cast<BadGuy*>(pobj);
+        pbad->kind =  badguykind_from_string((*object_properties_menu->get_item_by_id(1).list.second));
+        pbad->stay_on_platform = object_properties_menu->get_item_by_id(2).toggled;
+      }
+      loop = false;
+      break;
+      }
+    default:
+      break;
+    }
+
+    if(Menu::current() == NULL)
+      loop = false;
+
+    mouse_cursor->draw(context);
+//    context.draw_filled_rect();
+    SDL_Delay(25);
+  }
+
+  //delete cap_screen;
+  Menu::set_current(0);
   delete object_properties_menu;
 }
 
 
   delete object_properties_menu;
 }
 
 
-void le_checkevents()
+void LevelEditor::checkevents()
 {
   SDLKey key;
   SDLMod keymod;
 {
   SDLKey key;
   SDLMod keymod;
@@ -978,7 +1022,7 @@ void le_checkevents()
     if (Menu::current())
     {
       Menu::current()->event(event);
     if (Menu::current())
     {
       Menu::current()->event(event);
-      if(!le_world && !Menu::current())
+      if(!le_level && !Menu::current())
         Menu::set_current(leveleditor_menu);
     }
     else
         Menu::set_current(leveleditor_menu);
     }
     else
@@ -1001,57 +1045,16 @@ void le_checkevents()
           case SDLK_ESCAPE:
             Menu::set_current(leveleditor_menu);
             break;
           case SDLK_ESCAPE:
             Menu::set_current(leveleditor_menu);
             break;
-          case SDLK_LEFT:
-            if(fire == DOWN)
-              cursor_x -= KEY_CURSOR_SPEED;
-            else
-              cursor_x -= KEY_CURSOR_FASTSPEED;
-
-            if(cursor_x < pos_x + MOUSE_LEFT_MARGIN)
-              pos_x = cursor_x - MOUSE_LEFT_MARGIN;
-
-            break;
-          case SDLK_RIGHT:
-            if(fire == DOWN)
-              cursor_x += KEY_CURSOR_SPEED;
-            else
-              cursor_x += KEY_CURSOR_FASTSPEED;
-
-            if(cursor_x > pos_x + MOUSE_RIGHT_MARGIN-32)
-              pos_x = cursor_x - MOUSE_RIGHT_MARGIN+32;
-
-            break;
-          case SDLK_UP:
-            if(fire == DOWN)
-              cursor_y -= KEY_CURSOR_SPEED;
-            else
-              cursor_y -= KEY_CURSOR_FASTSPEED;
-
-            if(cursor_y < 0)
-              cursor_y = 0;
-            break;
-          case SDLK_DOWN:
-            if(fire == DOWN)
-              cursor_y += KEY_CURSOR_SPEED;
-            else
-              cursor_y += KEY_CURSOR_FASTSPEED;
-
-            if(cursor_y > screen->h-32)
-              cursor_y = screen->h-32;
-            break;
-          case SDLK_LCTRL:
-            fire =UP;
-            break;
           case SDLK_F1:
           case SDLK_F1:
-            if(le_world != NULL)
-              le_showhelp();
+            if(le_level != NULL)
+              showhelp();
             break;
           case SDLK_HOME:
             cursor_x = 0;
             pos_x = cursor_x;
             break;
           case SDLK_END:
             break;
           case SDLK_HOME:
             cursor_x = 0;
             pos_x = cursor_x;
             break;
           case SDLK_END:
-            cursor_x = (le_world->get_level()->width * 32) - 32;
+            cursor_x = (le_level->get_sector("main")->solids->get_width() * 32) - 32;
             pos_x = cursor_x;
             break;
           case SDLK_F9:
             pos_x = cursor_x;
             break;
           case SDLK_F9:
@@ -1061,25 +1064,15 @@ void le_checkevents()
             break;
           }
           break;
             break;
           }
           break;
-        case SDL_KEYUP:        /* key released */
-          switch(event.key.keysym.sym)
-          {
-          case SDLK_LCTRL:
-            fire = DOWN;
-            break;
-          default:
-            break;
-          }
-          break;
         case SDL_MOUSEBUTTONDOWN:
           if(event.button.button == SDL_BUTTON_LEFT)
           {
             le_mouse_pressed[LEFT] = true;
 
             selection.x1 = event.motion.x + pos_x;
         case SDL_MOUSEBUTTONDOWN:
           if(event.button.button == SDL_BUTTON_LEFT)
           {
             le_mouse_pressed[LEFT] = true;
 
             selection.x1 = event.motion.x + pos_x;
-            selection.y1 = event.motion.y;
+            selection.y1 = event.motion.y + pos_y;
             selection.x2 = event.motion.x + pos_x;
             selection.x2 = event.motion.x + pos_x;
-            selection.y2 = event.motion.y;
+            selection.y2 = event.motion.y + pos_y;
           }
           else if(event.button.button == SDL_BUTTON_RIGHT)
           {
           }
           else if(event.button.button == SDL_BUTTON_RIGHT)
           {
@@ -1108,7 +1101,7 @@ void le_checkevents()
             if(le_current.IsTile())
             {
               cursor_x = ((int)(pos_x + x) / 32) * 32;
             if(le_current.IsTile())
             {
               cursor_x = ((int)(pos_x + x) / 32) * 32;
-              cursor_y = ((int) y / 32) * 32;
+              cursor_y = ((int)(pos_y + y) / 32) * 32;
             }
             else
             {
             }
             else
             {
@@ -1119,25 +1112,27 @@ void le_checkevents()
             if(le_mouse_pressed[LEFT])
             {
               selection.x2 = x + pos_x;
             if(le_mouse_pressed[LEFT])
             {
               selection.x2 = x + pos_x;
-              selection.y2 = y;
+              selection.y2 = y + pos_y;
             }
 
             if(le_mouse_pressed[RIGHT])
             {
               pos_x += -1 * event.motion.xrel;
             }
 
             if(le_mouse_pressed[RIGHT])
             {
               pos_x += -1 * event.motion.xrel;
+              pos_y += -1 * event.motion.yrel;
             }
           }
           break;
             }
           }
           break;
-        case SDL_QUIT: // window closed
-          done = 1;
-          break;
         default:
           break;
         }
       }
         default:
           break;
         }
       }
+      else if(event.type == SDL_QUIT) /* window closing */
+      {
+      done = 1;
+      }
     }
 
     }
 
-    if(le_world != NULL)
+    if(le_level != NULL)
     {
       if(event.type == SDL_KEYDOWN || event.type == SDL_KEYUP || ((event.type == SDL_MOUSEBUTTONDOWN || SDL_MOUSEMOTION) && (event.motion.x > screen->w-64 && event.motion.x < screen->w &&
           event.motion.y > 0 && event.motion.y < screen->h)))
     {
       if(event.type == SDL_KEYDOWN || event.type == SDL_KEYUP || ((event.type == SDL_MOUSEBUTTONDOWN || SDL_MOUSEMOTION) && (event.motion.x > screen->w-64 && event.motion.x < screen->w &&
           event.motion.y > 0 && event.motion.y < screen->h)))
@@ -1150,10 +1145,10 @@ void le_checkevents()
           /* Check for button events */
           le_test_level_bt->event(event);
           if(le_test_level_bt->get_state() == BUTTON_CLICKED)
           /* Check for button events */
           le_test_level_bt->event(event);
           if(le_test_level_bt->get_state() == BUTTON_CLICKED)
-            le_testlevel();
+            testlevel();
           le_save_level_bt->event(event);
           if(le_save_level_bt->get_state() == BUTTON_CLICKED)
           le_save_level_bt->event(event);
           if(le_save_level_bt->get_state() == BUTTON_CLICKED)
-            le_world->get_level()->save(le_level_subset->name.c_str(),le_level);
+            le_level->save(le_level_subset->name.c_str());
           le_exit_bt->event(event);
           if(le_exit_bt->get_state() == BUTTON_CLICKED)
           {
           le_exit_bt->event(event);
           if(le_exit_bt->get_state() == BUTTON_CLICKED)
           {
@@ -1162,34 +1157,52 @@ void le_checkevents()
           le_next_level_bt->event(event);
           if(le_next_level_bt->get_state() == BUTTON_CLICKED)
           {
           le_next_level_bt->event(event);
           if(le_next_level_bt->get_state() == BUTTON_CLICKED)
           {
-            if(le_level < le_level_subset->levels)
+            if(le_levelnb < le_level_subset->get_num_levels())
             {
             {
-              le_goto_level(++le_level);
+              goto_level(le_levelnb+1);
             }
             else
             {
               Level new_lev;
               char str[1024];
             }
             else
             {
               Level new_lev;
               char str[1024];
-              sprintf(str,"Level %d doesn't exist. Create it?",le_level+1);
-              if(confirm_dialog(str))
+              sprintf(str,"Level %d doesn't exist. Create it?",le_levelnb+1);
+              Surface* surf = new Surface(le_level->get_sector("main")->background->get_image(), false);
+              if(confirm_dialog(surf, str))
               {
               {
-                new_lev.init_defaults();
-                new_lev.save(le_level_subset->name.c_str(),++le_level);
-                le_level_subset->levels = le_level;
-                le_goto_level(le_level);
+                le_level_subset->add_level("newlevel.stl");
+                new_lev.save(le_level_subset->get_level_filename(le_levelnb+1));
+                goto_level(le_levelnb);
               }
               }
+             if(surf != NULL)
+              delete surf;
             }
           }
           le_previous_level_bt->event(event);
           if(le_previous_level_bt->get_state() == BUTTON_CLICKED)
           {
             }
           }
           le_previous_level_bt->event(event);
           if(le_previous_level_bt->get_state() == BUTTON_CLICKED)
           {
-            if(le_level > 1)
-              le_goto_level(--le_level);
+            if(le_levelnb > 1)
+              goto_level(le_levelnb -1);
           }
           le_rubber_bt->event(event);
           if(le_rubber_bt->get_state() == BUTTON_CLICKED)
             le_current.Tile(0);
 
           }
           le_rubber_bt->event(event);
           if(le_rubber_bt->get_state() == BUTTON_CLICKED)
             le_current.Tile(0);
 
+          if(!cur_objects.empty())
+          {
+            le_object_select_bt->event(event);
+            if(le_object_select_bt->get_state() == BUTTON_CLICKED)
+            {
+              MouseCursor::set_current(mouse_select_object);
+            }
+
+            le_object_properties_bt->event(event);
+            if(le_object_properties_bt->get_state() == BUTTON_CLICKED)
+            {
+              change_object_properties(selected_game_object);
+            }
+          }
+
+
           if(le_selection_mode == SQUARE)
           {
             le_select_mode_one_bt->event(event);
           if(le_selection_mode == SQUARE)
           {
             le_select_mode_one_bt->event(event);
@@ -1315,7 +1328,9 @@ void le_checkevents()
             {
               if(pbutton->get_state() == BUTTON_CLICKED)
               {
             {
               if(pbutton->get_state() == BUTTON_CLICKED)
               {
-                le_current.Object(pbutton->get_game_object());
+#if 0   // TODO FIXME XXX: New solution for this?
+                le_current.Object(pbutton->get_drawable());
+#endif
               }
             }
           }
               }
             }
           }
@@ -1324,7 +1339,7 @@ void le_checkevents()
           {
             if(pbutton->get_state() == BUTTON_CLICKED)
             {
           {
             if(pbutton->get_state() == BUTTON_CLICKED)
             {
-              active_tm = static_cast<TileMapType>(pbutton->get_tag());
+              active_tm = pbutton->get_tag();
             }
           }
         }
             }
           }
         }
@@ -1352,24 +1367,84 @@ void le_checkevents()
       {
         if(le_mouse_pressed[LEFT])
         {
       {
         if(le_mouse_pressed[LEFT])
         {
-          if(le_current.IsTile())
-            le_change(cursor_x, cursor_y, active_tm, le_current.tile);
+          if(MouseCursor::current() != mouse_select_object)
+          {
+            if(le_current.IsTile())
+              change(cursor_x, cursor_y, active_tm, le_current.tile);
+          }
         }
         else if(le_mouse_clicked[LEFT])
         {
         }
         else if(le_mouse_clicked[LEFT])
         {
-          if(le_current.IsObject())
+          if(MouseCursor::current() == mouse_select_object)
           {
           {
-           le_level_changed  = true;
-            std::string type = le_current.obj->type();
-            if(type == "BadGuy")
+            bool object_got_hit = false;
+            base_type cursor_base;
+           if(le_current.IsTile())
+           {
+            cursor_base.x = cursor_x;
+            cursor_base.y = cursor_y;
+           }
+           else if(le_current.IsObject())
+           {
+            cursor_base.x = cursor_x + pos_x;
+            cursor_base.y = cursor_y + pos_y;      
+           }
+            cursor_base.width = 32;
+            cursor_base.height = 32;
+
+            for(std::vector<GameObject*>::iterator it =
+                le_level->get_sector("main")->gameobjects.begin();
+                it != le_level->get_sector("main")->gameobjects.end(); ++it) {
+              MovingObject* mobj = dynamic_cast<MovingObject*> (*it);
+              if(!mobj)
+                continue;
+
+              if(rectcollision(cursor_base, mobj->base))
+              {
+                selected_game_object = mobj;
+                object_got_hit = true;
+                break;
+              }
+            }
+
+            if(!object_got_hit)
             {
             {
+              selected_game_object = NULL;
+              le_object_properties_bt->set_active(false);
+            }
+            else
+              le_object_properties_bt->set_active(true);
+
+            MouseCursor::set_current(mouse_cursor);
+
+          }
+          else
+          {
+            // FIXME TODO
+#if 0
+//FIXME: objects interactions with the level editor should have a major improvement
+            if(le_current.IsObject())
+            {
+              le_level_changed  = true;
               BadGuy* pbadguy = dynamic_cast<BadGuy*>(le_current.obj);
 
               BadGuy* pbadguy = dynamic_cast<BadGuy*>(le_current.obj);
 
-              le_world->bad_guys.push_back(new BadGuy(cursor_x+scroll_x, cursor_y,pbadguy->kind,false));
-              le_world->get_level()->badguy_data.push_back(le_world->bad_guys.back());
+              if(pbadguy)
+              {
+                Camera& camera = *le_level->get_sector("main")->camera;
+
+                le_level->get_sector("main")->bad_guys.push_back(
+                    new BadGuy(pbadguy->kind,
+                      cursor_x + camera.get_translation().x,
+                      cursor_y + camera.get_translation().y));
+                le_level->get_sector("main")->gameobjects.push_back(le_level->get_sector("main")->bad_guys.back());
+              }
             }
             }
+#endif
+
           }
           }
+         
           le_mouse_clicked[LEFT] = false;
           le_mouse_clicked[LEFT] = false;
+
         }
       }
     }
         }
       }
     }
@@ -1378,16 +1453,21 @@ void le_checkevents()
   {
     show_minimap = false;
 
   {
     show_minimap = false;
 
+    if (event.type == SDL_KEYDOWN && event.key.keysym.sym == SDLK_TAB)
+      show_minimap = true;
+
     le_move_left_bt->event(event);
     le_move_right_bt->event(event);
     le_move_left_bt->event(event);
     le_move_right_bt->event(event);
+    le_move_up_bt->event(event);
+    le_move_down_bt->event(event);
     switch(le_move_left_bt->get_state())
     {
     case BUTTON_PRESSED:
     switch(le_move_left_bt->get_state())
     {
     case BUTTON_PRESSED:
-      pos_x -= 192;
+      pos_x -= KEYBOARD_SPEED;
       show_minimap = true;
       break;
     case BUTTON_HOVER:
       show_minimap = true;
       break;
     case BUTTON_HOVER:
-      pos_x -= 32;
+      pos_x -= MOUSE_SPEED;
       show_minimap = true;
       break;
     case BUTTON_CLICKED:
       show_minimap = true;
       break;
     case BUTTON_CLICKED:
@@ -1400,11 +1480,11 @@ void le_checkevents()
     switch(le_move_right_bt->get_state())
     {
     case BUTTON_PRESSED:
     switch(le_move_right_bt->get_state())
     {
     case BUTTON_PRESSED:
-      pos_x += 192;
+      pos_x += KEYBOARD_SPEED;
       show_minimap = true;
       break;
     case BUTTON_HOVER:
       show_minimap = true;
       break;
     case BUTTON_HOVER:
-      pos_x += 32;
+      pos_x += MOUSE_SPEED;
       show_minimap = true;
       break;
     case BUTTON_CLICKED:
       show_minimap = true;
       break;
     case BUTTON_CLICKED:
@@ -1414,11 +1494,54 @@ void le_checkevents()
       break;
     }
 
       break;
     }
 
-  }
+    switch(le_move_up_bt->get_state())
+    {
+    case BUTTON_PRESSED:
+      pos_y -= KEYBOARD_SPEED;
+      show_minimap = true;
+      break;
+    case BUTTON_HOVER:
+      pos_y -= MOUSE_SPEED;
+      show_minimap = true;
+      break;
+    case BUTTON_CLICKED:
+      show_minimap = true;
+      break;
+    default:
+      break;
+    }
 
 
+    switch(le_move_down_bt->get_state())
+    {
+    case BUTTON_PRESSED:
+      pos_y += KEYBOARD_SPEED;
+      show_minimap = true;
+      break;
+    case BUTTON_HOVER:
+      pos_y += MOUSE_SPEED;
+      show_minimap = true;
+      break;
+    case BUTTON_CLICKED:
+      show_minimap = true;
+      break;
+    default:
+      break;
+    }
+
+    /* checking if pos_x and pos_y is within the limits... */
+    if((unsigned)pos_x > (le_level->get_sector("main")->solids->get_width() * 32 + 32*2) - screen->w)
+      pos_x = (le_level->get_sector("main")->solids->get_width() * 32 + 32*2) - screen->w;
+    if(pos_x < 0)
+      pos_x = 0;
+
+    if((unsigned)pos_y > (le_level->get_sector("main")->solids->get_height() * 32) - screen->h)
+      pos_y = (le_level->get_sector("main")->solids->get_height() * 32) - screen->h;
+    if(pos_y < 0)
+      pos_y = 0;
+  }
 }
 
 }
 
-void le_highlight_selection()
+void LevelEditor::highlight_selection()
 {
   int x1, x2, y1, y2;
 
 {
   int x1, x2, y1, y2;
 
@@ -1448,23 +1571,22 @@ void le_highlight_selection()
   y1 /= 32;
   y2 /= 32;
 
   y1 /= 32;
   y2 /= 32;
 
-  fillrect(x1*32-pos_x, y1*32,32* (x2 - x1 + 1),32 * (y2 - y1 + 1),173,234,177,103);
+  fillrect(x1*32-pos_x, y1*32-pos_y,32* (x2 - x1 + 1),32 * (y2 - y1 + 1),173,234,177,103);
 }
 
 }
 
-void le_change(float x, float y, int tm, unsigned int c)
+void LevelEditor::change(float x, float y, int tm, unsigned int c)
 {
 {
-  if(le_world != NULL)
+  if(le_level != NULL)
   {
     int xx,yy;
     int x1, x2, y1, y2;
   {
     int xx,yy;
     int x1, x2, y1, y2;
-    unsigned int i = 0;
 
     le_level_changed = true;
 
     le_level_changed = true;
-    
+
     switch(le_selection_mode)
     {
     case CURSOR:
     switch(le_selection_mode)
     {
     case CURSOR:
-      le_world->get_level()->change(x,y,tm,c);
+      change(x,y,tm,c);
 
       base_type cursor_base;
       cursor_base.x = x;
 
       base_type cursor_base;
       cursor_base.x = x;
@@ -1473,14 +1595,22 @@ void le_change(float x, float y, int tm, unsigned int c)
       cursor_base.height = 32;
 
       /* if there is a bad guy over there, remove it */
       cursor_base.height = 32;
 
       /* if there is a bad guy over there, remove it */
-      for(std::list<BadGuy*>::iterator it = le_world->bad_guys.begin(); it != le_world->bad_guys.end(); ++it, ++i)
-        if(rectcollision(cursor_base,(*it)->base))
+      // XXX TODO
+      for(std::vector<GameObject*>::iterator it = le_level->get_sector("main")->gameobjects.begin();
+            it != le_level->get_sector("main")->gameobjects.end(); ++it) {
+        BadGuy* badguy = dynamic_cast<BadGuy*>((*it));
+        if (badguy)
         {
         {
-          delete (*it);
-          le_world->bad_guys.erase(it);
-          le_world->get_level()->badguy_data.erase(le_world->get_level()->badguy_data.begin() + i);
-          break;
+          if(rectcollision(cursor_base, badguy->base))
+          {
+            delete (*it);
+            le_level->get_sector("main")->gameobjects.erase(std::remove(le_level->get_sector("main")->gameobjects.begin(),
+               le_level->get_sector("main")->gameobjects.end(), *it),
+               le_level->get_sector("main")->gameobjects.end());
+            break;
+          }
         }
         }
+      }
 
       break;
     case SQUARE:
 
       break;
     case SQUARE:
@@ -1511,28 +1641,31 @@ void le_change(float x, float y, int tm, unsigned int c)
       y2 /= 32;
 
       /* if there is a bad guy over there, remove it */
       y2 /= 32;
 
       /* if there is a bad guy over there, remove it */
-      for(std::list<BadGuy*>::iterator it = le_world->bad_guys.begin();
-          it != le_world->bad_guys.end(); /* will be at end of loop */)
+      // TODO FIXME
+      for(std::vector<GameObject*>::iterator it = le_level->get_sector("main")->gameobjects.begin();
+          it != le_level->get_sector("main")->gameobjects.end(); ++it /* will be at end of loop */)
       {
       {
-        if((*it)->base.x/32 >= x1 && (*it)->base.x/32 <= x2
-            && (*it)->base.y/32 >= y1 && (*it)->base.y/32 <= y2)
+        MovingObject* pmobject = dynamic_cast<MovingObject*> (*it);       
+        if (pmobject)
         {
         {
-          delete (*it);
-          it = le_world->bad_guys.erase(it);
-          le_world->get_level()->badguy_data.erase(le_world->get_level()->badguy_data.begin() + i);
-          continue;
-        }
-        else
-        {
-          ++i;
-          ++it;
+          if(pmobject->base.x/32 >= x1 && pmobject->base.x/32 <= x2
+              && pmobject->base.y/32 >= y1 && pmobject->base.y/32 <= y2)
+          {
+            delete (*it);
+            le_level->get_sector("main")->gameobjects.erase(std::remove(le_level->get_sector("main")->gameobjects.begin(), le_level->get_sector("main")->gameobjects.end(), *it), le_level->get_sector("main")->gameobjects.end());
+            continue;
+          }
+          else
+          {
+            ++it;
+          }
         }
       }
 
       for(xx = x1; xx <= x2; xx++)
         for(yy = y1; yy <= y2; yy++)
         {
         }
       }
 
       for(xx = x1; xx <= x2; xx++)
         for(yy = y1; yy <= y2; yy++)
         {
-          le_world->get_level()->change(xx*32, yy*32, tm, c);
+          change(xx*32, yy*32, tm, c);
 
         }
       break;
 
         }
       break;
@@ -1542,37 +1675,38 @@ void le_change(float x, float y, int tm, unsigned int c)
   }
 }
 
   }
 }
 
-void le_testlevel()
+void LevelEditor::testlevel()
 {
   //Make sure a time value is set when testing the level
 {
   //Make sure a time value is set when testing the level
-  if(le_world->get_level()->time_left == 0)
-    le_world->get_level()->time_left = 250;
+  if(le_level->time_left == 0)
+    le_level->time_left = 250;
 
 
-  le_world->get_level()->save("test", le_level);
+  le_level->save("test.stl");
 
 
-  GameSession session("test",le_level, ST_GL_TEST);
+  GameSession session("test.stl", ST_GL_TEST);
   session.run();
   player_status.reset();
 
   session.run();
   player_status.reset();
 
-  music_manager->halt_music();
+  SoundManager::get()->halt_music();
 
   Menu::set_current(NULL);
 
   Menu::set_current(NULL);
-  World::set_current(le_world);
 }
 
 }
 
-void le_showhelp()
+void LevelEditor::showhelp()
 {
 {
+  DrawingContext context;
+
   bool tmp_show_grid = le_show_grid;
   bool tmp_show_grid = le_show_grid;
+  SelectionMode temp_le_selection_mode = le_selection_mode;
+  le_selection_mode = NONE;
   show_selections = true;
   le_show_grid = false;
   le_help_shown = true;
 
   show_selections = true;
   le_show_grid = false;
   le_help_shown = true;
 
-  drawgradient(Color(0,0,0), Color(255,255,255));
-  le_drawinterface();
-
   SDL_Event event;
   SDL_Event event;
-  unsigned int i, done_;
-  char *text[] = {
+  unsigned int done_;
+  char str[1024];
+  char *text1[] = {
 
                    " - Supertux level editor tutorial - ",
                    "",
 
                    " - Supertux level editor tutorial - ",
                    "",
@@ -1583,7 +1717,7 @@ void le_showhelp()
                    "the left mouse button over the map",
                    "to \"paint\" your selection over",
                    "the screen.",
                    "the left mouse button over the map",
                    "to \"paint\" your selection over",
                    "the screen.",
-                  "",
+                   "",
                    "There are three layers for painting",
                    "tiles upon, Background layer,",
                    "the Interactive layer, and the",
                    "There are three layers for painting",
                    "tiles upon, Background layer,",
                    "the Interactive layer, and the",
@@ -1604,104 +1738,71 @@ void le_showhelp()
                     "the Interactive layer are those",
                     "which actually effect Tux in the",
                     "game.",
                     "the Interactive layer are those",
                     "which actually effect Tux in the",
                     "game.",
-                   "",
+                    "",
                     "Click the objects menu to put ",
                     "bad guys and other objects in the",
                     "game. Unlike placing tiles, you",
                     "cannot \"paint\" enemies. Click",
                     "them onto the screen one at a time.",
                     "Click the objects menu to put ",
                     "bad guys and other objects in the",
                     "game. Unlike placing tiles, you",
                     "cannot \"paint\" enemies. Click",
                     "them onto the screen one at a time.",
-                   "",
+                    "",
                     "To change the settings of your",
                     "level, click the button with the",
                     "screwdriver and wrench. From here",
                     "you can change the background,",
                     "music, length of the level,",
                     "To change the settings of your",
                     "level, click the button with the",
                     "screwdriver and wrench. From here",
                     "you can change the background,",
                     "music, length of the level,",
-                   "and more."
+                    "and more."
                   };
 
   char *text3[] = {
 
                     " - Supertux level editor tutorial - ",
                     "",
                   };
 
   char *text3[] = {
 
                     " - Supertux level editor tutorial - ",
                     "",
-                   "You may have more than one level.",
+                    "You may have more than one level.",
                     "Pressing the up and down buttons",
                     "above the button bar lets you",
                     "Pressing the up and down buttons",
                     "above the button bar lets you",
-                   "choose which one you are working on.",
-                   "",
+                    "choose which one you are working on.",
+                    "",
                     "If you would like to speed up your",
                     "level editing, a useful trick is",
                     "to learn the keyboard shortcuts.",
                     "If you would like to speed up your",
                     "level editing, a useful trick is",
                     "to learn the keyboard shortcuts.",
-                   "They are easy to learn, just right-",
-                   "click on the buttons.",
-                   "",
+                    "They are easy to learn, just right-",
+                    "click on the buttons.",
+                    "",
                     "Have fun making levels! If you make",
                     "some good ones, send them to us on",
                     "the SuperTux mailing list!",
                     "- SuperTux team"
                   };
                     "Have fun making levels! If you make",
                     "some good ones, send them to us on",
                     "the SuperTux mailing list!",
                     "- SuperTux team"
                   };
-               
-                 
-
-  blue_text->drawf("- Help -", 0, 30, A_HMIDDLE, A_TOP, 2);
-
-  for(i = 0; i < sizeof(text)/sizeof(char *); i++)
-    white_text->draw(text[i], 5, 80+(i*white_text->h), 1);
-
-  gold_text->drawf("Press Anything to Continue - Page 1/3", 0, 0, A_LEFT, A_BOTTOM, 1);
-
-  flipscreen();
-
-  done_ = 0;
-
-  while(done_ == 0)
-  {
-    done_ = wait_for_event(event);
-    SDL_Delay(50);
-  }
-
-  drawgradient(Color(0,0,0), Color(255,255,255));
-  le_drawinterface();
-
 
 
-  blue_text->drawf("- Help -", 0, 30, A_HMIDDLE, A_TOP, 2);
+  char **text[] = { text1, text2, text3 };
 
 
-  for(i = 0; i < sizeof(text2)/sizeof(char *); i++)
-    white_text->draw(text2[i], 5, 80+(i*white_text->h), 1);
-
-  gold_text->drawf("Press Anything to Continue - Page 2/3", 0, 0, A_LEFT, A_BOTTOM, 1);
-
-  flipscreen();
-
-  done_ = 0;
-
-  while(done_ == 0)
-  {
-    done_ = wait_for_event(event);
-    SDL_Delay(50);
-  }
-  
-    drawgradient(Color(0,0,0), Color(255,255,255));
-  le_drawinterface();
 
 
+  for(int i = 0; i < 3; i++)
+    {
+    context.draw_gradient(Color(0,0,0), Color(255,255,255), LAYER_BACKGROUND0);
+    drawinterface(context);
 
 
-  blue_text->drawf("- Help -", 0, 30, A_HMIDDLE, A_TOP, 2);
+    context.draw_text_center(blue_text, "- Help -", Vector(0, 30), LAYER_GUI);
 
 
-  for(i = 0; i < sizeof(text3)/sizeof(char *); i++)
-    white_text->draw(text3[i], 5, 80+(i*white_text->h), 1);
+    for(unsigned int t = 0; t < sizeof(text[i])/sizeof(char *); t++)
+      context.draw_text(white_text, text[i][t], Vector(5, 80+(t*white_text->get_height())), LAYER_GUI);
 
 
-  gold_text->drawf("Press Anything to Continue - Page 3/3", 0, 0, A_LEFT, A_BOTTOM, 1);
+    sprintf(str,"Press any key to continue - Page %d/%d?", i, static_cast<int>(sizeof(text)));
+    context.draw_text(gold_text, str, Vector(0, 0), LAYER_GUI);
 
 
-  flipscreen();
+    context.do_drawing();
 
 
-  done_ = 0;
+    done_ = 0;
 
 
-  while(done_ == 0)
-  {
-    done_ = wait_for_event(event);
-    SDL_Delay(50);
-  }
+    while(done_ == 0)
+      {
+      done_ = wait_for_event(event);
+      SDL_Delay(50);
+      }
+    }
 
   show_selections = true;
   le_show_grid = tmp_show_grid;
 
   show_selections = true;
   le_show_grid = tmp_show_grid;
+  le_selection_mode = temp_le_selection_mode;
   le_help_shown = false;
 }
   le_help_shown = false;
 }