diff -urN orig/rhythmbox-0.11.6svn20081008.orig/data/glade/Makefile.am rhythmbox-0.11.6svn20081008/data/glade/Makefile.am
--- orig/rhythmbox-0.11.6svn20081008.orig/data/glade/Makefile.am	2008-10-07 17:06:16.000000000 +0100
+++ rhythmbox-0.11.6svn20081008/data/glade/Makefile.am	2008-11-02 17:56:54.000000000 +0000
@@ -12,6 +12,7 @@
 		plugins.glade			\
 		playlist-save.glade		\
 		playback-prefs.glade		\
+		random-prefs.glade		\
 		uri-new.glade
 
 gladedir = $(pkgdatadir)/glade
diff -urN orig/rhythmbox-0.11.6svn20081008.orig/data/glade/Makefile.in rhythmbox-0.11.6svn20081008/data/glade/Makefile.in
--- orig/rhythmbox-0.11.6svn20081008.orig/data/glade/Makefile.in	2008-10-08 09:32:01.000000000 +0100
+++ rhythmbox-0.11.6svn20081008/data/glade/Makefile.in	2008-11-02 19:08:16.000000000 +0000
@@ -304,6 +304,7 @@
 		plugins.glade			\
 		playlist-save.glade		\
 		playback-prefs.glade		\
+		random-prefs.glade              \
 		uri-new.glade
 
 gladedir = $(pkgdatadir)/glade
