#include "mmcache.h"
 #include "mmcat.h"
 
-mm_category_t g_categories [ MAX_CATS ];
+mm_category_t _categories [ MAX_CATS ];
+mm_category_t *g_categories = _categories;
 unsigned char g_categorycount = 0;
 
+mm_category_t _categories_invis [ MAX_CATS ];
+unsigned char _categories_inviscount = 0;
+
 mm_catmap_t g_catmaps [ MAX_CATS ];
 unsigned char g_catmapcount = 0;
 
 
 int cat_sort_score ( mm_appref_t *s1, mm_appref_t *s2 ) {
 
-  extern mm_category_t g_categories [ MAX_CATS ];
-  extern unsigned char g_categorycount;
   extern unsigned char ui_category;
 
   // are we in a directory browser, or looking at pnd-files?
   return ( NULL );
 }
 
-unsigned char category_meta_push ( char *catname, pnd_disco_t *app, pnd_conf_handle ovrh ) {
+unsigned char category_meta_push ( char *catname, pnd_disco_t *app, pnd_conf_handle ovrh, unsigned char visiblep ) {
   mm_category_t *cat;
+  unsigned char catcount = g_categorycount;
+
+  if ( ! catname ) {
+    return ( 1 ); // fine, just nada
+  }
+
+  if ( ! visiblep ) {
+    //return ( 1 ); // fine, suppress it
+
+    // serious evidence this was a rushed program
+    g_categories = _categories_invis;
+    g_categorycount = _categories_inviscount;
+
+  }
 
   // do we honour cat mapping at all?
   if ( pnd_conf_get_as_int_d ( g_conf, "categories.map_on", 0 ) ) {
     cat = category_map_query ( catname );
 
     if ( cat ) {
-      return ( category_push ( cat -> catname, app, ovrh, NULL /* fspath */ ) );
+      category_push ( cat -> catname, app, ovrh, NULL /* fspath */ );
+      goto visibility_hack_cleanup;
     }
 
     // not mapped.. but default?
     if ( pnd_conf_get_as_int_d ( g_conf, "categories.map_default_on", 0 ) ) {
       char *def = pnd_conf_get_as_char ( g_conf, "categories.map_default_cat" );
       if ( def ) {
-       return ( category_push ( def, app, ovrh, NULL /* fspath */ ) );
+       category_push ( def, app, ovrh, NULL /* fspath */ );
+       goto visibility_hack_cleanup;
       }
     }
 
   } // cat map is desired?
 
   // not default, just do it
-  return ( category_push ( catname, app, ovrh, NULL /* fspath */ ) );
+  category_push ( catname, app, ovrh, NULL /* fspath */ );
+  // hack :(
+ visibility_hack_cleanup:
+  if ( ! visiblep ) {
+    _categories_inviscount = g_categorycount;
+    g_categories = _categories;
+    g_categorycount = catcount;
+  }
+  return ( 1 );
 }
 
 unsigned char category_fs_restock ( mm_category_t *cat ) {
 
   pnd_box_handle disco;   // faux-applications generated from filesystem
 } mm_category_t;
 
-#define MAX_CATS 100
+#define MAX_CATS 200
 
 #define CATEGORY_ALL "All"
 
 
 unsigned char category_map_setup ( void ); // set up the mappings
 mm_category_t *category_map_query ( char *cat );
-unsigned char category_meta_push ( char *catname, pnd_disco_t *app, pnd_conf_handle ovrh );
+unsigned char category_meta_push ( char *catname, pnd_disco_t *app, pnd_conf_handle ovrh, unsigned char visiblep );
 
 // filesystem browser
 unsigned char category_fs_restock ( mm_category_t *cat );
 
       // push to All category
       // we do this first, so first category is always All
       if ( pnd_conf_get_as_int_d ( g_conf, "categories.do_all_cat", 1 ) ) {
-       if ( ! category_push ( g_x11_present ? CATEGORY_ALL "    (X11)" : CATEGORY_ALL "   (No X11)", iter, ovrh, NULL /* fspath */ ) ) {
-         pnd_log ( pndn_warning, "  Couldn't categorize to All: '%s'\n", IFNULL(iter -> title_en, "No Name") );
-       }
+       category_push ( g_x11_present ? CATEGORY_ALL "    (X11)" : CATEGORY_ALL "   (No X11)", iter, ovrh, NULL /* fspath */ );
       } // all?
 
       // main categories
-      if ( iter -> main_category && pnd_conf_get_as_int_d ( g_conf, "tabs.top_maincat", 1 ) ) {
-       if ( ! category_meta_push ( iter -> main_category, iter, ovrh ) ) {
-         pnd_log ( pndn_warning, "  Couldn't categorize to %s: '%s'\n", iter -> main_category, IFNULL(iter -> title_en, "No Name") );
-       }
-      }
-
-      if ( iter -> main_category1 && pnd_conf_get_as_int_d ( g_conf, "tabs.top_maincat1", 0 ) ) {
-       if ( ! category_meta_push ( iter -> main_category1, iter, ovrh ) ) {
-         pnd_log ( pndn_warning, "  Couldn't categorize to %s: '%s'\n", iter -> main_category1, IFNULL(iter -> title_en, "No Name") );
-       }
-      }
-
-      if ( iter -> main_category2 && pnd_conf_get_as_int_d ( g_conf, "tabs.top_maincat2", 0 ) ) {
-       if ( ! category_meta_push ( iter -> main_category2, iter, ovrh ) ) {
-         pnd_log ( pndn_warning, "  Couldn't categorize to %s: '%s'\n", iter -> main_category2, IFNULL(iter -> title_en, "No Name") );
-       }
-      }
-
+      category_meta_push ( iter -> main_category, iter, ovrh, pnd_conf_get_as_int_d ( g_conf, "tabs.top_maincat", 1 ) );
+      category_meta_push ( iter -> main_category1, iter, ovrh, pnd_conf_get_as_int_d ( g_conf, "tabs.top_maincat1", 0 ) );
+      category_meta_push ( iter -> main_category2, iter, ovrh, pnd_conf_get_as_int_d ( g_conf, "tabs.top_maincat2", 0 ) );
       // alt categories
-      if ( iter -> alt_category && pnd_conf_get_as_int_d ( g_conf, "tabs.top_altcat", 0 ) ) {
-       if ( ! category_meta_push ( iter -> alt_category, iter, ovrh ) ) {
-         pnd_log ( pndn_warning, "  Couldn't categorize to %s: '%s'\n", iter -> alt_category, IFNULL(iter -> title_en, "No Name") );
-       }
-      }
-
-      if ( iter -> alt_category1 && pnd_conf_get_as_int_d ( g_conf, "tabs.top_altcat1", 0 ) ) {
-       if ( ! category_meta_push ( iter -> alt_category1, iter, ovrh ) ) {
-         pnd_log ( pndn_warning, "  Couldn't categorize to %s: '%s'\n", iter -> alt_category1, IFNULL(iter -> title_en, "No Name") );
-       }
-      }
-
-      if ( iter -> alt_category2 && pnd_conf_get_as_int_d ( g_conf, "tabs.top_altcat2", 0 ) ) {
-       if ( ! category_meta_push ( iter -> alt_category2, iter, ovrh ) ) {
-         pnd_log ( pndn_warning, "  Couldn't categorize to %s: '%s'\n", iter -> alt_category2, IFNULL(iter -> title_en, "No Name") );
-       }
-      }
+      category_meta_push ( iter -> alt_category, iter, ovrh, pnd_conf_get_as_int_d ( g_conf, "tabs.top_altcat", 0 ) );
+      category_meta_push ( iter -> alt_category1, iter, ovrh, pnd_conf_get_as_int_d ( g_conf, "tabs.top_altcat1", 0 ) );
+      category_meta_push ( iter -> alt_category2, iter, ovrh, pnd_conf_get_as_int_d ( g_conf, "tabs.top_altcat2", 0 ) );
 
     } // register with categories or filter out
 
 
 unsigned char ui_category = 0;          // current category
 unsigned char ui_catshift = 0;          // how many cats are offscreen to the left
 
