Index: plog-admin/plog-feedback.php
===================================================================
--- plog-admin/plog-feedback.php	(revision 562)
+++ plog-admin/plog-feedback.php	(working copy)
@@ -109,7 +109,9 @@
 #$url = "&amp;entries_per_page=$_SESSION[entries_per_page]&amp;level=$_REQUEST[level]&amp;id=$_REQUEST[id]";
 $url = "?entries_per_page=$_SESSION[entries_per_page]";
 
-$first_item = ($_REQUEST['plog_page'] - 1) * $_SESSION['entries_per_page'];
+$plog_page = isset($_REQUEST["plog_page"]) ? $_REQUEST["plog_page"] : 1;
+
+$first_item = ($plog_page - 1) * $_SESSION['entries_per_page'];
 $limit = "LIMIT $first_item, $_SESSION[entries_per_page]";
 
 // lets generate the pagination menu as well
@@ -121,15 +123,14 @@
 $mod_result = run_query($query);
 $num_comments_im = mysql_result($mod_result, "in_moderation");
 
-$page = isset($_GET["plog_page"]) ? $_GET["plog_page"] : 1;
-
 // filter based on whether were looking at approved comments or unmoderated comments
-$approved = isset($_GET["moderate"]) ? 0 : 1;
+$approved = isset($_REQUEST['moderate']) ? 0 : 1;
 
-if ($approved)
-	$pagination_menu = generate_pagination('plog-feedback.php'.$url,$page,$num_comments,$_SESSION['entries_per_page']);
-else
-	$pagination_menu = generate_pagination('plog-feedback.php'.$url,$page,$num_comments_im,$_SESSION['entries_per_page'],"&amp;moderate=1");
+if ($approved) {
+	$pagination_menu = generate_pagination("admin", "feedback", $plog_page, $num_comments, $_SESSION['entries_per_page']);
+} else {
+	$pagination_menu = generate_pagination("admin", "feedback", $plog_page, $num_comments_im, $_SESSION['entries_per_page'], array("moderate" => 1));
+}
 
 // generate javascript init function for ajax editing
 $query = "SELECT *, UNIX_TIMESTAMP(`date`) AS `unix_date` from ".TABLE_PREFIX."comments WHERE `approved` = $approved ORDER BY `id` DESC $limit";
Index: plog-admin/plog-manage.php
===================================================================
--- plog-admin/plog-manage.php	(revision 562)
+++ plog-admin/plog-manage.php	(working copy)
@@ -300,13 +300,12 @@
 
 	// handle pagination
 	// lets determine the limit filter based on current page and number of results per page
-	if (!isset($_REQUEST["page"])) $_REQUEST["page"] = "1"; // we're on the first page
+	if (isset($_REQUEST['entries_per_page'])) {
+		$_SESSION['entries_per_page'] = $_REQUEST['entries_per_page'];
+	} else {
+		$_SESSION['entries_per_page'] = 20;
+	}
 
-	if (isset($_REQUEST['entries_per_page']))
-	$_SESSION['entries_per_page'] = $_REQUEST['entries_per_page'];
-	else
-	$_SESSION['entries_per_page'] = 20;
-
 	$cond = "";
 
 	// determine the filtering conditional based on the level and id number
@@ -317,31 +316,28 @@
 		$cond = "WHERE `parent_album` = '$id'";
 	}
 
-	$url = "?entries_per_page=$_SESSION[entries_per_page]&amp;level=$_REQUEST[level]&amp;id=$id";
-
-	$plog_page = isset($_REQUEST['plog_page']) ? $_REQUEST['plog_page'] : 0;
+	$plog_page = isset($_REQUEST['plog_page']) ? $_REQUEST['plog_page'] : 1; // we're on the first page
 	$first_item = ($plog_page - 1) * $_SESSION['entries_per_page'];
 	if ($first_item < 0) {
 		$first_item = 0;
-	};
-	$limit = "LIMIT $first_item, $_SESSION[entries_per_page]";
+	}
+	$limit = "LIMIT ".$first_item.", ".$_SESSION['entries_per_page'];
 
 	// lets generate the pagination menu as well
 	$recordCount = "SELECT COUNT(*) AS num_items FROM ".TABLE_PREFIX."$level $cond";
 	$totalRowsResult = mysql_query($recordCount);
 	$totalRows = mysql_result($totalRowsResult,'num_items');
 