diff -urN orig/rhythmbox-0.11.6svn20081008.orig/data/glade/random-prefs.glade rhythmbox-0.11.6svn20081008/data/glade/random-prefs.glade
--- orig/rhythmbox-0.11.6svn20081008.orig/data/glade/random-prefs.glade	1970-01-01 01:00:00.000000000 +0100
+++ rhythmbox-0.11.6svn20081008/data/glade/random-prefs.glade	2008-11-12 23:55:37.000000000 +0000
@@ -0,0 +1,390 @@
+<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
+<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd">
+
+<glade-interface>
+
+<widget class="GtkWindow" id="preferences">
+  <property name="visible">True</property>
+  <property name="title" translatable="yes"></property>
+  <property name="type">GTK_WINDOW_TOPLEVEL</property>
+  <property name="window_position">GTK_WIN_POS_NONE</property>
+  <property name="modal">False</property>
+  <property name="resizable">False</property>
+  <property name="destroy_with_parent">False</property>
+  <property name="decorated">True</property>
+  <property name="skip_taskbar_hint">False</property>
+  <property name="skip_pager_hint">False</property>
+  <property name="type_hint">GDK_WINDOW_TYPE_HINT_NORMAL</property>
+  <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
+  <property name="focus_on_map">True</property>
+  <property name="urgency_hint">False</property>
+
+  <child>
+    <widget class="GtkTable" id="random_table">
+      <property name="border_width">12</property>
+      <property name="visible">True</property>
+      <property name="n_rows">6</property>
+      <property name="n_columns">2</property>
+      <property name="homogeneous">True</property>
+      <property name="row_spacing">0</property>
+      <property name="column_spacing">0</property>
+
+      <child>
+	<widget class="GtkLabel" id="shuffle_behaviour_label">
+	  <property name="visible">True</property>
+	  <property name="label" translatable="yes">Behaviour of Shuffle button:</property>
+	  <property name="use_underline">False</property>
+	  <property name="use_markup">False</property>
+	  <property name="justify">GTK_JUSTIFY_RIGHT</property>
+	  <property name="wrap">False</property>
+	  <property name="selectable">False</property>
+	  <property name="xalign">1</property>
+	  <property name="yalign">0.5</property>
+	  <property name="xpad">0</property>
+	  <property name="ypad">0</property>
+	  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+	  <property name="width_chars">-1</property>
+	  <property name="single_line_mode">False</property>
+	  <property name="angle">0</property>
+	</widget>
+	<packing>
+	  <property name="left_attach">0</property>
+	  <property name="right_attach">1</property>
+	  <property name="top_attach">0</property>
+	  <property name="bottom_attach">1</property>
+	</packing>
+      </child>
+
+      <child>
+	<widget class="GtkHButtonBox" id="shuffle_behaviour_box">
+	  <property name="visible">True</property>
+	  <property name="layout_style">GTK_BUTTONBOX_DEFAULT_STYLE</property>
+	  <property name="spacing">0</property>
+
+	  <child>
+	    <widget class="GtkRadioButton" id="shuffle_button_radio_shuffle">
+	      <property name="visible">True</property>
+	      <property name="can_focus">True</property>
+	      <property name="label" translatable="yes">Shuffle</property>
+	      <property name="use_underline">True</property>
+	      <property name="relief">GTK_RELIEF_NORMAL</property>
+	      <property name="focus_on_click">True</property>
+	      <property name="active">True</property>
+	      <property name="inconsistent">False</property>
+	      <property name="draw_indicator">True</property>
+	      <signal name="toggled" handler="rb_shell_preferences_random_shuffle_behaviour_activated_cb"/>
+	    </widget>
+	  </child>
+
+	  <child>
+	    <widget class="GtkRadioButton" id="shuffle_button_radio_random">
+	      <property name="visible">True</property>
+	      <property name="can_focus">True</property>
+	      <property name="label" translatable="yes">Random</property>
+	      <property name="use_underline">True</property>
+	      <property name="relief">GTK_RELIEF_NORMAL</property>
+	      <property name="focus_on_click">True</property>
+	      <property name="active">False</property>
+	      <property name="inconsistent">False</property>
+	      <property name="draw_indicator">True</property>
+	      <property name="group">shuffle_button_radio_shuffle</property>
+	      <signal name="toggled" handler="rb_shell_preferences_random_shuffle_behaviour_activated_cb"/>
+	    </widget>
+	  </child>
+	</widget>
+	<packing>
+	  <property name="left_attach">1</property>
+	  <property name="right_attach">2</property>
+	  <property name="top_attach">0</property>
+	  <property name="bottom_attach">1</property>
+	</packing>
+      </child>
+
+      <child>
+	<widget class="GtkHScale" id="veryrecentplay_period_scale">
+	  <property name="visible">True</property>
+	  <property name="can_focus">True</property>
+	  <property name="draw_value">True</property>
+	  <property name="value_pos">GTK_POS_RIGHT</property>
+	  <property name="digits">1</property>
+	  <property name="update_policy">GTK_UPDATE_CONTINUOUS</property>
+	  <property name="inverted">False</property>
+	  <property name="adjustment">0 0 100 1 10 10</property>
+	</widget>
+	<packing>
+	  <property name="left_attach">1</property>
+	  <property name="right_attach">2</property>
+	  <property name="top_attach">5</property>
+	  <property name="bottom_attach">6</property>
+	  <property name="x_options">fill</property>
+	</packing>
+      </child>
+
+      <child>
+	<widget class="GtkLabel" id="veryrecentplay_period_label">
+	  <property name="visible">True</property>
+	  <property name="label" translatable="yes">Very recent period (days):</property>
+	  <property name="use_underline">False</property>
+	  <property name="use_markup">False</property>
+	  <property name="justify">GTK_JUSTIFY_RIGHT</property>
+	  <property name="wrap">False</property>
+	  <property name="selectable">False</property>
+	  <property name="xalign">1</property>
+	  <property name="yalign">0.5</property>
+	  <property name="xpad">0</property>
+	  <property name="ypad">0</property>
+	  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+	  <property name="width_chars">-1</property>
+	  <property name="single_line_mode">False</property>
+	  <property name="angle">0</property>
+	</widget>
+	<packing>
+	  <property name="left_attach">0</property>
+	  <property name="right_attach">1</property>
+	  <property name="top_attach">5</property>
+	  <property name="bottom_attach">6</property>
+	  <property name="x_options">fill</property>
+	  <property name="y_options"></property>
+	</packing>
+      </child>
+
+      <child>
+	<widget class="GtkLabel" id="veryrecentplay_bias_label">
+	  <property name="visible">True</property>
+	  <property name="label" translatable="yes">Bias against very recent play:</property>
+	  <property name="use_underline">False</property>
+	  <property name="use_markup">False</property>
+	  <property name="justify">GTK_JUSTIFY_RIGHT</property>
+	  <property name="wrap">False</property>
+	  <property name="selectable">False</property>
+	  <property name="xalign">1</property>
+	  <property name="yalign">0.5</property>
+	  <property name="xpad">0</property>
+	  <property name="ypad">0</property>
+	  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+	  <property name="width_chars">-1</property>
+	  <property name="single_line_mode">False</property>
+	  <property name="angle">0</property>
+	</widget>
+	<packing>
+	  <property name="left_attach">0</property>
+	  <property name="right_attach">1</property>
+	  <property name="top_attach">4</property>
+	  <property name="bottom_attach">5</property>
+	  <property name="x_options">fill</property>
+	  <property name="y_options"></property>
+	</packing>
+      </child>
+
+      <child>
+	<widget class="GtkHScale" id="veryrecentplay_bias_scale">
+	  <property name="visible">True</property>
+	  <property name="can_focus">True</property>
+	  <property name="draw_value">False</property>
+	  <property name="value_pos">GTK_POS_RIGHT</property>
+	  <property name="digits">1</property>
+	  <property name="update_policy">GTK_UPDATE_CONTINUOUS</property>
+	  <property name="inverted">False</property>
+	  <property name="adjustment">1 1 100 1 10 10</property>
+	</widget>
+	<packing>
+	  <property name="left_attach">1</property>
+	  <property name="right_attach">2</property>
+	  <property name="top_attach">4</property>
+	  <property name="bottom_attach">5</property>
+	  <property name="x_options">fill</property>
+	  <property name="y_options">fill</property>
+	</packing>
+      </child>
+
+      <child>
+	<widget class="GtkHScale" id="age_bias_scale">
+	  <property name="visible">True</property>
+	  <property name="can_focus">True</property>
+	  <property name="draw_value">False</property>
+	  <property name="value_pos">GTK_POS_RIGHT</property>
+	  <property name="digits">1</property>
+	  <property name="update_policy">GTK_UPDATE_CONTINUOUS</property>
+	  <property name="inverted">False</property>
+	  <property name="adjustment">0 0 40 1 1 1</property>
+	</widget>
+	<packing>
+	  <property name="left_attach">1</property>
+	  <property name="right_attach">2</property>
+	  <property name="top_attach">3</property>
+	  <property name="bottom_attach">4</property>
+	  <property name="x_options">fill</property>
+	</packing>
+      </child>
+
+      <child>
+	<widget class="GtkLabel" id="age_bias_label">
+	  <property name="visible">True</property>
+	  <property name="label" translatable="yes">Bias for 'age':</property>
+	  <property name="use_underline">False</property>
+	  <property name="use_markup">False</property>
+	  <property name="justify">GTK_JUSTIFY_RIGHT</property>
+	  <property name="wrap">False</property>
+	  <property name="selectable">False</property>
+	  <property name="xalign">1</property>
+	  <property name="yalign">0.5</property>
+	  <property name="xpad">0</property>
+	  <property name="ypad">0</property>
+	  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+	  <property name="width_chars">-1</property>
+	  <property name="single_line_mode">False</property>
+	  <property name="angle">0</property>
+	</widget>
+	<packing>
+	  <property name="left_attach">0</property>
+	  <property name="right_attach">1</property>
+	  <property name="top_attach">3</property>
+	  <property name="bottom_attach">4</property>
+	  <property name="x_options">fill</property>
+	  <property name="y_options"></property>
+	</packing>
+      </child>
+
+      <child>
+	<widget class="GtkLabel" id="rating_bias_label">
+	  <property name="visible">True</property>
+	  <property name="label" translatable="yes">Bias towards rating:</property>
+	  <property name="use_underline">False</property>
+	  <property name="use_markup">False</property>
+	  <property name="justify">GTK_JUSTIFY_LEFT</property>
+	  <property name="wrap">False</property>
+	  <property name="selectable">False</property>
+	  <property name="xalign">1</property>
+	  <property name="yalign">0.5</property>
+	  <property name="xpad">0</property>
+	  <property name="ypad">0</property>
+	  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+	  <property name="width_chars">-1</property>
+	  <property name="single_line_mode">True</property>
+	  <property name="angle">0</property>
+	</widget>
+	<packing>
+	  <property name="left_attach">0</property>
+	  <property name="right_attach">1</property>
+	  <property name="top_attach">2</property>
+	  <property name="bottom_attach">3</property>
+	  <property name="x_options">fill</property>
+	  <property name="y_options"></property>
+	</packing>
+      </child>
+
+      <child>
+	<widget class="GtkHScale" id="rating_bias_scale">
+	  <property name="visible">True</property>
+	  <property name="can_focus">True</property>
+	  <property name="draw_value">False</property>
+	  <property name="value_pos">GTK_POS_RIGHT</property>
+	  <property name="digits">1</property>
+	  <property name="update_policy">GTK_UPDATE_CONTINUOUS</property>
+	  <property name="inverted">False</property>
+	  <property name="adjustment">0 0 40 1 1 1</property>
+	</widget>
+	<packing>
+	  <property name="left_attach">1</property>
+	  <property name="right_attach">2</property>
+	  <property name="top_attach">2</property>
+	  <property name="bottom_attach">3</property>
+	  <property name="x_options">fill</property>
+	  <property name="y_options">fill</property>
+	</packing>
+      </child>
+
+      <child>
+	<widget class="GtkHBox" id="hbox1">
+	  <property name="visible">True</property>
+	  <property name="homogeneous">False</property>
+	  <property name="spacing">0</property>
+
+	  <child>
+	    <widget class="GtkLabel" id="label1">
+	      <property name="visible">True</property>
+	      <property name="label" translatable="yes">Low</property>
+	      <property name="use_underline">False</property>
+	      <property name="use_markup">False</property>
+	      <property name="justify">GTK_JUSTIFY_LEFT</property>
+	      <property name="wrap">False</property>
+	      <property name="selectable">False</property>
+	      <property name="xalign">0.5</property>
+	      <property name="yalign">0.5</property>
+	      <property name="xpad">0</property>
+	      <property name="ypad">0</property>
+	      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+	      <property name="width_chars">-1</property>
+	      <property name="single_line_mode">False</property>
+	      <property name="angle">0</property>
+	    </widget>
+	    <packing>
+	      <property name="padding">0</property>
+	      <property name="expand">False</property>
+	      <property name="fill">False</property>
+	    </packing>
+	  </child>
+
+	  <child>
+	    <widget class="GtkLabel" id="label3">
+	      <property name="visible">True</property>
+	      <property name="label" translatable="yes"></property>
+	      <property name="use_underline">False</property>
+	      <property name="use_markup">False</property>
+	      <property name="justify">GTK_JUSTIFY_LEFT</property>
+	      <property name="wrap">False</property>
+	      <property name="selectable">False</property>
+	      <property name="xalign">0.5</property>
+	      <property name="yalign">0.5</property>
+	      <property name="xpad">0</property>
+	      <property name="ypad">0</property>
+	      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+	      <property name="width_chars">-1</property>
+	      <property name="single_line_mode">False</property>
+	      <property name="angle">0</property>
+	    </widget>
+	    <packing>
+	      <property name="padding">0</property>
+	      <property name="expand">True</property>
+	      <property name="fill">False</property>
+	    </packing>
+	  </child>
+
+	  <child>
+	    <widget class="GtkLabel" id="label2">
+	      <property name="visible">True</property>
+	      <property name="label" translatable="yes">High</property>
+	      <property name="use_underline">False</property>
+	      <property name="use_markup">False</property>
+	      <property name="justify">GTK_JUSTIFY_LEFT</property>
+	      <property name="wrap">False</property>
+	      <property name="selectable">False</property>
+	      <property name="xalign">0.5</property>
+	      <property name="yalign">0.5</property>
+	      <property name="xpad">0</property>
+	      <property name="ypad">0</property>
+	      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+	      <property name="width_chars">-1</property>
+	      <property name="single_line_mode">False</property>
+	      <property name="angle">0</property>
+	    </widget>
+	    <packing>
+	      <property name="padding">0</property>
+	      <property name="expand">False</property>
+	      <property name="fill">False</property>
+	    </packing>
+	  </child>
+	</widget>
+	<packing>
+	  <property name="left_attach">1</property>
+	  <property name="right_attach">2</property>
+	  <property name="top_attach">1</property>
+	  <property name="bottom_attach">2</property>
+	  <property name="x_options">fill</property>
+	</packing>
+      </child>
+    </widget>
+  </child>
+</widget>
+
+</glade-interface>
diff -urN orig/rhythmbox-0.11.6svn20081008.orig/data/glade/random-prefs.gladep rhythmbox-0.11.6svn20081008/data/glade/random-prefs.gladep
--- orig/rhythmbox-0.11.6svn20081008.orig/data/glade/random-prefs.gladep	1970-01-01 01:00:00.000000000 +0100
+++ rhythmbox-0.11.6svn20081008/data/glade/random-prefs.gladep	2008-11-12 23:55:37.000000000 +0000
@@ -0,0 +1,8 @@
+<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
+<!DOCTYPE glade-project SYSTEM "http://glade.gnome.org/glade-project-2.0.dtd">
+
+<glade-project>
+  <name></name>
+  <program_name></program_name>
+  <gnome_support>FALSE</gnome_support>
+</glade-project>
diff -urN orig/rhythmbox-0.11.6svn20081008.orig/data/rhythmbox.schemas rhythmbox-0.11.6svn20081008/data/rhythmbox.schemas
--- orig/rhythmbox-0.11.6svn20081008.orig/data/rhythmbox.schemas	2008-10-07 17:06:16.000000000 +0100
+++ rhythmbox-0.11.6svn20081008/data/rhythmbox.schemas	2008-11-13 00:10:51.000000000 +0000
@@ -315,8 +315,8 @@
         <locale name="C">
 	<short>Order to play songs in</short>
 	<long>Value identifies the order songs are played in. Legal values are:
-	"linear", "shuffle", "random-equal-weights", "random-by-age",
-	"random-by-rating".</long>
+	"linear", "shuffle",
+	"random-by-age-and-rating". </long>
         </locale>
       </schema>
       <schema>
@@ -833,6 +833,50 @@
         </locale>
       </schema>
       <schema>
+        <key>/schemas/apps/rhythmbx/random/rating_bias</key>
+        <applyto>/apps/rhythmbox/rating_bias</applyto>
+        <owner>rhythmbox</owner>
+        <type>float</type>
+        <default>1.0</default>
+        <locale name="C">
+	<short>How much influence your ratings have on random playback.</short>
+	<long>The higher this value the more influence your ratings have on random playback.  Unrated entries are equivalent to a rating of 2.5.  Setting this value to 0 causes the random playback to ignore your ratings.</long>
+        </locale>
+      </schema>
+      <schema>
+        <key>/schemas/apps/rhythmbx/random/age_bias</key>
+        <applyto>/apps/rhythmbox/age_bias</applyto>
+        <owner>rhythmbox</owner>
+        <type>float</type>
+        <default>8.0</default>
+        <locale name="C">
+	<short>Increases the chance that songs that haven't been played for a while are played in random playback.</short>
+	<long>The higher this value the more influence the time since the track was last played has on random playback. Setting this value to 0 causes the random playback to ignore when the track was last played.</long>
+        </locale>
+      </schema>
+      <schema>
+        <key>/schemas/apps/rhythmbx/random/very_recent_bias</key>
+        <applyto>/apps/rhythmbox/very_recent_bias</applyto>
+        <owner>rhythmbox</owner>
+        <type>float</type>
+        <default>4.0</default>
+        <locale name="C">
+	<short>The higher this value the less likely very recently played tracks will be played in random playback.</short>
+	<long>Tracks that have been played very recently (as defined by very_recent_period) are penalised by having their probability divided by this penalty.</long>
+        </locale>
+      </schema>
+      <schema>
+        <key>/schemas/apps/rhythmbx/random/very_recent_period</key>
+        <applyto>/apps/rhythmbox/very_recent_period</applyto>
+        <owner>rhythmbox</owner>
+        <type>float</type>
+        <default>2.0</default>
+        <locale name="C">
+	<short>The time (in days) that is classified as 'very recent'.</short>
+	<long>The time (in days) for which 'very_recent_bias' is applied.  This shouldn't be too large otherwise it could include most of your tracks which would make the penalty pointless.</long>
+        </locale>
+      </schema>
+      <schema>
         <key>/schemas/apps/rhythmbox/plugins/no_user_plugins</key>
         <applyto>/apps/rhythmbox/plugins/no_user_plugins</applyto>
         <owner>rhythmbox</owner>
diff -urN orig/rhythmbox-0.11.6svn20081008.orig/lib/rb-preferences.h rhythmbox-0.11.6svn20081008/lib/rb-preferences.h
--- orig/rhythmbox-0.11.6svn20081008.orig/lib/rb-preferences.h	2008-10-07 17:06:11.000000000 +0100
+++ rhythmbox-0.11.6svn20081008/lib/rb-preferences.h	2008-11-02 17:57:05.000000000 +0000
@@ -84,6 +84,15 @@
 #define CONF_PLAYER_TRANSITION_TIME 	CONF_PREFIX "/player/transition_time"
 #define CONF_PLAYER_NETWORK_BUFFER_SIZE	CONF_PREFIX "/player/network_buffer_size"
 
+#define CONF_RANDOM_DIR			CONF_PREFIX "/random"
+#define CONF_RANDOM_RATING_BIAS		CONF_PREFIX "/random/rating_bias"
+#define CONF_RANDOM_AGE_BIAS		CONF_PREFIX "/random/age_bias"
+#define CONF_RANDOM_VERY_RECENT_BIAS    CONF_PREFIX "/random/very_recent_bias"
+#define CONF_RANDOM_VERY_RECENT_PERIOD	CONF_PREFIX "/random/very_recent_period"
+#define CONF_RANDOM_SHUFFLE_BEHAVIOUR	CONF_PREFIX "/random/shuffle_behaviour"
+/* These are the indexes of the radio buttons - is there a safer way? */
+#define CONF_RANDOM_SHUFFLE_BEHAVIOUR_INDEX_SHUFFLE 0
+#define CONF_RANDOM_SHUFFLE_BEHAVIOUR_INDEX_RANDOM 1
 G_END_DECLS
 
 #endif /* __RB_PREFERENCES_H */
diff -urN orig/rhythmbox-0.11.6svn20081008.orig/shell/Makefile.am rhythmbox-0.11.6svn20081008/shell/Makefile.am
--- orig/rhythmbox-0.11.6svn20081008.orig/shell/Makefile.am	2008-10-07 17:06:13.000000000 +0100
+++ rhythmbox-0.11.6svn20081008/shell/Makefile.am	2008-11-02 17:57:05.000000000 +0000
@@ -80,14 +80,8 @@
 	rb-play-order-shuffle.h				\
 	rb-play-order-random.c				\
 	rb-play-order-random.h				\