-extern mm_category_t g_categories [ MAX_CATS ];
+extern mm_category_t *g_categories;
 extern unsigned char g_categorycount;
+extern mm_category_t _categories_invis [ MAX_CATS ];
+extern unsigned char _categories_inviscount;
 
 static SDL_Surface *ui_scale_image ( SDL_Surface *s, unsigned int maxwidth, int maxheight ); // height -1 means ignore
 static int ui_selected_index ( void );
 
       } else if ( event.key.keysym.sym == SDLK_LCTRL /*LALT*/ ) { // select button
        char *opts [ 20 ] = {
-         "Return to Minimenu",
+         "Reveal hidden category",
          "Shutdown Pandora",
-         "Rescan for Applications",
+         "Rescan for applications",
          "Cache previews to SD now",
          "Run xfce4 from Minimenu",
          "Run a terminal/console",
        char buffer [ 100 ];
        if ( sel == 0 ) {
          // do nothing
+         ui_revealscreen();
        } else if ( sel == 1 ) {
          // shutdown
          sprintf ( buffer, "sudo poweroff" );
 
   return;
 }
+
+void ui_revealscreen ( void ) {
+  char *labels [ 500 ];
+  unsigned int labelmax = 0;
+  unsigned int i;
+
+  for ( i = 0; i < _categories_inviscount; i++ ) {
+    labels [ labelmax++ ] = _categories_invis [ i ].catname;
+  }
+
+  int sel = ui_modal_single_menu ( labels, labelmax, "Temporary Category Reveal",
+                                  "Enter to select; other to return." );
+
+  if ( sel >= 0 ) {
+
+    if ( category_query ( _categories_invis [ sel ].catname ) ) {
+      // already present
+      return;
+    }
+
+    memmove ( &(g_categories [ g_categorycount ]), &(_categories_invis [ sel ]), sizeof(mm_category_t) );
+    g_categorycount++;
+
+    ui_category = g_categorycount - 1;
+
+    unsigned int screen_width = pnd_conf_get_as_int_d ( g_conf, "display.screen_width", 800 );
+    unsigned int tab_width = pnd_conf_get_as_int ( g_conf, "tabs.tab_width" );
+    if ( ui_category > ui_catshift + ( screen_width / tab_width ) - 1 ) {
+      //ui_catshift++;
+      ui_catshift = ui_category - ( screen_width / tab_width ) + 1;
+    }
+
+    render_mask |= CHANGED_CATEGORY;
+  }
+
+  return;
+}
 
 void ui_post_scan ( void );
 unsigned char ui_show_info ( char *pndrun, pnd_disco_t *p );
 void ui_aboutscreen ( char *textpath );
+void ui_revealscreen ( void );
 
 /* internal functions follow
  */