-	$page = isset($_GET["plog_page"]) ? $_GET["plog_page"] : 1;
-	$pagination_menu = "\n\t\t" . '<div class="pagination">'.generate_pagination('plog-manage.php'.$url,$page,$totalRows,$_SESSION['entries_per_page']).'</div>';
+	$pagination_menu = "\n\t\t" . '<div class="pagination">'.generate_pagination("admin", "manage", $plog_page, $totalRows, $_SESSION['entries_per_page'], array("level" => $level, "id" => $id, "entries_per_page" => $_SESSION['entries_per_page'])).'</div>';
 
 	$output .= "\n\t\t" . '<form id="contentList" action="'.$_SERVER["PHP_SELF"].'" method="get">';
 
 	$level = $_REQUEST['level'];
 
-	if (empty($level)) {
+	if (empty($level) || $level == "collections") {
 		$output .= generate_breadcrumb_admin("").$pagination_menu;
 		$output .= plog_collection_manager($first_item,$_SESSION['entries_per_page']);
-	};
+	}
 
 	if ($level == "albums") {
 		$output .= generate_breadcrumb_admin("albums", $id).$pagination_menu;
@@ -365,7 +361,7 @@
 		<input type="hidden" name="id" value="'.$id.'" />
 		<input type="hidden" name="action" value="1" />
 		<input class="submit" type="submit" name="delete_checked" onclick="return confirm(\'' . plog_tr('Are you sure you want to delete selected items?') . '\');" value="' . plog_tr('Delete Checked') . '" />';
-	if (!empty($level) && $level != "comments"){
+	if (!empty($level) && $level != "collections" && $level != "comments"){
 		$output .= generate_move_menu($level);
 	};
 	$output .= "\n\t\t</div>\n\t\t</form>\n";
Index: plog-includes/plog-functions.php
===================================================================
--- plog-includes/plog-functions.php	(revision 562)
+++ plog-includes/plog-functions.php	(working copy)
@@ -1024,10 +1024,14 @@
 		}
 	}
 
-	if (!empty($names["collection"])) {
+	if (!empty($names['collection'])) {
+		// check for collections level pagination first
+		if ($names['collection'] == 'page' && !empty($names['album']) && is_numeric($names['album']) && intval($names['album']) == $names['album']) {
+			return array("level" => "collections", "id" => 0, "plog_page" => intval($names['album']));
+		}
 		$sql = "SELECT *
 		FROM `".TABLE_PREFIX."collections`
-		WHERE `path`='".$names["collection"]."'";
+		WHERE `path`='".$names['collection']."'";
 		$result = run_query($sql);
 
 		// No such collection, fall back to main page
@@ -1039,14 +1043,18 @@
 
 		// what if there are multiple collections with same names? I hope there aren't .. this would
 		// suck. But here is an idea, we shouldn't allow the user to enter similar names
-		$rv = array("level" => "collection","id" => $collection["id"]);
+		$rv = array("level" => "collection","id" => $collection['id']);
 	}
 
 	if (!empty($names['album'])) {
+		// check for collection level pagination first
+		if ($names['album'] == 'page' && !empty($names['picture']) && is_numeric($names['picture']) && intval($names['picture']) == $names['picture']) {
+			return array("level" => "collection", "id" => $collection['id'], "plog_page" => intval($names['picture']));
+		}
 		$sql = "SELECT *
 		FROM `".TABLE_PREFIX."albums`
-		WHERE `path`='".$names["album"]."'
-		AND `parent_id`=".intval($collection["id"]);
+		WHERE `path`='".$names['album']."'
+		AND `parent_id`=".intval($collection['id']);
 		$result = run_query($sql);
 
 		// no such album, fall back to collection
@@ -1077,11 +1085,15 @@
 		$rv = array('level' => 'album','id' => $album['id']);
 	}
 
-	if (!empty($names["picture"])) {
+	if (!empty($names['picture'])) {
+		// check for album level pagination first
+		if ($names['picture'] == 'page' && !empty($names['arg1']) && is_numeric($names['arg1']) && intval($names['arg1']) == $names['arg1']) {
+			return array("level" => "album", "id" => $album['id'], "plog_page" => intval($names['arg1']));
+		}
 		$sql = "SELECT *
 		FROM `".TABLE_PREFIX."pictures`
-		WHERE `caption`='".$names["picture"]."'
-		AND `parent_album`=".intval($album["id"]);
+		WHERE `caption`='".$names['picture']."'
+		AND `parent_album`=".intval($album['id']);
 		$result = run_query($sql);
 
 		$picture = mysql_fetch_assoc($result);
@@ -1105,48 +1117,41 @@
 			return $rv;
 		}
 
-		$rv = array("level" => "picture", "id" => $picture["id"]);
+		$rv = array("level" => "picture", "id" => $picture['id']);
 	}
 
 	return $rv;
 }
 