-	rb-play-order-random-equal-weights.c		\
-	rb-play-order-random-equal-weights.h		\
-	rb-play-order-random-by-age.c			\
-	rb-play-order-random-by-age.h			\
 	rb-play-order-random-by-age-and-rating.c	\
 	rb-play-order-random-by-age-and-rating.h	\
-	rb-play-order-random-by-rating.c		\
-	rb-play-order-random-by-rating.h		\
 	rb-tray-icon.c					\
 	rb-tray-icon.h					\
 	rb-missing-plugins.c				\
diff -urN orig/rhythmbox-0.11.6svn20081008.orig/shell/Makefile.in rhythmbox-0.11.6svn20081008/shell/Makefile.in
--- orig/rhythmbox-0.11.6svn20081008.orig/shell/Makefile.in	2008-10-08 09:32:07.000000000 +0100
+++ rhythmbox-0.11.6svn20081008/shell/Makefile.in	2008-11-02 17:57:05.000000000 +0000
@@ -61,10 +61,9 @@
 	rb-removable-media-manager.lo rb-history.lo rb-play-order.lo \
 	rb-play-order-linear.lo rb-play-order-linear-loop.lo \
 	rb-play-order-queue.lo rb-play-order-shuffle.lo \
-	rb-play-order-random.lo rb-play-order-random-equal-weights.lo \
-	rb-play-order-random-by-age.lo \
+	rb-play-order-random.lo \
 	rb-play-order-random-by-age-and-rating.lo \
-	rb-play-order-random-by-rating.lo rb-tray-icon.lo \
+	rb-tray-icon.lo \
 	rb-missing-plugins.lo
 librbshell_la_OBJECTS = $(am_librbshell_la_OBJECTS)
 am__installdirs = "$(DESTDIR)$(bindir)"
@@ -397,14 +396,8 @@
 	rb-play-order-shuffle.h				\
 	rb-play-order-random.c				\
 	rb-play-order-random.h				\
-	rb-play-order-random-equal-weights.c		\
-	rb-play-order-random-equal-weights.h		\
-	rb-play-order-random-by-age.c			\
-	rb-play-order-random-by-age.h			\
 	rb-play-order-random-by-age-and-rating.c	\
 	rb-play-order-random-by-age-and-rating.h	\
-	rb-play-order-random-by-rating.c		\
-	rb-play-order-random-by-rating.h		\
 	rb-tray-icon.c					\
 	rb-tray-icon.h					\
 	rb-missing-plugins.c				\
@@ -511,9 +504,6 @@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rb-play-order-linear.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rb-play-order-queue.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rb-play-order-random-by-age-and-rating.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rb-play-order-random-by-age.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rb-play-order-random-by-rating.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rb-play-order-random-equal-weights.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rb-play-order-random.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rb-play-order-shuffle.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rb-play-order.Plo@am__quote@
diff -urN orig/rhythmbox-0.11.6svn20081008.orig/shell/rb-play-order-random-by-age-and-rating.c rhythmbox-0.11.6svn20081008/shell/rb-play-order-random-by-age-and-rating.c
--- orig/rhythmbox-0.11.6svn20081008.orig/shell/rb-play-order-random-by-age-and-rating.c	2008-10-07 17:06:13.000000000 +0100
+++ rhythmbox-0.11.6svn20081008/shell/rb-play-order-random-by-age-and-rating.c	2008-11-13 00:24:54.000000000 +0000
@@ -30,6 +30,8 @@
 #include "config.h"
 
 #include "rb-play-order-random-by-age-and-rating.h"
+#include "eel-gconf-extensions.h"
+#include "rb-preferences.h"
 
 #include "rhythmdb.h"
 #include <time.h>
@@ -66,8 +68,49 @@
 }
 
 static void
+rb_random_play_order_by_age_and_rating_fromeel (RBRandomPlayOrderByAgeAndRating *porder)
+{
+        porder->rating_bias = eel_gconf_get_float (CONF_RANDOM_RATING_BIAS);
+        porder->age_bias = eel_gconf_get_float (CONF_RANDOM_AGE_BIAS);
+        porder->very_recent_bias = eel_gconf_get_float (CONF_RANDOM_VERY_RECENT_BIAS);
+
+	/* This is used as a divisor so it mustn't be 0 and it doesn't make sense for it to be less than 1 */
+	if (porder->very_recent_bias < 1.0)
+		porder->very_recent_bias = 1.0;
+
+	/* Users setting is in days, seconds is more useful for us here */
+        porder->very_recent_period = eel_gconf_get_float (CONF_RANDOM_VERY_RECENT_PERIOD) * 60*60*24;
+}
+
+static void
+rb_random_play_order_by_age_and_rating_prefchange_cb (GConfClient *client,
+                         guint cnxn_id,
+                         GConfEntry *entry,
+                         RBRandomPlayOrderByAgeAndRating *porder)
+{
+	rb_random_play_order_by_age_and_rating_fromeel (porder);
+}
+
+static void
 rb_random_play_order_by_age_and_rating_init (RBRandomPlayOrderByAgeAndRating *porder)
 {
+	/* treblig: Not sure if the etiquette is to do this here or do it elsewhere in the shell
+	and pass it in? */
+	rb_random_play_order_by_age_and_rating_fromeel(porder);
+
+	/* Need to clean these out in a destructor */
+		eel_gconf_notification_add (CONF_RANDOM_RATING_BIAS,
+               	                             (GConfClientNotifyFunc) rb_random_play_order_by_age_and_rating_prefchange_cb,
+               	                             porder);
+		eel_gconf_notification_add (CONF_RANDOM_AGE_BIAS,
+               	                             (GConfClientNotifyFunc) rb_random_play_order_by_age_and_rating_prefchange_cb,
+               	                             porder);
+		eel_gconf_notification_add (CONF_RANDOM_VERY_RECENT_BIAS,
+               	                             (GConfClientNotifyFunc) rb_random_play_order_by_age_and_rating_prefchange_cb,
+               	                             porder);
+		eel_gconf_notification_add (CONF_RANDOM_VERY_RECENT_PERIOD,
+               	                             (GConfClientNotifyFunc) rb_random_play_order_by_age_and_rating_prefchange_cb,
+               	                             porder);
 }
 
 static double
@@ -77,6 +120,10 @@
 	gulong last_play;
 	gulong seconds_since_last_play;
 	gdouble rating;
+	double log_seconds_since_last_play;
+	double result;
+
+	RBRandomPlayOrderByAgeAndRating *us=RB_RANDOM_PLAY_ORDER_BY_AGE_AND_RATING (rorder);
 
 	/* This finds the log of the number of seconds since the last play.
 	 * It handles never played automatically, since now-0 is a valid
@@ -94,5 +141,18 @@
 	if (rating < 0.01)
 		rating = 2.5;
 
-	return log (seconds_since_last_play) * (rating + 1.0);
+	log_seconds_since_last_play=log (seconds_since_last_play);
+
+	/* Apply biases */
+	rating = pow((rating + 1.0),us->rating_bias);
+	log_seconds_since_last_play = pow(log_seconds_since_last_play , us->age_bias);
+
+	result = log_seconds_since_last_play * rating;
+
+	/* Now apply the very recent penalty - if it has been played within a set time then we scale
+	   the weight down again */
+	if (seconds_since_last_play < us->very_recent_period)
+		result = result / us->very_recent_bias;
+
+	return result;
 }
