--- themeswitcher.module 2006-09-04 10:40:16.000000000 -0400
+++ themeswitcher.module	2006-09-04 14:38:09.000000000 -0400
@@ -17,6 +17,21 @@ function themeswitcher_help($section = '
   return t($output);
 }
 
+/**
+ * hook_menu
+ **/
+
+function themeswitcher_menu($may_cache) {
+  $items = array();
+  if ($may_cache) {
+    $items[] = array('path' => 'themes',
+      'title' => t('theme previewer'),
+      'callback' => 'themeswitcher_page',
+      'access' => user_access('access content'));
+  }
+  return $items;
+}
+
 function themeswitcher_init() {
   global $custom_theme;
 
@@ -86,20 +101,25 @@ function themeswitcher_cron() {
 }
 
 function themeswitcher_block($op = 'list', $delta = 0) {
-  if ($op == 'list') {
-    $blocks[0]['info'] = t('Random theme');
-    $blocks[1]['info'] = t('Theme browser');
-    return $blocks;
-  }
-  elseif ($delta == 0) {
-    $block['subject'] = t('Random theme');
-    $block['content'] = themeswitcher_display_random_block();
-    return $block;
-  }
-  elseif ($delta == 1) {
-    $block['subject'] = t('Browse themes');
-    $block['content'] = themeswitcher_display_nextprev_block();
-    return $block;
+  switch ($op) {
+    case 'list': 
+      $blocks[0]['info'] = t('Random theme');
+      $blocks[1]['info'] = t('Theme browser');
+      return $blocks;
+    break;
+    case 'view':
+      if ($delta == 0) {
+        $block['subject'] = t('Random theme');
+        $block['content'] = themeswitcher_display_random_block();
+      }
+      elseif ($delta == 1) {
+        $block['subject'] = t('Browse themes');
+        $block['content'] = themeswitcher_display_nextprev_block();
+      }
+      return $block;
+    break;
+    case 'default':
+    break;
   }
 }
 
@@ -116,43 +136,178 @@ function themeswitcher_display_random_bl
 }
 
 function themeswitcher_display_nextprev_block() {
-  global $custom_theme;
+  global $custom_theme, $user;
   $themes = list_themes();
-  ksort($themes);
+  if (count($themes) > 1) {
+    ksort($themes);
+    $i = 0;
+    foreach ($themes as $key => $theme) {
+      $themes[$key]->screenshot = dirname($theme->filename) . '/screenshot.png';
+      // I need both a numerical and an associative array
+      $sort[$i] = $themes[$key];
+      $themes[$key]->order = $i;
+      $i++;
+    }  
+    $count = count($themes) - 1; // offest for starting at zero
 
-  if (!$custom_theme) {
-    $next = current($themes);
-    if (file_exists($next->screenshot)) {
-      $output .= l("<img src=\"$next->screenshot\" alt=\"preview of $next->name\"  width=\"75px\"/>", $_GET['q'], NULL, 'theme='. $next->name, NULL, FALSE, TRUE);
-      $output .= '<br/>';
-    }
-    $output .= l($next->name . ' ›', $_GET['q'], NULL, 'theme='. $next->name);
-    return $output;
-  }
-
-  while (list($key, $theme) = each($themes)) {
-    if ($custom_theme == $theme->name) {
-      prev($themes);
-      $previous = prev($themes);
-      if ($previous) {
-        if (file_exists($previous->screenshot)) {
-          $output = l("<img src=\"$previous->screenshot\" alt=\"preview of $previous->name\"  width=\"75px\"/>", $_GET['q'], NULL, 'theme='. $previous->name, NULL, FALSE, TRUE);
-          $output .= '<br/>';
-        }
-        $output .= l('‹ '. $previous->name, $_GET['q'], NULL, 'theme='. $previous->name);
+    // assign the current theme as value of $custom_theme
+    $current = themeswitcher_get_current($themes);
+    
+    // derive the next and previous from the order of $current
+    $pos = $current->order;
+    $next = $pos + 1;
+    $prev = $pos - 1;
+  
+    if ($pos == $count) {
+      $next = 0;
+      $prev = $pos - 1;
+    }
+    elseif ($pos == 0) {
+      $next = $pos + 1;
+      $prev = $count;
+    }
+    
+    $next_theme = $sort[$next];
+    $prev_theme = $sort[$prev];
+  
+    // add the themes to the output  
+    if (file_exists($prev_theme->screenshot)) {
+      $output = '<p>' . t('Previous theme') . '<br />';
+      $output .= l("<img src=\"$prev_theme->screenshot\" alt=\"preview of $prev_theme->name\" />", $_GET['q'], NULL, 'theme='. $prev_theme->name, NULL, FALSE, TRUE);
+    }
+    $output .= '<br />' . l('‹ '. $prev_theme->name, $_GET['q'], NULL, 'theme='. $prev_theme->name) . '</p>';    
+    $output .= '<p>' . t('Next theme') . '<br />';
+    if (file_exists($next_theme->screenshot)) {
+      $output .= l("<img src=\"$next_theme->screenshot\" alt=\"preview of $next_theme->name\"  />", $_GET['q'], NULL, 'theme='. $next_theme->name, NULL, FALSE, TRUE);
+    }
+    $output .= '<br />' . l($next_theme->name . ' ›', $_GET['q'], NULL, 'theme='. $next_theme->name) . '</p>';        
+  }
+  else {
+    $output = t('You must enable more than one theme.');
+  }
+  return $output;
+}
+
+
+/**
+ * Creates a browsable page showing all themes
+ **/
+
+function themeswitcher_page() {
+  $output = t('<p>Select a theme below to see how it looks for this site.</p>');
+  $themes = list_themes();
+  if (count($themes) > 1) {  
+    ksort($themes);
+    $current = themeswitcher_get_current($themes);    
+    $i = 0;
+    foreach ($themes as $key => $theme) {
+      $theme->picture = dirname($theme->filename) . '/screenshot.png';
+      if (file_exists(dirname($theme->filename) . '/screenshot.png')) { 
+        $themes[$key]->screenshot = dirname($theme->filename) . '/screenshot.png';
       }
-      next($themes);
-      $next = next($themes);
-      if ($next) {
-        $output .= ' | ';
-        if (file_exists($next->screenshot)) {
-          $output .= l("<img src=\"$next->screenshot\" alt=\"preview of $next->name\"  width=\"75px\"/>", $_GET['q'], NULL, 'theme='. $next->name, NULL, FALSE, TRUE);
-          $output .= '<br/>';
+      // easier to handle as a numerical array
+      $sort[$i] = $themes[$key];
+      $i++;
+    }  
+    
+    // this might all be rethemed, but it works this way.
+    $page = floor($_GET['page']);
+    $max = 24;
+    $cells = '';
+    $count = count($themes) - 1; // offset for the zero
+    $current_theme = $current->name;
+    
+    $start = ($page - 1) * $max;
+    $end = $page * $max - 1;
+    $pages = floor($count / $max) + 1;
+    
+    for ($i = $start; $i <= $end; $i++) {
+      $key = $i;
+      $theme = $sort[$i];
+      $row_open = 0;
+      if (!empty($theme)) {
+        if ($key == $start) {
+          $cells .= '<table width="100%" align="center" cellpadding="6" cellspacing="0">';
+        }
+        if (fmod($key, 3) == 0 || $key == 0) {
+          $cells .= '<tr>';
+          $row_open = 1;
         }
-        $output .= l($next->name . ' ›', $_GET['q'], NULL, 'theme='. $next->name);
+        $cells .= '<td align="center" valign="top" width="33%">' . theme('themeswitcher', $theme, $current_theme) . '</td>';
+        if (fmod($key+1, 3) == 0) {
+          $cells .= '</tr>';
+          $row_open = 0;
+        }
+        if ($key == $end || $key == $count) {
+          if ($row_open == 1) {
+            $cells .= '</tr>';
+          }
+          $cells .= '</table>';
+        }    
+      }  
+    }
+    $output .= $cells;  
+    
+    // pagination links
+    if ($pages > 1) {
+      $output .= l(t('first'), $_GET['q'], NULL, 'page=1'. '&theme='. $current_theme). ' | ';
+      for ($i = 1; $i <= $pages; $i++) {
+         $output .= l($i, $_GET['q'], NULL, 'page='. $i . '&theme='. $current_theme);
+         $output .= ' | ';
       }
-      return $output;
+      $output .= l(t('last'), $_GET['q'], NULL, 'page=' . $pages. '&theme='. $current_theme);
+    }
+    
+  }
+  else {
+    $output = t('You must enable more than one theme.');
+  }  
+
+  print theme('page', $output);
+}
+
+/**
+ * Theme function for the themes overview
+ **/
+ 
+function theme_themeswitcher($theme, $current_theme) {
+  if ($theme->name == $current_theme) {
+    $cells = '<div style="background-color: #eeeeee; border: 1px solid #cccccc; padding: 6px;"><b>';  
+  }
+  else {
+    $cells = '<div style="background-color: #ffffff; border: 1px solid #cccccc; padding: 6px;"><b>';  
+  }
+  $cells .= '<p>' . l($theme->name, $_GET['q'], NULL, 'page='.$_GET['page'] . 'theme='. $theme->name);
+  $cells .= '</p><p>';
+  $cells .= l("<img src=\"$theme->screenshot\" alt=\"preview of $theme->name\"  />", $_GET['q'], NULL, 'page='.$_GET['page'] .'&theme='. $theme->name, NULL, FALSE, TRUE);
+  $cells .= '</p>';
+  if ($theme->name == $current_theme) {
+    $cells .= '</b>';  
+  }
+  $cells .= '</div>';
+  return $cells;
+}
+
+
+/**
+ * Retrieve the active theme
+ **/
+ 
+function themeswitcher_get_current($themes) {
+  global $custom_theme;
+  if (!empty($custom_theme)) {
+    $current = $themes[$custom_theme];
+  }
+  else {
+    // if no theme, use the user default
+    if (empty($user->theme)) {
+      $conf = $GLOBALS['conf']['theme_default'];
     }
+    else {
+      $conf = $user->theme;
+    }  
+    $current = $themes[$conf];
   }
+  return $current;
 }
-?>
+