-function generate_pagination($url, $current_page, $items_total, $items_on_page, $extra_params = ''){
+function generate_pagination($level, $id, $current_page, $items_total, $items_on_page, $args = array(1 => "page")){
 	$output = '';
 
-	if (!isset($GLOBALS["total_pictures"])) $GLOBALS["total_pictures"] = 0;
+	if (!isset($GLOBALS['total_pictures'])) $GLOBALS['total_pictures'] = 0;
 
-	if (($items_total == 0) && ($GLOBALS["total_pictures"] > 0)) {
-		$items_total = $GLOBALS["total_pictures"];
+	if (($items_total == 0) && ($GLOBALS['total_pictures'] > 0)) {
+		$items_total = $GLOBALS['total_pictures'];
 	}
 
 	$num_pages = ceil($items_total / $items_on_page);
 
-	// if adding arguments to mod_rewritten urls, then I need ? (question mark) before the arguments
-	// otherwise I want &amp;
-	//$last = substr($url,-1);
-
-	if (!strpos($url,"?")) {
-		$separator = "?";
-	} else {
-		$separator = "&amp;";
-	}
-
 	if ($num_pages > 1){
 		if ($current_page > 1){
-			$output .= ' <a accesskey="," class="pagPrev" href="'.$url.$separator.'plog_page='.($current_page - 1).$extra_params.'"><span>&laquo;</span></a> ';
+			$args['plog_page'] = $current_page - 1;
+			$output .= ' <a accesskey="," class="pagPrev" href="'.generate_url($level, $id, $args).'"><span>&laquo;</span></a> ';
 		}
 
 		for ($i = 1; $i <= $num_pages; $i++){
 			if ($i == $current_page){
 				$output .= '<span class="page_link"> ['.$i.'] </span>';
 			} else{
-				$output .= '<a href="'.$url.$separator.'plog_page='.$i.$extra_params.'" class="page_link">'.$i.'</a> ';
+				$args['plog_page'] =  $i;
+				$output .= '<a href="'.generate_url($level, $id, $args).'" class="page_link">'.$i.'</a> ';
 			}
 		}
 
 		if ($current_page != $num_pages){
-			$output .= ' <a accesskey="." class="pagNext" href="'.$url.$separator.'plog_page='.($current_page + 1).$extra_params.'"><span>&raquo;</span></a> ';
+			$args['plog_page'] =  $current_page + 1;
+			$output .= ' <a accesskey="." class="pagNext" href="'.generate_url($level, $id, $args).'"><span>&raquo;</span></a> ';
 		}
 	}
 
@@ -1166,12 +1171,20 @@
 	$rv = '';
 
 	if ($config['use_mod_rewrite']){
+		$args = '';
+		// I need to give additional arguments to the url-s
+		if (sizeof($arg) > 0) {
+			foreach($arg as $aval) {
+				$args .= $aval."/";
+			}
+		}
+
 		switch($level){
 			case "collection":
 				$query = "SELECT `path` FROM `".TABLE_PREFIX."collections` WHERE `id`=".intval($id);
 				$result = run_query($query);
 				$row = mysql_fetch_assoc($result);
-				$rv = $config['baseurl'].rawurlencode(SmartStripSlashes($row['path']))."/";
+				$rv = $config['baseurl'].rawurlencode(SmartStripSlashes($row['path']))."/".$args;
 				break;
 			case "album":
 				$query = "SELECT
@@ -1182,15 +1195,7 @@
 				WHERE `a`.`id`=".intval($id);
 				$result = run_query($query);
 				$row = mysql_fetch_assoc($result);
-
-				$rv = $config['baseurl'].rawurlencode(SmartStripSlashes($row['collection_path'])) . '/' . rawurlencode(SmartStripSlashes($row['album_path']))."/";
-
-				// I need to give additional arguments to the url-s
-				if (sizeof($arg) > 0) {
-					foreach($arg as $aval) {
-						$rv .= $aval."/";
-					}
-				}
+				$rv = $config['baseurl'].rawurlencode(SmartStripSlashes($row['collection_path'])) . '/' . rawurlencode(SmartStripSlashes($row['album_path']))."/".$args;
 				break;
 			case "picture":
 				$pic = get_picture_by_id($id);
@@ -1203,63 +1208,65 @@
 				if (sizeof($arg) > 0) {
 					foreach($arg as $akey => $aval) {
 						// mod_rewrite url-s need /sorted in them, the old style ones do not.
-						// this temporary workaround removes the 'sorted' string
-						if ($aval != 'sorted') {
+						// this temporary workaround removes the 'sorted' and 'plog_page' strings
+						if (!is_numeric($akey)) {
 							$rv .= "&amp;".$akey."=".$aval;
 						}
 					}
 				}
 				break;
 			case "collections":
-				default:
-				$rv = $config['baseurl'];
+			default:
+				$rv = $config['baseurl'].$args;
 				break;
 		}
 	} else {
 		// if there are non-Plogger query items, get them here to prepend to the URL query string
-		$query = (isset($config['query_args'])) ? "?".$config['query_args']."&amp;" : $query = "?";
+		// non-Plogger query items only work with old style URLs (not with mod_rewrite URLs)
+		$query = (isset($config['query_args'])) ? "?".$config['query_args']."&amp;" : "?";
+		
+		$args = '';
+		// add on any additional arguments from the $arg array
+		if (sizeof($arg) > 0) {
+			foreach($arg as $akey => $aval) {
+				// mod_rewrite url-s need /sorted and /plog_page in them, the old style ones do not.
+				// this temporary workaround removes the 'sorted' and 'plog_page' strings
+				if (!is_numeric($akey)) {
+					$args .= "&amp;".$akey."=".$aval;
+				}
+			}
+		}
 
 		switch($level){
+			// admin section for generate_url
+			case "admin":
+				$rv = $config['baseurl']."plog-admin/plog-".$id.".php?".substr($args, 5);
+				break;
+			// front end section for generate_url
 			case "collection":
-				return $config['baseurl'].$query.'level=collection&amp;id='.$id;
+				$rv = $config['baseurl'].$query.'level=collection&amp;id='.$id.$args;
 				break;
 			case "album":
-				$rv = $config['baseurl'].$query.'level=album&amp;id='.$id;
-				if (sizeof($arg) > 0) {
-					foreach($arg as $akey => $aval) {
-						// mod_rewrite url-s need /sorted in them, the old style ones do not.
-						// this temporary workaround removes the 'sorted' string
-						if ($aval != 'sorted') {
-							$rv .= "&amp;".$akey."=".$aval;
-						}
-					}
-				}
+				$rv = $config['baseurl'].$query.'level=album&amp;id='.$id.$args;
 				break;
 			case "picture":
 				$rv = $config['baseurl'].$query.'level=picture&amp;id='.$id;
 				break;
 			case "search":
-				$rv = $config['baseurl'].$query."level=search";
-				// I need to give additional arguments to the url-s
-				if (sizeof($arg) > 0) {
-					foreach($arg as $akey => $aval) {
-						// mod_rewrite url-s need /sorted in them, the old style ones do not.
-						// this temporary workaround removes the 'sorted' string
-						if ($aval != 'sorted') {
-							$rv .= "&amp;".$akey."=".$aval;
-						}
-					}
-				}
+				$rv = $config['baseurl'].$query."level=search".$args;
 				break;
 			case "collections":
-				default:
-				$query = (isset($config['query_args'])) ? "?".$config['query_args'] : $query = "";
-				$rv = $config['baseurl'].$query;
+			default:
+				$rv = $config['baseurl'];
+				if ($query != "?" && empty($args)) {
+					if ($query == "?") { $args = substr($args, 5); }
+					$rv .= $query.$args;
+				}
 				break;
 		}
 	}
 
-	// replace &amp; with & if outputting to email
+	// replace &amp; with & if formatting plaintext (i.e. outputting to email)
 	if ($plaintext !== false){
 		$rv = str_replace("&amp;","&",$rv);
 	}
@@ -1974,38 +1981,31 @@
 	global $config;
 
 	if ($GLOBALS['plogger_mode'] != 'slideshow') {
-		$page = isset($_GET["plog_page"]) ? intval($_GET["plog_page"]) : 1;
-
-		if ($GLOBALS['plogger_level'] == "search") {
-			$p_url = generate_url("search", -1, array('searchterms'=>urlencode($_GET["searchterms"])));
-		}
-		else {
-			if ($GLOBALS['plogger_level']) {
-				$p_url = generate_url($GLOBALS['plogger_level'], $GLOBALS['plogger_id']);
-			} else {
-				$p_url = generate_url("collections");
-			}
-		}
-
-		switch($GLOBALS['plogger_level']) {
+		$page = isset($_GET['plog_page']) ? intval($_GET['plog_page']) : 1;
+		$level = $GLOBALS['plogger_level'];
+		$id = $GLOBALS['plogger_id'];
+		switch($level) {
 			case 'search':
-				$num_items = $GLOBALS["total_pictures"];
-			break;
+				$num_items = $GLOBALS['total_pictures'];
+				return generate_pagination("search", -1, $page, $num_items, $config['thumb_num'], array('searchterms'=>urlencode($_GET['searchterms'])));
+				break;
 
 			case 'album':
 				$num_items = plogger_album_picture_count();
-			break;
+				break;
 
 			case 'collection':
 				$num_items = plogger_collection_album_count();
-			break;
+				break;
 
 			default:
-			$num_items = plogger_count_collections();
-			break;
+				$level = "collections";
+				$id = 0;
+				$num_items = plogger_count_collections();
+				break;
 		}
 
-		return generate_pagination($p_url, $page, $num_items, $config["thumb_num"]);
+		return generate_pagination($level, $id, $page, $num_items, $config['thumb_num']);
 	}
 
 }
Index: plog-load-config.php
===================================================================
--- plog-load-config.php	(revision 562)
+++ plog-load-config.php	(working copy)
@@ -85,7 +85,8 @@
 // remove plog-admin/ from the end, if present .. is there a better way to determine the full url?
 // had to update this for new use of links without mod_rewrite turned on (only affects the View gallery greybox in Admin)
 if (strpos($config['baseurl'], "plog-admin/")) {
-	$config['baseurl'] = substr($config['baseurl'],0,strpos($config['baseurl'], "plog-admin/"));
+	$config['use_mod_rewrite'] = 0;
+	$config['baseurl'] = substr($config['baseurl'], 0, strpos($config['baseurl'], "plog-admin/"));
 }
 
 $config['theme_url'] = $config['gallery_url']."plog-content/themes/".basename($config['theme_dir'])."/";
Index: plogger.php
===================================================================
--- plogger.php	(revision 562)
+++ plogger.php	(working copy)
@@ -21,18 +21,15 @@
 		if (isset($resolved_path['id'])) {
 			$_GET['id'] = $resolved_path['id'];
 		}
+		if (isset($resolved_path['plog_page'])) {
+			$_GET['plog_page'] = $resolved_path['plog_page'];
+		}
 		if (isset($resolved_path['mode'])) {
 			$_GET['mode'] = $resolved_path['mode'];
 		}
 
-		// get page number from url, if present
+		// get the path for RSS links (maybe should rework this)
 		$parts = parse_url($_SERVER['REQUEST_URI']);
-		if (isset($parts['query'])) {
-			parse_str($parts['query'],$query_parts);
-			if (!empty($query_parts['plog_page'])) {
-				$_GET['plog_page'] = $query_parts['plog_page'];
-			}
-		}
 		$path = $parts['path'];
 	}
 } else {