Binary files orig/rhythmbox-0.11.6svn20081008.orig/shell/.rb-play-order-random-by-age-and-rating.c.swo and rhythmbox-0.11.6svn20081008/shell/.rb-play-order-random-by-age-and-rating.c.swo differ
diff -urN orig/rhythmbox-0.11.6svn20081008.orig/shell/rb-play-order-random-by-age-and-rating.h rhythmbox-0.11.6svn20081008/shell/rb-play-order-random-by-age-and-rating.h
--- orig/rhythmbox-0.11.6svn20081008.orig/shell/rb-play-order-random-by-age-and-rating.h	2008-10-07 17:06:13.000000000 +0100
+++ rhythmbox-0.11.6svn20081008/shell/rb-play-order-random-by-age-and-rating.h	2008-11-02 17:57:05.000000000 +0000
@@ -46,6 +46,11 @@
 typedef struct
 {
 	RBRandomPlayOrder parent;
+
+	gdouble rating_bias;
+	gdouble age_bias;
+	gdouble very_recent_bias;
+	gdouble very_recent_period;
 } RBRandomPlayOrderByAgeAndRating;
 
 typedef struct
diff -urN orig/rhythmbox-0.11.6svn20081008.orig/shell/rb-play-order-random-by-age.c rhythmbox-0.11.6svn20081008/shell/rb-play-order-random-by-age.c
--- orig/rhythmbox-0.11.6svn20081008.orig/shell/rb-play-order-random-by-age.c	2008-10-07 17:06:13.000000000 +0100
+++ rhythmbox-0.11.6svn20081008/shell/rb-play-order-random-by-age.c	1970-01-01 01:00:00.000000000 +0100
@@ -1,89 +0,0 @@
-/*
- *  arch-tag: Implementation of random play order weighted by the time since last play
- *
- *  Copyright (C) 2003 Jeffrey Yasskin <jyasskin@mail.utexas.edu>
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  The Rhythmbox authors hereby grant permission for non-GPL compatible
- *  GStreamer plugins to be used and distributed together with GStreamer
- *  and Rhythmbox. This permission is above and beyond the permissions granted
- *  by the GPL license by which Rhythmbox is covered. If you modify this code
- *  you may extend this exception to your version of the code, but you are not
- *  obligated to do so. If you do not wish to do so, delete this exception
- *  statement from your version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA.
- *
- */
-
-#include "config.h"
-
-#include "rb-play-order-random-by-age.h"
-
-#include "rhythmdb.h"
-#include <time.h>
-#include <math.h>
-
-static void rb_random_play_order_by_age_class_init (RBRandomPlayOrderByAgeClass *klass);
-
-static double rb_random_by_age_get_entry_weight (RBRandomPlayOrder *rorder,
-						 RhythmDB *db, RhythmDBEntry *entry);
-
-G_DEFINE_TYPE (RBRandomPlayOrderByAge, rb_random_play_order_by_age, RB_TYPE_RANDOM_PLAY_ORDER)
-
-static void
-rb_random_play_order_by_age_class_init (RBRandomPlayOrderByAgeClass *klass)
-{
-	RBRandomPlayOrderClass *rorder;
-
-	rorder = RB_RANDOM_PLAY_ORDER_CLASS (klass);
-	rorder->get_entry_weight = rb_random_by_age_get_entry_weight;
-}
-
-RBPlayOrder *
-rb_random_play_order_by_age_new (RBShellPlayer *player)
-{
-	RBRandomPlayOrderByAge *rorder;
-
-	rorder = g_object_new (RB_TYPE_RANDOM_PLAY_ORDER_BY_AGE,
-			"player", player,
-			NULL);
-
-	return RB_PLAY_ORDER (rorder);
-}
-
-static void
-rb_random_play_order_by_age_init (RBRandomPlayOrderByAge *porder)
-{
-}
-
-static double
-rb_random_by_age_get_entry_weight (RBRandomPlayOrder *rorder, RhythmDB *db, RhythmDBEntry *entry)
-{
-	time_t now;
-	gulong last_play;
-	gulong seconds_since_last_play;
-
-	/* This returns the log of the number of seconds since the last play.
-	 * It handles never played automatically, since now-0 is a valid
-	 * argument to log(). */
-
-	time (&now);
-	last_play = rhythmdb_entry_get_ulong (entry, RHYTHMDB_PROP_LAST_PLAYED);
-	seconds_since_last_play = now - last_play;
-	/* The lowest weight should be 0. */
-	if (seconds_since_last_play < 1)
-		seconds_since_last_play = 1;
-	return log (seconds_since_last_play);
-}
diff -urN orig/rhythmbox-0.11.6svn20081008.orig/shell/rb-play-order-random-by-age.h rhythmbox-0.11.6svn20081008/shell/rb-play-order-random-by-age.h
--- orig/rhythmbox-0.11.6svn20081008.orig/shell/rb-play-order-random-by-age.h	2008-10-07 17:06:13.000000000 +0100
+++ rhythmbox-0.11.6svn20081008/shell/rb-play-order-random-by-age.h	1970-01-01 01:00:00.000000000 +0100
@@ -1,62 +0,0 @@
-/*
- *  arch-tag: Header for random play order weighted by the time since last play
- *
- *  Copyright (C) 2003 Jeffrey Yasskin <jyasskin@mail.utexas.edu>
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  The Rhythmbox authors hereby grant permission for non-GPL compatible
- *  GStreamer plugins to be used and distributed together with GStreamer
- *  and Rhythmbox. This permission is above and beyond the permissions granted
- *  by the GPL license by which Rhythmbox is covered. If you modify this code
- *  you may extend this exception to your version of the code, but you are not
- *  obligated to do so. If you do not wish to do so, delete this exception
- *  statement from your version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA.
- *
- */
-
-#ifndef __RB_PLAY_ORDER_RANDOM_BY_AGE_H
-#define __RB_PLAY_ORDER_RANDOM_BY_AGE_H
-
-#include "rb-play-order-random.h"
-
-#include "rb-shell-player.h"
-
-G_BEGIN_DECLS
-
-#define RB_TYPE_RANDOM_PLAY_ORDER_BY_AGE         (rb_random_play_order_by_age_get_type ())
-#define RB_RANDOM_PLAY_ORDER_BY_AGE(o)           (G_TYPE_CHECK_INSTANCE_CAST ((o), RB_TYPE_RANDOM_PLAY_ORDER_BY_AGE, RBRandomPlayOrderByAge))
-#define RB_RANDOM_PLAY_ORDER_BY_AGE_CLASS(k)     (G_TYPE_CHECK_CLASS_CAST ((k), RB_TYPE_RANDOM_PLAY_ORDER_BY_AGE, RBRandomPlayOrderByAgeClass))
-#define RB_IS_RANDOM_PLAY_ORDER_BY_AGE(o)        (G_TYPE_CHECK_INSTANCE_TYPE ((o), RB_TYPE_RANDOM_PLAY_ORDER_BY_AGE))
-#define RB_IS_RANDOM_PLAY_ORDER_BY_AGE_CLASS(k)  (G_TYPE_CHECK_CLASS_TYPE ((k), RB_TYPE_RANDOM_PLAY_ORDER_BY_AGE))
-#define RB_RANDOM_PLAY_ORDER_BY_AGE_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), RB_TYPE_RANDOM_PLAY_ORDER_BY_AGE, RBRandomPlayOrderByAgeClass))
-
-typedef struct
-{
-	RBRandomPlayOrder parent;
-} RBRandomPlayOrderByAge;
-
-typedef struct
-{
-	RBRandomPlayOrderClass parent_class;
-} RBRandomPlayOrderByAgeClass;
-
-GType					rb_random_play_order_by_age_get_type	(void);
-
-RBPlayOrder *				rb_random_play_order_by_age_new		(RBShellPlayer *player);
-
-G_END_DECLS
-
-#endif /* __RB_PLAY_ORDER_RANDOM_BY_AGE_H */
diff -urN orig/rhythmbox-0.11.6svn20081008.orig/shell/rb-play-order-random-by-rating.c rhythmbox-0.11.6svn20081008/shell/rb-play-order-random-by-rating.c
--- orig/rhythmbox-0.11.6svn20081008.orig/shell/rb-play-order-random-by-rating.c	2008-10-07 17:06:13.000000000 +0100
+++ rhythmbox-0.11.6svn20081008/shell/rb-play-order-random-by-rating.c	1970-01-01 01:00:00.000000000 +0100
@@ -1,81 +0,0 @@
-/*
- *  arch-tag: Implementation of random play order weighted by rating
- *
- *  Copyright (C) 2003 Jeffrey Yasskin <jyasskin@mail.utexas.edu>
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  The Rhythmbox authors hereby grant permission for non-GPL compatible
- *  GStreamer plugins to be used and distributed together with GStreamer
- *  and Rhythmbox. This permission is above and beyond the permissions granted
- *  by the GPL license by which Rhythmbox is covered. If you modify this code
- *  you may extend this exception to your version of the code, but you are not
- *  obligated to do so. If you do not wish to do so, delete this exception
- *  statement from your version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA.
- *
- */
-
-#include "config.h"
-
-#include "rb-play-order-random-by-rating.h"
-
-#include "rhythmdb.h"
-#include <time.h>
-#include <math.h>
-
-static void rb_random_play_order_by_rating_class_init (RBRandomPlayOrderByRatingClass *klass);
-
-static double rb_random_by_rating_get_entry_weight (RBRandomPlayOrder *rorder,
-						 RhythmDB *db, RhythmDBEntry *entry);
-
-G_DEFINE_TYPE (RBRandomPlayOrderByRating, rb_random_play_order_by_rating, RB_TYPE_RANDOM_PLAY_ORDER)
-
-static void
-rb_random_play_order_by_rating_class_init (RBRandomPlayOrderByRatingClass *klass)
-{
-	RBRandomPlayOrderClass *rorder;
-
-	rorder = RB_RANDOM_PLAY_ORDER_CLASS (klass);
-	rorder->get_entry_weight = rb_random_by_rating_get_entry_weight;
-}
-
-RBPlayOrder *
-rb_random_play_order_by_rating_new (RBShellPlayer *player)
-{
-	RBRandomPlayOrderByRating *rorder;
-
-	rorder = g_object_new (RB_TYPE_RANDOM_PLAY_ORDER_BY_RATING,
-			"player", player,
-			NULL);
-
-	return RB_PLAY_ORDER (rorder);
-}
-
-static void
-rb_random_play_order_by_rating_init (RBRandomPlayOrderByRating *porder)
-{
-}
-
-static double
-rb_random_by_rating_get_entry_weight (RBRandomPlayOrder *rorder, RhythmDB *db, RhythmDBEntry *entry)
-{
-	double rating;
-
-	rating = rhythmdb_entry_get_double (entry, RHYTHMDB_PROP_RATING);
-	if (rating < 0.01)
-		rating = 2.5;
-
-	return rating;
-}
diff -urN orig/rhythmbox-0.11.6svn20081008.orig/shell/rb-play-order-random-by-rating.h rhythmbox-0.11.6svn20081008/shell/rb-play-order-random-by-rating.h
--- orig/rhythmbox-0.11.6svn20081008.orig/shell/rb-play-order-random-by-rating.h	2008-10-07 17:06:13.000000000 +0100
+++ rhythmbox-0.11.6svn20081008/shell/rb-play-order-random-by-rating.h	1970-01-01 01:00:00.000000000 +0100
@@ -1,62 +0,0 @@
-/*
- *  arch-tag: Header for random play order weighted by rating
- *
- *  Copyright (C) 2003 Jeffrey Yasskin <jyasskin@mail.utexas.edu>
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  The Rhythmbox authors hereby grant permission for non-GPL compatible
- *  GStreamer plugins to be used and distributed together with GStreamer
- *  and Rhythmbox. This permission is above and beyond the permissions granted
- *  by the GPL license by which Rhythmbox is covered. If you modify this code
- *  you may extend this exception to your version of the code, but you are not
- *  obligated to do so. If you do not wish to do so, delete this exception
- *  statement from your version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA.
- *
- */
-
-#ifndef __RB_PLAY_ORDER_RANDOM_BY_RATING_H
-#define __RB_PLAY_ORDER_RANDOM_BY_RATING_H
-
-#include "rb-play-order-random.h"
-
-#include "rb-shell-player.h"
-
-G_BEGIN_DECLS
-
-#define RB_TYPE_RANDOM_PLAY_ORDER_BY_RATING         (rb_random_play_order_by_rating_get_type ())
-#define RB_RANDOM_PLAY_ORDER_BY_RATING(o)           (G_TYPE_CHECK_INSTANCE_CAST ((o), RB_TYPE_RANDOM_PLAY_ORDER_BY_RATING, RBRandomPlayOrderByRating))
-#define RB_RANDOM_PLAY_ORDER_BY_RATING_CLASS(k)     (G_TYPE_CHECK_CLASS_CAST ((k), RB_TYPE_RANDOM_PLAY_ORDER_BY_RATING, RBRandomPlayOrderByRatingClass))
-#define RB_IS_RANDOM_PLAY_ORDER_BY_RATING(o)        (G_TYPE_CHECK_INSTANCE_TYPE ((o), RB_TYPE_RANDOM_PLAY_ORDER_BY_RATING))
-#define RB_IS_RANDOM_PLAY_ORDER_BY_RATING_CLASS(k)  (G_TYPE_CHECK_CLASS_TYPE ((k), RB_TYPE_RANDOM_PLAY_ORDER_BY_RATING))
-#define RB_RANDOM_PLAY_ORDER_BY_RATING_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), RB_TYPE_RANDOM_PLAY_ORDER_BY_RATING, RBRandomPlayOrderByRatingClass))
-
-typedef struct
-{
-	RBRandomPlayOrder parent;
-} RBRandomPlayOrderByRating;
-
-typedef struct
-{
-	RBRandomPlayOrderClass parent_class;
-} RBRandomPlayOrderByRatingClass;
-
-GType					rb_random_play_order_by_rating_get_type	(void);
-
-RBPlayOrder *				rb_random_play_order_by_rating_new		(RBShellPlayer *player);
-
-G_END_DECLS
-
-#endif /* __RB_PLAY_ORDER_RANDOM_BY_RATING_H */
diff -urN orig/rhythmbox-0.11.6svn20081008.orig/shell/rb-play-order-random.c rhythmbox-0.11.6svn20081008/shell/rb-play-order-random.c
--- orig/rhythmbox-0.11.6svn20081008.orig/shell/rb-play-order-random.c	2008-10-07 17:06:13.000000000 +0100
+++ rhythmbox-0.11.6svn20081008/shell/rb-play-order-random.c	2008-11-02 17:57:09.000000000 +0000
@@ -45,11 +45,10 @@
 
 #include <string.h>
 
