diff --git a/block/flickr_block.module b/block/flickr_block.module
index 3e0ccf0..6ef4a93 100644
--- a/block/flickr_block.module
+++ b/block/flickr_block.module
@@ -1,524 +1,688 @@
-<?php
-/**
- * @file
- * The Flickr block module
- */
-
-/**
- * Implements hook_block_info().
- */
-function flickr_block_info() {
-  // User base blocks.
-  $blocks[0]['info'] = t("Flickr user page recent photos");
-  $blocks[1]['info'] = t("Flickr user page photosets");
-  $blocks[2]['info'] = t("Flickr user page random photos");
-
-  // Site wide blocks.
-  $blocks[3]['info'] = t('Flickr recent photos');
-  $blocks[4]['info'] = t('Flickr recent photosets');
-  $blocks[5]['info'] = t('Flickr random photos');
-  $blocks[6]['info'] = t('Flickr group photos');
-
-  // Photoset blocks.
-  $blocks[7]['info'] = t('Flickr random photo from photoset');
-  $blocks[8]['info'] = t('Flickr recent photo from photoset');
-
-  // Returns a list of favorite public photos for the given user.
-  $blocks[9]['info'] = t("Flickr user favorite public photos");
-
-  return $blocks;
-}
-
-/**
- * Implements hook_block_configure().
- */
-function flickr_block_configure($delta = '') {
-  $count_options = array(
-    1 => '1',
-    2 => '2',
-    3 => '3',
-    4 => '4',
-    5 => '5',
-    6 => '6',
-    7 => '7',
-    8 => '8',
-    9 => '9',
-    10 => '10',
-    15 => '15',
-    20 => '20',
-    25 => '25',
-    30 => '30',
-  );
-
-  // Remove the large and original sizes.
-  $size_options = array();
-  foreach (flickr_photo_sizes() as $size => $info) {
-    $size_options[$size] = $info['label'] . ' - ' . $info['description'];
-  }
-  unset($size_options['b']);
-  unset($size_options['o']);
-
-  $settings = variable_get('flickr_block_' . $delta, array(
-    'user_id' => '',
-    'show_n' => 4,
-    'size' => 's',
-    'photoset_id' => '',
-    'media' => 'all',
-  ));
-
-  $form = array();
-  $user_id = array_key_exists('user_id', $settings) ? $settings['user_id'] : '';
-  $form["flickr_block_{$delta}_user_id"] = array(
-    '#type' => 'textfield',
-    '#title' => t('Flickr User Id'),
-    '#default_value' => $user_id,
-    '#description' => t("The user id of a Flickr user. If this is left blank, the sites's default user will be used. Current default id is") . " " . variable_get('flickr_default_userid', ''),
-  );
-  $form["flickr_block_{$delta}_show_n"] = array(
-    '#type' => 'select',
-    '#options' => $count_options,
-    '#title' => t('Show <em>n</em> photos'),
-    '#default_value' => $settings['show_n'],
-    '#description' => t("The block will display this many photos."),
-  );
-  $form["flickr_block_{$delta}_size"] = array(
-    '#type' => 'select',
-    '#options' => $size_options,
-    '#title' => t('Size of photos'),
-    '#default_value' => $settings['size'],
-    '#description' => t("Select the size of photos you'd like to display in the block."),
-  );
-
-  $form["flickr_block_{$delta}_media"] = array(
-    '#type' => 'select',
-    '#options' => array(
-      'all' => t('all'),
-      'photos' => t('photos'),
-      'videos' => t('videos'),
-    ),
-    '#title' => t('Media type'),
-    '#default_value' => $settings['media'],
-    '#description' => t("Filter results by media type."),
-  );
-
-  switch ($delta) {
-    // User page, recent.
-    case 0:
-      unset($form["flickr_block_{$delta}_user_id"]);
-      break;
-
-    // User page, photosets.
-    case 1:
-      unset($form["flickr_block_{$delta}_user_id"]);
-      // Photoset, not photos.
-      $form["flickr_block_{$delta}_show_n"]['#title'] = t('Show the last <em>n</em> photosets');
-      $form["flickr_block_{$delta}_show_n"]['#description'] = t("The block will show this many of the user's photosets.");
-      unset($form["flickr_block_{$delta}_media"]);
-      break;
-
-    // User page, random.
-    case 2:
-      unset($form["flickr_block_{$delta}_user_id"]);
-      break;
-
-    // Sitewide, recent.
-    case 3:
-      break;
-
-    // Sitewite photoset, not photos.
-    case 4:
-      $form["flickr_block_{$delta}_show_n"]['#title'] = t('Show the last <em>n</em> photosets');
-      $form["flickr_block_{$delta}_show_n"]['#description'] = t("The block will show this many of the user's photosets.");
-      unset($form["flickr_block_{$delta}_media"]);
-      break;
-
-    // Sitewide, random.
-    case 5:
-      break;
-
-    // Sitewide, group.
-    case 6:
-      $form["flickr_block_{$delta}_user_id"]['#title'] = t('Show photos from this Group ID');
-      $form["flickr_block_{$delta}_user_id"]['#description'] = t('Will select photos from this group pool');
-      $form["flickr_block_{$delta}_user_id"]['#required'] = TRUE;
-      break;
-
-    // Sitewide, random.
-    case 7:
-      // Sitewide, recent.
-    case 8:
-      unset($form["flickr_block_{$delta}_user_id"]);
-      $form["flickr_block_{$delta}_photoset"] = array(
-        '#type' => 'textfield',
-        '#title' => t('Flickr Photoset Id'),
-        '#default_value' => $settings['photoset_id'],
-        '#description' => t("The id of a Flickr photoset."),
-        '#required' => TRUE,
-      );
-      break;
-
-    // List of favorite public photos for the given user.
-    case 9:
-      break;
-
-  }
-  return $form;
-}
-
-/**
- * Implements hook_block_save().
- */
-function flickr_block_save($delta = '', $edit = array()) {
-  switch ($delta) {
-    case 0:
-    case 1:
-    case 2:
-      variable_set('flickr_block_' . $delta, array(
-        'show_n' => (int) $edit["flickr_block_{$delta}_show_n"],
-        'size' => $edit["flickr_block_{$delta}_size"],
-        'media' => $edit["flickr_block_{$delta}_media"],
-      ));
-      break;
-
-    case 3:
-    case 4:
-    case 5:
-    case 6:
-    case 9:
-      variable_set('flickr_block_' . $delta, array(
-        'user_id' => $edit["flickr_block_{$delta}_user_id"],
-        'show_n' => (int) $edit["flickr_block_{$delta}_show_n"],
-        'size' => $edit["flickr_block_{$delta}_size"],
-        'media' => $edit["flickr_block_{$delta}_media"],
-      ));
-      break;
-
-    case 7:
-    case 8:
-      variable_set('flickr_block_' . $delta, array(
-        'show_n' => (int) $edit["flickr_block_{$delta}_show_n"],
-        'size' => $edit["flickr_block_{$delta}_size"],
-        'media' => $edit["flickr_block_{$delta}_media"],
-        'photoset_id' => $edit["flickr_block_{$delta}_photoset"],
-      ));
-      break;
-
-  }
-}
-
-/**
- * Implements hook_block_view().
- */
-function flickr_block_view($delta = '') {
-  drupal_add_css(drupal_get_path('module', 'flickr') . '/flickr.css');
-  $settings = variable_get('flickr_block_' . $delta, array(
-    'user_id' => '',
-    'show_n' => 4,
-    'size' => 's',
-    'media' => 'all',
-  ));
-
-  // Get the default user id as a fallback.
-  if (empty($settings['user_id'])) {
-    $settings['user_id'] = variable_get('flickr_default_userid');
-  }
-  $settings['user_id'] = flickr_user_find_by_identifier($settings['user_id']);
-  $block = array();
-
-  switch ($delta) {
-    case 0:
-    case 1:
-    case 2:
-      // Get per user nsid if necessary.
-      if (arg(0) == 'user' && ($uid = (int) arg(1))) {
-        if ($user = user_load($uid)) {
-          if (!empty($user->flickr['nsid'])) {
-            if ($delta == 0) {
-              $block['subject'] = t("%username's recent Flickr photos", array('%username' => $user->name));
-              $block['content'] = _flickr_block_recent($user->flickr['nsid'], $settings['show_n'], $settings['size'], $settings['media']);
-            }
-            elseif ($delta == 1) {
-              $block['subject'] = t("%username's recent Flickr photosets", array('%username' => $user->name));
-              $block['content'] = _flickr_block_photosets($user->flickr['nsid'], $settings['show_n'], $settings['size']);
-            }
-            elseif ($delta == 2) {
-              $block['subject'] = t("%username's random Flickr photos", array('%username' => $user->name));
-              $block['content'] = _flickr_block_random($user->flickr['nsid'], $settings['show_n'], $settings['size'], $settings['media']);
-            }
-            elseif ($delta == 9) {
-              $block['subject'] = t("%username's favorite public Flickr photos", array('%username' => $user->name));
-              $block['content'] = _flickr_block_favorite_public($user->flickr['nsid'], $settings['show_n'], $settings['size'], $settings['media']);
-            }
-          }
-        }
-      }
-      break;
-
-    case 3:
-      $block['subject'] = t('Flickr recent photos');
-      $block['content'] = _flickr_block_recent($settings['user_id'], $settings['show_n'], $settings['size'], $settings['media']);
-      break;
-
-    case 4:
-      $block['subject'] = t('Flickr recent photosets');
-      $block['content'] = _flickr_block_photosets($settings['user_id'], $settings['show_n'], $settings['size']);
-      break;
-
-    case 5:
-      $block['subject'] = t('Flickr random photos');
-      $block['content'] = _flickr_block_random($settings['user_id'], $settings['show_n'], $settings['size'], $settings['media']);
-      break;
-
-    case 6:
-      $block['subject'] = t('Flickr Group photos');
-      $block['content'] = _flickr_block_group_recent($settings['user_id'], $settings['show_n'], $settings['size'], $settings['media']);
-      break;
-
-    case 7:
-      $block['subject'] = t('Flickr random photoset photos');
-      $block['content'] = _flickr_block_photoset_random($settings['user_id'], $settings['show_n'], $settings['size'], $settings['media'], $settings['photoset_id']);
-      break;
-
-    case 8:
-      $block['subject'] = t('Flickr recent photoset photos');
-      $block['content'] = _flickr_block_photoset_recent($settings['user_id'], $settings['show_n'], $settings['size'], $settings['media'], $settings['photoset_id']);
-      break;
-
-    case 9:
-      $block['subject'] = t('Flickr favorite public photos');
-      $block['content'] = _flickr_block_favorite_public($settings['user_id'], $settings['show_n'], $settings['size'], $settings['media']);
-      break;
-
-  }
-  return $block;
-}
-
-/**
- * Recent block.
- */
-function _flickr_block_recent($nsid, $show_n, $size, $media) {
-  $output = '';
-  if ($photos = flickr_photos_search($nsid, 1, array(
-    'per_page' => $show_n,
-    'media' => $media,
-  ))) {
-    foreach ($photos['photo'] as $photo) {
-      $output .= theme('flickr_block_photo', array(
-        'photo' => $photo,
-        'size' => $size,
-      ));
-    }
-  }
-  return $output;
-}
-
-/**
- * Photoset block.
- */
-function _flickr_block_photosets($nsid, $show_n, $size) {
-  $photosets = flickr_photoset_get_list($nsid);
-  $output = '';
-  $to = min($show_n, count($photosets));
-  for ($i = 0; $i < $to; $i++) {
-    $output .= theme('flickr_block_photoset', array(
-      'photoset' => $photosets[$i],
-      'owner' => $nsid,
-      'size' => $size,
-    ));
-  }
-  return $output;
-}
-
-/**
- * Random from user block.
- */
-function _flickr_block_random($nsid, $show_n, $size, $media) {
-  $output = '';
-  $random_photos = array();
-  if ($photos = flickr_photos_search($nsid, 1, array(
-    'per_page' => 500,
-    'media' => $media,
-  ))) {
-    $page_count = $photos['pages'];
-    // Do not try to return more than the total number of photos.
-    $to = min($show_n, $photos['total']);
-    $output = '';
-    for ($i = 0; $i < $to; $i++) {
-      sleep(0.125);
-      // Request a random page.
-      $photos = flickr_photos_search($nsid, rand(1, $page_count), array(
-        'per_page' => 500,
-        'media' => $media,
-      ));
-      // Select a random photo.
-      $index = rand(0, count($photos['photo']) - 1);
-      $photo_id = $photos['photo'][$index]['id'];
-      if (in_array($photo_id, $random_photos)) {
-        // Photo already added.
-        $i--;
-      }
-      else {
-        $random_photos[] = $photo_id;
-        $output .= theme('flickr_block_photo', array(
-          'photo' => $photos['photo'][$index],
-          'size' => $size,
-        ));
-      }
-    }
-  }
-  return $output;
-}
-
-/**
- * Random from photoset block.
- */
-function _flickr_block_photoset_random($nsid, $show_n, $size, $media, $photoset_id) {
-  // Get information about the photoset, including the owner.
-  $info = flickr_photoset_get_info($photoset_id);
-  if (!$info) {
-    return;
-  }
-
-  // Get a list of "all" the photos in the photoset. This is cached.
-  $response = flickr_request('flickr.photosets.getPhotos',
-    array(
-      'photoset_id' => $photoset_id,
-      // Get as many images as possible.
-      'per_page' => 500,
-      'extras' => 'owner',
-      'media' => $media,
-    )
-  );
-  if (!$response) {
-    return;
-  }
-
-  // Randomly display $show_n of them.
-  $photos = $response['photoset']['photo'];
-  shuffle($photos);
-
-  // We shouldn't try to return more than the total number of photos.
-  $output = '';
-  $to = min($show_n, count($photos));
-  for ($i = 0; $i < $to; $i++) {
-    // Insert owner into $photo because theme_flickr_photo needs it.
-    $photos[$i]['owner'] = $info['owner'];
-    $output .= theme('flickr_block_photo', array(
-      'photo' => $photos[$i],
-      'size' => $size,
-    ));
-  }
-  return $output;
-}
-
-/**
- * Recent from photoset block.
- */
-function _flickr_block_photoset_recent($nsid, $show_n, $size, $media, $photoset_id) {
-  // Get information about the photoset, including the owner.
-  $info = flickr_photoset_get_info($photoset_id);
-  if (!$info) {
-    return;
-  }
-
-  $response = flickr_request('flickr.photosets.getPhotos',
-    array(
-      'photoset_id' => $photoset_id,
-      'per_page' => $show_n,
-      'extras' => 'owner',
-      'media' => $media,
-    )
-  );
-
-  if (!$response) {
-    return;
-  }
-
-  $output = '';
-  foreach ($response['photoset']['photo'] as $photo) {
-    // Insert owner into $photo because theme_flickr_photo needs it.
-    $photo['owner'] = $info['owner'];
-    $output .= theme('flickr_block_photo', array(
-      'photo' => $photo,
-      'size' => $size,
-    ));
-  }
-
-  return $output;
-}
-
-/**
- * Favorites block.
- */
-function _flickr_block_favorite_public($nsid, $show_n, $size, $media) {
-  $output = '';
-  if ($photos = flickr_favorites_get_public_list($nsid, 1, array(
-    'per_page' => $show_n,
-    'media' => $media,
-  ))) {
-    foreach ($photos['photo'] as $photo) {
-      $output .= theme('flickr_block_photo', array(
-        'photo' => $photo,
-        'size' => $size,
-      ));
-    }
-  }
-  return $output;
-}
-
-/**
- * This renders a block with photos from the selected groupid.
- */
-function _flickr_block_group_recent($groupid, $show_n, $size, $media) {
-  $output = '';
-  if ($photos = flickr_get_group_photos($groupid, 1, array(
-    'per_page' => $show_n,
-    'media' => $media,
-  ))) {
-    foreach ($photos['photo'] as $photo) {
-      $output .= theme('flickr_block_photo', array(
-        'photo' => $photo,
-        'size' => $size,
-      ));
-    }
-  }
-  return $output;
-}
-
-/**
- * Implements hook_theme().
- */
-function flickr_block_theme() {
-  return array(
-    'flickr_block_photo' => array(
-      'variables' => array('photo', 'size' => NULL),
-    ),
-    'flickr_block_photoset' => array(
-      'variables' => array('photoset', 'owner', 'size'),
-    ),
-  );
-}
-
-/**
- * Theme photo blocks.
- */
-function theme_flickr_block_photo($variables) {
-  $photo = $variables['photo'];
-  $size = $variables['size'];
-  return theme('flickr_photo', array('photo' => $photo, 'size' => $size));
-}
-
-/**
- * Theme photoset blocks.
- */
-function theme_flickr_block_photoset($variables) {
-  $photoset = $variables['photoset'];
-  $owner = $variables['owner'];
-  $size = $variables['size'];
-  return theme('flickr_photoset', array(
-    'photoset' => $photoset,
-    'owner' => $owner,
-    'size' => $size,
-  ));
-}
-
+<?php
+/**
+ * @file
+ * The Flickr block module
+ */
+
+/**
+ * Implements hook_block_info().
+ */
+function flickr_block_info() {
+  // User base blocks.
+  $blocks[0]['info'] = t("Flickr user page recent photos");
+  $blocks[1]['info'] = t("Flickr user page photosets");
+  $blocks[2]['info'] = t("Flickr user page random photos");
+
+  // Site wide blocks.
+  $blocks[3]['info'] = t('Flickr recent photos');
+  $blocks[4]['info'] = t('Flickr recent photosets');
+  $blocks[5]['info'] = t('Flickr random photos');
+  $blocks[6]['info'] = t('Flickr group photos');
+
+  // Photoset blocks.
+  $blocks[7]['info'] = t('Flickr random photo from photoset');
+  $blocks[8]['info'] = t('Flickr recent photo from photoset');
+
+  // Returns a list of favorite public photos for the given user.
+  $blocks[9]['info'] = t("Flickr user favorite public photos");
+
+  $blocks[10]['info'] = t("Flickr random photos from a group");
+  $blocks[11]['info'] = t("Flickr random user photos with a tag");
+  return $blocks;
+}
+
+/**
+ * Implements hook_block_configure().
+ */
+function flickr_block_configure($delta = '') {
+  $count_options = array(
+    1 => '1',
+    2 => '2',
+    3 => '3',
+    4 => '4',
+    5 => '5',
+    6 => '6',
+    7 => '7',
+    8 => '8',
+    9 => '9',
+    10 => '10',
+    15 => '15',
+    20 => '20',
+    25 => '25',
+    30 => '30',
+  );
+
+  // Remove the large and original sizes.
+  $size_options = array();
+  foreach (flickr_photo_sizes() as $size => $info) {
+    $size_options[$size] = $info['label'] . ' - ' . $info['description'];
+  }
+  unset($size_options['b']);
+  unset($size_options['o']);
+
+  // Define all of the form element variables and retrieve existing values
+  $settings = variable_get('flickr_block_' . $delta, array(
+    'user_id' => '',
+    'show_n' => 4,
+    'size' => 's',
+    'tag' => '',
+    'group_id' => '',
+    'photoset_id' => '',
+    'media' => 'all',
+  ));
+  if (!isset($settings['tag'])) $settings['tag'] = '';
+  if (!isset($settings['group_id'])) $settings['group_id'] = '';
+  if (!isset($settings['photoset_id'])) $settings['photoset_id'] = '';
+
+  // Define all elements of the block parameters form
+  $form = array();
+  $default_userid = variable_get('flickr_default_userid', '');
+  $user_id = array_key_exists('user_id', $settings) ? $settings['user_id'] : '';
+  // Require a user id if the site-wide default user has not been set
+  if (empty($default_userid)) {
+    $form["flickr_block_{$delta}_user_id"] = array(
+      '#type' => 'textfield',
+      '#title' => t('Flickr User Id'),
+      '#default_value' => $user_id,
+      '#required' => TRUE,
+      '#description' => t("The user id of a Flickr user. Note that the sites's default Flickr user id has not been set."),
+    );
+  } else {
+    $form["flickr_block_{$delta}_user_id"] = array(
+      '#type' => 'textfield',
+      '#title' => t('Flickr User Id'),
+      '#default_value' => $user_id,
+      '#description' => t("The user id of a Flickr user. If this is left blank, the sites's default user will be used. Current default id is") . " " . $default_userid,
+    );
+  }
+  
+  $form["flickr_block_{$delta}_show_n"] = array(
+    '#type' => 'select',
+    '#options' => $count_options,
+    '#title' => t('Show <em>n</em> photos'),
+    '#default_value' => $settings['show_n'],
+    '#description' => t("The block will display this many photos."),
+  );
+  $form["flickr_block_{$delta}_size"] = array(
+    '#type' => 'select',
+    '#options' => $size_options,
+    '#title' => t('Size of photos'),
+    '#default_value' => $settings['size'],
+    '#description' => t("Select the size of photos you'd like to display in the block."),
+  );
+  $form["flickr_block_{$delta}_group_id"] = array(
+    '#type' => 'textfield',
+    '#title' => t('Flickr Group id'),
+    '#default_value' => $settings['group_id'],
+    '#description' => t("The numerical group id."),
+  );
+  $form["flickr_block_{$delta}_tag"] = array(
+    '#type' => 'textfield',
+    '#title' => t('Flickr tag'),
+    '#default_value' => $settings['tag'],
+    '#description' => t("The tag you want to search for."),
+  );
+  $form["flickr_block_{$delta}_media"] = array(
+    '#type' => 'select',
+    '#options' => array(
+      'all' => t('all'),
+      'photos' => t('photos'),
+      'videos' => t('videos'),
+    ),
+    '#title' => t('Media type'),
+    '#default_value' => $settings['media'],
+    '#description' => t("Filter results by media type."),
+  );
+
+  // Build the block form - use unset to hide unwanted form elements
+  switch ($delta) {
+    // User page, recent.
+    case 0:
+      unset($form["flickr_block_{$delta}_user_id"]);
+      unset($form["flickr_block_{$delta}_group_id"]);
+      unset($form["flickr_block_{$delta}_tag"]);
+      break;
+
+    // User page, photosets.
+    case 1:
+      unset($form["flickr_block_{$delta}_user_id"]);
+      unset($form["flickr_block_{$delta}_group_id"]);
+      unset($form["flickr_block_{$delta}_tag"]);
+      // Photoset, not photos.
+      $form["flickr_block_{$delta}_show_n"]['#title'] = t('Show the last <em>n</em> photosets');
+      $form["flickr_block_{$delta}_show_n"]['#description'] = t("The block will show this many of the user's photosets.");
+      unset($form["flickr_block_{$delta}_media"]);
+      break;
+
+    // User page, random.
+    case 2:
+      unset($form["flickr_block_{$delta}_user_id"]);
+      unset($form["flickr_block_{$delta}_group_id"]);
+      unset($form["flickr_block_{$delta}_tag"]);
+      break;
+
+    // Sitewide, recent.
+    case 3:
+      unset($form["flickr_block_{$delta}_group_id"]);
+      unset($form["flickr_block_{$delta}_tag"]);
+      break;
+
+    // Sitewite photoset, not photos.
+    case 4:
+      unset($form["flickr_block_{$delta}_group_id"]);
+      unset($form["flickr_block_{$delta}_tag"]);
+      $form["flickr_block_{$delta}_show_n"]['#title'] = t('Show the last <em>n</em> photosets');
+      $form["flickr_block_{$delta}_show_n"]['#description'] = t("The block will show this many of the user's photosets.");
+      unset($form["flickr_block_{$delta}_media"]);
+      break;
+
+    // Sitewide, random.
+    case 5:
+      unset($form["flickr_block_{$delta}_group_id"]);
+      unset($form["flickr_block_{$delta}_tag"]);
+      break;
+
+    // Sitewide, group.
+    case 6:
+      unset($form["flickr_block_{$delta}_group_id"]);
+      unset($form["flickr_block_{$delta}_tag"]);
+      $form["flickr_block_{$delta}_user_id"]['#title'] = t('Show photos from this Group ID');
+      $form["flickr_block_{$delta}_user_id"]['#description'] = t('Will select photos from this group pool');
+      $form["flickr_block_{$delta}_user_id"]['#required'] = TRUE;
+      break;
+
+    // Sitewide, random.
+    case 7:
+    // Sitewide, recent.
+    case 8:
+      unset($form["flickr_block_{$delta}_user_id"]);
+      unset($form["flickr_block_{$delta}_group_id"]);
+      unset($form["flickr_block_{$delta}_tag"]);
+      $form["flickr_block_{$delta}_photoset"] = array(
+        '#type' => 'textfield',
+        '#title' => t('Flickr Photoset Id'),
+        '#default_value' => $settings['photoset_id'],
+        '#description' => t("The id of a Flickr photoset."),
+        '#required' => TRUE,
+      );
+      break;
+
+    // List of favorite public photos for the given user.
+    case 9:
+      unset($form["flickr_block_{$delta}_group_id"]);
+      unset($form["flickr_block_{$delta}_tag"]);
+      break;
+
+    // Group, random.
+    case 10:
+      unset($form["flickr_block_{$delta}_user_id"]);
+      unset($form["flickr_block_{$delta}_tag"]);
+      $form["flickr_block_{$delta}_group_id"]['#title'] = t('Show photos from this Group ID');
+      $form["flickr_block_{$delta}_group_id"]['#description'] = t('Will select random photos from this group pool');
+      $form["flickr_block_{$delta}_group_id"]['#required'] = TRUE;
+      break;
+    // Tag, random.
+    case 11:
+      unset($form["flickr_block_{$delta}_group_id"]);
+      $form["flickr_block_{$delta}_tag"]['#title'] = t('Show photos having this tag');
+      $form["flickr_block_{$delta}_tag"]['#description'] = t("Will select random photos from the user's photosets having this tag");
+      $form["flickr_block_{$delta}_tag"]['#required'] = TRUE;
+      break;
+  }
+  return $form;
+}
+
+/**
+ * Implements hook_block_save().
+ */
+function flickr_block_save($delta = '', $edit = array()) {
+  switch ($delta) {
+    case 0:
+    case 1:
+    case 2:
+      variable_set('flickr_block_' . $delta, array(
+        'show_n' => (int) $edit["flickr_block_{$delta}_show_n"],
+        'size' => $edit["flickr_block_{$delta}_size"],
+        'media' => $edit["flickr_block_{$delta}_media"],
+      ));
+      break;
+
+    case 3:
+    case 4:
+    case 5:
+    case 6:
+    case 9:
+      variable_set('flickr_block_' . $delta, array(
+        'user_id' => $edit["flickr_block_{$delta}_user_id"],
+        'show_n' => (int) $edit["flickr_block_{$delta}_show_n"],
+        'size' => $edit["flickr_block_{$delta}_size"],
+        'media' => $edit["flickr_block_{$delta}_media"],
+      ));
+      break;
+
+    case 7:
+    case 8:
+      variable_set('flickr_block_' . $delta, array(
+        'show_n' => (int) $edit["flickr_block_{$delta}_show_n"],
+        'size' => $edit["flickr_block_{$delta}_size"],
+        'media' => $edit["flickr_block_{$delta}_media"],
+        'photoset_id' => $edit["flickr_block_{$delta}_photoset"],
+      ));
+      break;
+      
+    case 10:
+      variable_set('flickr_block_' . $delta, array(
+        'group_id' => $edit["flickr_block_{$delta}_group_id"],
+        'show_n' => (int) $edit["flickr_block_{$delta}_show_n"],
+        'size' => $edit["flickr_block_{$delta}_size"],
+        'media' => $edit["flickr_block_{$delta}_media"],
+      ));
+      break;
+    case 11:
+      variable_set('flickr_block_' . $delta, array(
+        'user_id' => $edit["flickr_block_{$delta}_user_id"],
+        'tag' => $edit["flickr_block_{$delta}_tag"],
+        'show_n' => (int) $edit["flickr_block_{$delta}_show_n"],
+        'size' => $edit["flickr_block_{$delta}_size"],
+        'media' => $edit["flickr_block_{$delta}_media"],
+      ));
+      break;
+  }
+}
+
+/**
+ * Implements hook_block_view().
+ */
+function flickr_block_view($delta = '') {
+  drupal_add_css(drupal_get_path('module', 'flickr') . '/flickr.css');
+  $settings = variable_get('flickr_block_' . $delta, array(
+    'user_id' => '',
+    'show_n' => 4,
+    'size' => 's',
+    'tag' => '',
+    'group_id' => '',
+    'photoset_id' => '',
+    'media' => 'all',
+  ));
+  if (!isset($settings['tag'])) $settings['tag'] = '';
+  if (!isset($settings['group_id'])) $settings['group_id'] = '';
+  if (!isset($settings['photoset_id'])) $settings['photoset_id'] = '';
+
+  // Get the default user id as a fallback.
+  if (empty($settings['user_id'])) {
+    $settings['user_id'] = variable_get('flickr_default_userid');
+  }
+  $settings['user_id'] = flickr_user_find_by_identifier($settings['user_id']);
+  $block = array();
+
+  switch ($delta) {
+    case 0:
+    case 1:
+    case 2:
+      // Get per user nsid if necessary.
+      if (arg(0) == 'user' && ($uid = (int) arg(1))) {
+        if ($user = user_load($uid)) {
+          if (!empty($user->flickr['nsid'])) {
+            if ($delta == 0) {
+              $block['subject'] = t("%username's recent Flickr photos", array('%username' => $user->name));
+              $block['content'] = _flickr_block_recent($user->flickr['nsid'], $settings['show_n'], $settings['size'], $settings['media']);
+            }
+            elseif ($delta == 1) {
+              $block['subject'] = t("%username's recent Flickr photosets", array('%username' => $user->name));
+              $block['content'] = _flickr_block_photosets($user->flickr['nsid'], $settings['show_n'], $settings['size']);
+            }
+            elseif ($delta == 2) {
+              $block['subject'] = t("%username's random Flickr photos", array('%username' => $user->name));
+              $block['content'] = _flickr_block_random($user->flickr['nsid'], $settings['show_n'], $settings['size'], $settings['media']);
+            }
+            elseif ($delta == 9) {
+              $block['subject'] = t("%username's favorite public Flickr photos", array('%username' => $user->name));
+              $block['content'] = _flickr_block_favorite_public($user->flickr['nsid'], $settings['show_n'], $settings['size'], $settings['media']);
+            }
+          }
+        }
+      }
+      break;
+
+    case 3:
+      $block['subject'] = t('Flickr recent photos');
+      $block['content'] = _flickr_block_recent($settings['user_id'], $settings['show_n'], $settings['size'], $settings['media']);
+      break;
+
+    case 4:
+      $block['subject'] = t('Flickr recent photosets');
+      $block['content'] = _flickr_block_photosets($settings['user_id'], $settings['show_n'], $settings['size']);
+      break;
+
+    case 5:
+      $block['subject'] = t('Flickr random photos');
+      $block['content'] = _flickr_block_random($settings['user_id'], $settings['show_n'], $settings['size'], $settings['media']);
+      break;
+
+    case 6:
+      $block['subject'] = t('Flickr Group photos');
+      $block['content'] = _flickr_block_group_recent($settings['user_id'], $settings['show_n'], $settings['size'], $settings['media']);
+      break;
+
+    case 7:
+      $block['subject'] = t('Flickr random photoset photos');
+      $block['content'] = _flickr_block_photoset_random($settings['user_id'], $settings['show_n'], $settings['size'], $settings['media'], $settings['photoset_id']);
+      break;
+
+    case 8:
+      $block['subject'] = t('Flickr recent photoset photos');
+      $block['content'] = _flickr_block_photoset_recent($settings['user_id'], $settings['show_n'], $settings['size'], $settings['media'], $settings['photoset_id']);
+      break;
+
+    case 9:
+      $block['subject'] = t('Flickr favorite public photos');
+      $block['content'] = _flickr_block_favorite_public($settings['user_id'], $settings['show_n'], $settings['size'], $settings['media']);
+      break;
+
+    case 10:
+      $block['subject'] = t('Flickr Group random photos');
+      $block['content'] = _flickr_block_group_random($settings['group_id'], $settings['show_n'], $settings['size'], $settings['media']);
+      break;
+    case 11:
+      $block['subject'] = t('Flickr tag random photos');
+      $block['content'] = _flickr_block_tag_random($settings['user_id'], $settings['show_n'], $settings['size'], $settings['media'], $settings['tag']);
+      break;
+  }
+  return $block;
+}
+
+/**
+ * Recent block.
+ */
+function _flickr_block_recent($nsid, $show_n, $size, $media) {
+  $output = '';
+  if ($photos = flickr_photos_search($nsid, 1, array(
+    'per_page' => $show_n,
+    'media' => $media,
+  ))) {
+    foreach ($photos['photo'] as $photo) {
+      $output .= theme('flickr_block_photo', array(
+        'photo' => $photo,
+        'size' => $size,
+      ));
+    }
+  }
+  return $output;
+}
+
+/**
+ * Photoset block.
+ */
+function _flickr_block_photosets($nsid, $show_n, $size) {
+  $photosets = flickr_photoset_get_list($nsid);
+  $output = '';
+  $to = min($show_n, count($photosets));
+  for ($i = 0; $i < $to; $i++) {
+    $output .= theme('flickr_block_photoset', array(
+      'photoset' => $photosets[$i],
+      'owner' => $nsid,
+      'size' => $size,
+    ));
+  }
+  return $output;
+}
+
+/**
+ * Random from user block.
+ */
+function _flickr_block_random($nsid, $show_n, $size, $media) {
+  $output = '';
+  $random_photos = array();
+  if ($photos = flickr_photos_search($nsid, 1, array(
+    'per_page' => 500,
+    'media' => $media,
+  ))) {
+    $page_count = $photos['pages'];
+    // Do not try to return more than the total number of photos.
+    $to = min($show_n, $photos['total']);
+    $output = '';
+    for ($i = 0; $i < $to; $i++) {
+      sleep(0.125);
+      // Request a random page.
+      $photos = flickr_photos_search($nsid, rand(1, $page_count), array(
+        'per_page' => 500,
+        'media' => $media,
+      ));
+      // Select a random photo.
+      $index = rand(0, count($photos['photo']) - 1);
+      $photo_id = $photos['photo'][$index]['id'];
+      if (in_array($photo_id, $random_photos)) {
+        // Photo already added.
+        $i--;
+      }
+      else {
+        $random_photos[] = $photo_id;
+        $output .= theme('flickr_block_photo', array(
+          'photo' => $photos['photo'][$index],
+          'size' => $size,
+        ));
+      }
+    }
+  }
+  return $output;
+}
+
+/**
+ * Random from photoset block.
+ */
+function _flickr_block_photoset_random($nsid, $show_n, $size, $media, $photoset_id) {
+  // Get information about the photoset, including the owner.
+  $info = flickr_photoset_get_info($photoset_id);
+  if (!$info) {
+    return;
+  }
+
+  // Get a list of "all" the photos in the photoset. This is cached.
+  $response = flickr_request('flickr.photosets.getPhotos',
+    array(
+      'photoset_id' => $photoset_id,
+      // Get as many images as possible.
+      'per_page' => 500,
+      'extras' => 'owner',
+      'media' => $media,
+    )
+  );
+  if (!$response) {
+    return;
+  }
+
+  // Randomly display $show_n of them.
+  $photos = $response['photoset']['photo'];
+  shuffle($photos);
+
+  // We shouldn't try to return more than the total number of photos.
+  $output = '';
+  $to = min($show_n, count($photos));
+  for ($i = 0; $i < $to; $i++) {
+    // Insert owner into $photo because theme_flickr_photo needs it.
+    $photos[$i]['owner'] = $info['owner'];
+    $output .= theme('flickr_block_photo', array(
+      'photo' => $photos[$i],
+      'size' => $size,
+    ));
+  }
+  return $output;
+}
+
+/**
+ * Random from group block.
+ */
+function _flickr_block_group_random($group_id, $show_n, $size, $media) {
+  // Get a list of "all" the photos in the group. This is cached.
+  $response = flickr_request('flickr.groups.pools.getPhotos',
+    array(
+      'group_id' => $group_id,
+      // Get as many images as possible.
+      'per_page' => 500,
+      'extras' => 'owner',
+      'media' => $media,
+    )
+  );
+  if (!$response) {
+    return;
+  }
+
+  // Randomly display $show_n of them.
+  $photos = $response['photos']['photo'];
+  shuffle($photos);
+
+  // We shouldn't try to return more than the total number of photos.
+  $output = '';
+  $to = min($show_n, count($photos));
+  for ($i = 0; $i < $to; $i++) {
+    $output .= theme('flickr_block_photo', array(
+      'photo' => $photos[$i],
+      'size' => $size,
+    ));
+  }
+  return $output;
+}
+
+
+/**
+ * Random by tag block.
+ */
+function _flickr_block_tag_random($nsid, $show_n, $size, $media, $tag) {
+  // Do a photo search for the provided tag in the given user's public photos
+  $response = flickr_request('flickr.photos.search',
+    array(
+      'user_id' => $nsid,
+      'tags' => $tag,
+      'per_page' => 500,
+      'privacy_filter' => 1,
+      'media' => $media,
+    )
+  );
+
+  // Randomly display $show_n of them.
+  $photos = $response['photos']['photo'];
+  shuffle($photos);
+
+  // We shouldn't try to return more than the total number of photos.
+  $output = '';
+  $to = min($show_n, count($photos));
+  for ($i = 0; $i < $to; $i++) {
+    $output .= theme('flickr_block_photo', array(
+      'photo' => $photos[$i],
+      'size' => $size,
+    ));
+  }
+  return $output;
+}
+
+/**
+ * Recent from photoset block.
+ */
+function _flickr_block_photoset_recent($nsid, $show_n, $size, $media, $photoset_id) {
+  // Get information about the photoset, including the owner.
+  $info = flickr_photoset_get_info($photoset_id);
+  if (!$info) {
+    return;
+  }
+
+  $response = flickr_request('flickr.photosets.getPhotos',
+    array(
+      'photoset_id' => $photoset_id,
+      'per_page' => $show_n,
+      'extras' => 'owner',
+      'media' => $media,
+    )
+  );
+
+  if (!$response) {
+    return;
+  }
+
+  $output = '';
+  foreach ($response['photoset']['photo'] as $photo) {
+    // Insert owner into $photo because theme_flickr_photo needs it.
+    $photo['owner'] = $info['owner'];
+    $output .= theme('flickr_block_photo', array(
+      'photo' => $photo,
+      'size' => $size,
+    ));
+  }
+
+  return $output;
+}
+
+/**
+ * Favorites block.
+ */
+function _flickr_block_favorite_public($nsid, $show_n, $size, $media) {
+  $output = '';
+  if ($photos = flickr_favorites_get_public_list($nsid, 1, array(
+    'per_page' => $show_n,
+    'media' => $media,
+  ))) {
+    foreach ($photos['photo'] as $photo) {
+      $output .= theme('flickr_block_photo', array(
+        'photo' => $photo,
+        'size' => $size,
+      ));
+    }
+  }
+  return $output;
+}
+
+/**
+ * This renders a block with photos from the selected groupid.
+ */
+function _flickr_block_group_recent($groupid, $show_n, $size, $media) {
+  $output = '';
+  if ($photos = flickr_get_group_photos($groupid, 1, array(
+    'per_page' => $show_n,
+    'media' => $media,
+  ))) {
+    foreach ($photos['photo'] as $photo) {
+      $output .= theme('flickr_block_photo', array(
+        'photo' => $photo,
+        'size' => $size,
+      ));
+    }
+  }
+  return $output;
+}
+
+/**
+ * Implements hook_theme().
+ */
+function flickr_block_theme() {
+  return array(
+    'flickr_block_photo' => array(
+      'variables' => array('photo', 'size' => NULL),
+    ),
+    'flickr_block_photoset' => array(
+      'variables' => array('photoset', 'owner', 'size'),
+    ),
+  );
+}
+
+/**
+ * Theme photo blocks.
+ */
+function theme_flickr_block_photo($variables) {
+  $photo = $variables['photo'];
+  $size = $variables['size'];
+  return theme('flickr_photo', array('photo' => $photo, 'size' => $size));
+}
+
+/**
+ * Theme photoset blocks.
+ */
+function theme_flickr_block_photoset($variables) {
+  $photoset = $variables['photoset'];
+  $owner = $variables['owner'];
+  $size = $variables['size'];
+  return theme('flickr_photoset', array(
+    'photoset' => $photoset,
+    'owner' => $owner,
+    'size' => $size,
+  ));
+}
+