-#include "rb-play-order-random-by-age.h"
-
 #include "rb-debug.h"
 #include "rhythmdb.h"
 #include "rb-history.h"
+#include "rb-play-order-random.h"
 
 static void rb_random_play_order_class_init (RBRandomPlayOrderClass *klass);
 static void rb_random_play_order_init (RBRandomPlayOrder *rorder);
diff -urN orig/rhythmbox-0.11.6svn20081008.orig/shell/rb-shell-player.c rhythmbox-0.11.6svn20081008/shell/rb-shell-player.c
--- orig/rhythmbox-0.11.6svn20081008.orig/shell/rb-shell-player.c	2008-10-07 17:06:13.000000000 +0100
+++ rhythmbox-0.11.6svn20081008/shell/rb-shell-player.c	2008-11-02 17:57:10.000000000 +0000
@@ -93,9 +93,6 @@
 #include "rb-play-order-linear.h"
 #include "rb-play-order-linear-loop.h"
 #include "rb-play-order-shuffle.h"
-#include "rb-play-order-random-equal-weights.h"
-#include "rb-play-order-random-by-age.h"
-#include "rb-play-order-random-by-rating.h"
 #include "rb-play-order-random-by-age-and-rating.h"
 #include "rb-play-order-queue.h"
 
@@ -181,6 +178,8 @@
 							GConfEntry *entry, RBShellPlayer *player);
 static void gconf_network_buffer_size_changed (GConfClient *client, guint cnxn_id,
 					       GConfEntry *entry, RBShellPlayer *player);
+static void gconf_shuffle_button_behaviour_changed (GConfClient *client, guint cnxn_id,
+						    GConfEntry *entry, RBShellPlayer *player);
 static void rb_shell_player_playing_changed_cb (RBShellPlayer *player,
 						GParamSpec *arg1,
 						gpointer user_data);
@@ -259,6 +258,7 @@
 
 	RBPlayOrder *play_order;
 	RBPlayOrder *queue_play_order;
+	gint shuffle_button_behaviour; /* as per CONF_RANDOM_SHUFFLE_BEHAVIOUR_INDEX_* */
 
 	GQueue *playlist_urls;
 
@@ -270,6 +270,7 @@
 	guint gconf_track_transition_time_id;
 	guint gconf_track_transition_album_check_id;
 	guint gconf_network_buffer_size_id;
+	guint gconf_shuffle_button_behaviour_id;
 
 	gboolean mute;
 	float volume;
@@ -954,12 +955,6 @@
 					RB_TYPE_LINEAR_PLAY_ORDER_LOOP, FALSE);
 	rb_shell_player_add_play_order (player, "shuffle", N_("Shuffle"),
 					RB_TYPE_SHUFFLE_PLAY_ORDER, FALSE);
-	rb_shell_player_add_play_order (player, "random-equal-weights", N_("Random with equal weights"),
-					RB_TYPE_RANDOM_PLAY_ORDER_EQUAL_WEIGHTS, FALSE);
-	rb_shell_player_add_play_order (player, "random-by-age", N_("Random by time since last play"),
-					RB_TYPE_RANDOM_PLAY_ORDER_BY_AGE, FALSE);
-	rb_shell_player_add_play_order (player, "random-by-rating", N_("Random by rating"),
-					RB_TYPE_RANDOM_PLAY_ORDER_BY_RATING, FALSE);
 	rb_shell_player_add_play_order (player, "random-by-age-and-rating", N_("Random by time since last play and rating"),
 					RB_TYPE_RANDOM_PLAY_ORDER_BY_AGE_AND_RATING, FALSE);
 	rb_shell_player_add_play_order (player, "queue", N_("Linear, removing entries once played"),
@@ -1021,6 +1016,11 @@
 					    player);
 
 	player->priv->volume = eel_gconf_get_float (CONF_STATE_VOLUME);
+	player->priv->shuffle_button_behaviour = eel_gconf_get_integer (CONF_RANDOM_SHUFFLE_BEHAVIOUR);
+	player->priv->gconf_shuffle_button_behaviour_id =
+		eel_gconf_notification_add (CONF_RANDOM_SHUFFLE_BEHAVIOUR,
+					    (GConfClientNotifyFunc)gconf_shuffle_button_behaviour_changed,
+					    player);
 
 	player->priv->track_transition_time = (int)(eel_gconf_get_float (CONF_PLAYER_TRANSITION_TIME));
 	player->priv->track_transition_album_check = eel_gconf_get_boolean (CONF_PLAYER_TRANSITION_ALBUM_CHECK);
@@ -1827,6 +1827,24 @@
 	g_free (old_val);
 }
 
+static const char*
+rb_shell_player_get_order_from_flags (RBShellPlayer *player,
+                                    gboolean shuffle,
+                                    gboolean repeat)
+{
+	/* This behaviour isn't right yet - I don't think we should special case this,
+	  I think we should just kill off the shuffle && repeat  combo so that shuffle
+	  being true always does what the pref says */
+	if (shuffle  && !repeat) {
+		if (player->priv->shuffle_button_behaviour == CONF_RANDOM_SHUFFLE_BEHAVIOUR_INDEX_SHUFFLE)
+			return "shuffle";
+		else
+			return "random-by-age-and-rating";
+	}
+
+	return state_to_play_order[shuffle ? 1 : 0][repeat ? 1 : 0];
+}
+
 /**
  * rb_shell_player_set_playback_state:
  * @player: the #RBShellPlayer
@@ -1840,8 +1858,7 @@
 				    gboolean shuffle,
 				    gboolean repeat)
 {
-	const char *neworder = state_to_play_order[shuffle ? 1 : 0][repeat ? 1 : 0];
-	rb_shell_player_set_play_order (player, neworder);
+	rb_shell_player_set_play_order (player, rb_shell_player_get_order_from_flags(player, shuffle, repeat));
 }
 
 static void
@@ -2653,7 +2670,7 @@
 	rb_shell_player_get_playback_state (player, &shuffle, &repeat);
 
 	shuffle = !shuffle;
-	neworder = state_to_play_order[shuffle ? 1 : 0][repeat ? 1 : 0];
+	neworder = rb_shell_player_get_order_from_flags(player, shuffle, repeat);
 	rb_shell_player_set_play_order (player, neworder);
 }
 
@@ -2672,7 +2689,7 @@
 	rb_shell_player_get_playback_state (player, &shuffle, &repeat);
 
 	repeat = !repeat;
-	neworder = state_to_play_order[shuffle ? 1 : 0][repeat ? 1 : 0];
+	neworder = rb_shell_player_get_order_from_flags(player, shuffle, repeat);
 	rb_shell_player_set_play_order (player, neworder);
 }
 
@@ -3866,6 +3883,14 @@
 }
 
 static void
+gconf_shuffle_button_behaviour_changed (GConfClient *client, guint cnxn_id,
+				        GConfEntry *entry, RBShellPlayer *player)
+{
+	/* Should we actually sync the play button now? */
+	player->priv->shuffle_button_behaviour = eel_gconf_get_integer (CONF_RANDOM_SHUFFLE_BEHAVIOUR);
+}
+
+static void
 gconf_network_buffer_size_changed (GConfClient *client,
 				   guint cnxn_id,
 				   GConfEntry *entry,
diff -urN orig/rhythmbox-0.11.6svn20081008.orig/shell/rb-shell-preferences.c rhythmbox-0.11.6svn20081008/shell/rb-shell-preferences.c
--- orig/rhythmbox-0.11.6svn20081008.orig/shell/rb-shell-preferences.c	2008-10-07 17:06:13.000000000 +0100
+++ rhythmbox-0.11.6svn20081008/shell/rb-shell-preferences.c	2008-11-02 18:33:07.000000000 +0000
@@ -100,6 +100,17 @@
 							 RBShellPreferences *preferences);
 static void update_playback_prefs_sensitivity (RBShellPreferences *preferences);
 
+void rb_shell_preferences_random_shuffle_behaviour_activated_cb (GtkWidget *widget,
+						      RBShellPreferences *shell_preferences);
+static void rb_shell_preferences_random_rating_bias_changed_cb (GtkRange *range,
+							 RBShellPreferences *preferences);
+static void rb_shell_preferences_random_age_bias_changed_cb (GtkRange *range,
+							 RBShellPreferences *preferences);
+static void rb_shell_preferences_very_recent_play_bias_changed_cb (GtkRange *range,
+							 RBShellPreferences *preferences);
+static void rb_shell_preferences_very_recent_play_period_changed_cb (GtkRange *range,
+							 RBShellPreferences *preferences);
+
 enum
 {
 	PROP_0,
@@ -130,6 +141,13 @@
 	GtkWidget *transition_duration;
 	GtkWidget *network_buffer_size;
 
+        /* Random settings pane */
+	GSList *shuffle_button_behaviour_group;
+	GtkWidget *random_rating_bias;
+	GtkWidget *random_age_bias;
+	GtkWidget *random_veryrecentplay_bias;
+	GtkWidget *random_veryrecentplay_period;
+
 	GSList *browser_views_group;
 
 	GtkWidget *toolbar_style_menu;
@@ -324,6 +342,58 @@
 				    (GConfClientNotifyFunc) rb_shell_preferences_ui_pref_changed,
 				    shell_preferences);
 
+        /* random playback preferences */
+        xml = rb_glade_xml_new ("random-prefs.glade",
+                                "random_table",
+                                shell_preferences);
+	rb_glade_boldify_label (xml, "shuffle_behaviour_label");
+	rb_glade_boldify_label (xml, "rating_bias_label");
+	rb_glade_boldify_label (xml, "age_bias_label");
+	rb_glade_boldify_label (xml, "veryrecentplay_bias_label");
+	rb_glade_boldify_label (xml, "veryrecentplay_period_label");
+
+	tmp = glade_xml_get_widget (xml, "shuffle_button_radio_shuffle");
+  	shell_preferences->priv->shuffle_button_behaviour_group =
+  		g_slist_reverse (g_slist_copy (gtk_radio_button_get_group
+  					       (GTK_RADIO_BUTTON (tmp))));
+  
+  	shell_preferences->priv->random_rating_bias =
+  		glade_xml_get_widget (xml, "rating_bias_scale");
+  	g_signal_connect_object (shell_preferences->priv->random_rating_bias,
+  				 "value-changed",
+  				 G_CALLBACK (rb_shell_preferences_random_rating_bias_changed_cb),
+  				 shell_preferences, 0);
+  
+  	shell_preferences->priv->random_age_bias =
+  		glade_xml_get_widget (xml, "age_bias_scale");
+  	g_signal_connect_object (shell_preferences->priv->random_age_bias,
+  				 "value-changed",
+  				 G_CALLBACK (rb_shell_preferences_random_age_bias_changed_cb),
+  				 shell_preferences, 0);
+  
+  	shell_preferences->priv->random_veryrecentplay_bias =
+  		glade_xml_get_widget (xml, "veryrecentplay_bias_scale");
+  	g_signal_connect_object (shell_preferences->priv->random_veryrecentplay_bias,
+  				 "value-changed",
+  				 G_CALLBACK (rb_shell_preferences_very_recent_play_bias_changed_cb),
+  				 shell_preferences, 0);
+  
+  	shell_preferences->priv->random_veryrecentplay_period =
+ 		glade_xml_get_widget (xml, "veryrecentplay_period_scale");
+ 	g_signal_connect_object (shell_preferences->priv->random_veryrecentplay_period,
+ 				 "value-changed",
+ 				 G_CALLBACK (rb_shell_preferences_very_recent_play_period_changed_cb),
+ 				 shell_preferences, 0);
+ 
+ 
+ 	gtk_notebook_append_page (GTK_NOTEBOOK (shell_preferences->priv->notebook),
+ 				  glade_xml_get_widget (xml, "random_table"),
+ 				  gtk_label_new (_("Random")));
+ 	g_object_unref (xml);
+ 	eel_gconf_notification_add (CONF_RANDOM_DIR,
+ 				    (GConfClientNotifyFunc) rb_shell_preferences_ui_pref_changed,
+ 				    shell_preferences);
+ 
 	rb_shell_preferences_sync (shell_preferences);
 }
 
@@ -538,7 +608,8 @@
 {
 	char *columns;
 	GSList  *l;
-	gint view, i;
+	gint view, i, behaviour;
+	gdouble d;
 	gboolean b;
 	float duration;
 	int buffer_size;
@@ -624,6 +695,22 @@
 
 	update_playback_prefs_sensitivity (shell_preferences);
 
+        /* random behaviour pane */
+        d = eel_gconf_get_float (CONF_RANDOM_RATING_BIAS);
+        gtk_range_set_value (GTK_RANGE (shell_preferences->priv->random_rating_bias), d);
+        d = eel_gconf_get_float (CONF_RANDOM_AGE_BIAS);
+        gtk_range_set_value (GTK_RANGE (shell_preferences->priv->random_age_bias), d);
+        d = eel_gconf_get_float (CONF_RANDOM_VERY_RECENT_BIAS);
+        gtk_range_set_value (GTK_RANGE (shell_preferences->priv->random_veryrecentplay_bias), d);
+        d = eel_gconf_get_float (CONF_RANDOM_VERY_RECENT_PERIOD);
+        gtk_range_set_value (GTK_RANGE (shell_preferences->priv->random_veryrecentplay_period), d);
+
+	behaviour = eel_gconf_get_integer (CONF_RANDOM_SHUFFLE_BEHAVIOUR);
+	for (l = shell_preferences->priv->shuffle_button_behaviour_group, i = 0; l != NULL; l = g_slist_next (l), i++)
+		gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (l->data), (i == behaviour));
+
+        /* Do something to get these prefs into the actual random code! */
+
 	shell_preferences->priv->loading = FALSE;
 }
 
@@ -716,3 +803,57 @@
 	eel_gconf_set_integer (CONF_PLAYER_NETWORK_BUFFER_SIZE, (int)v);
 }
 
+void
+rb_shell_preferences_random_shuffle_behaviour_activated_cb (GtkWidget *widget,
+						 RBShellPreferences *shell_preferences)
+{
+	int index;
+
+	if (shell_preferences->priv->loading)
+		return;
+
+	index = g_slist_index (shell_preferences->priv->shuffle_button_behaviour_group, widget);
+
+	eel_gconf_set_integer (CONF_RANDOM_SHUFFLE_BEHAVIOUR, index);
+}
+
+static void
+rb_shell_preferences_random_rating_bias_changed_cb (GtkRange *range,
+							 RBShellPreferences *preferences)
+{
+	gdouble v;
+
+	v = gtk_range_get_value (range);
+	eel_gconf_set_float (CONF_RANDOM_RATING_BIAS, (float)v);
+}
+
+static void
+rb_shell_preferences_random_age_bias_changed_cb (GtkRange *range,
+							 RBShellPreferences *preferences)
+{
+	gdouble v;
+
+	v = gtk_range_get_value (range);
+	eel_gconf_set_float (CONF_RANDOM_AGE_BIAS, (float)v);
+}
+
+static void
+rb_shell_preferences_very_recent_play_bias_changed_cb (GtkRange *range,
+							 RBShellPreferences *preferences)
+{
+	gdouble v;
+
+	v = gtk_range_get_value (range);
+	eel_gconf_set_float (CONF_RANDOM_VERY_RECENT_BIAS, (float)v);
+}
+
+static void
+rb_shell_preferences_very_recent_play_period_changed_cb (GtkRange *range,
+							 RBShellPreferences *preferences)
+{
+	gdouble v;
+
+	v = gtk_range_get_value (range);
+	eel_gconf_set_float (CONF_RANDOM_VERY_RECENT_PERIOD, (float)v);
+}
+
