Index: /extensions/Back2Front/Back2Front.php
===================================================================
--- /extensions/Back2Front/Back2Front.php	(revision 10820)
+++ /extensions/Back2Front/Back2Front.php	(revision 10821)
@@ -62,5 +62,6 @@
 function Back2Front_picture_modify()
 {
-  global $page, $template;
+  global $page, $template, $conf;
+  $conf['back2front'] = explode(',',$conf['back2front']);
   
   if ($page['page'] == 'picture_modify')
@@ -75,27 +76,45 @@
         if (picture_exists($_POST['b2f_front_id']))
         {
-          $query = "
-            INSERT INTO ".B2F_TABLE."
-            VALUES(".$_POST['b2f_front_id'].", ".$_GET['image_id'].", ".$_POST['b2f_old_level'].")
-            ON DUPLICATE KEY UPDATE image_id = ".$_POST['b2f_front_id'].", old_level = ".$_POST['b2f_old_level']."
-          ;";
-          pwg_query($query);
-          
-          $query = "
-            UPDATE ".IMAGES_TABLE."
-            SET level = 99
-            WHERE id = ".$_GET['image_id']."
-          ;";
-          pwg_query($query);
-          
-          $template->assign(array(
-            'B2F_IS_VERSO' => 'checked="checked"',
-            'B2F_FRONT_ID' => $_POST['b2f_front_id'],
-            'B2F_OLD_LEVEL' => $_POST['b2f_old_level'],
-          ));
+          /* search if recto has already a verso */
+          $query = "SELECT verso_id
+            FROM ".B2F_TABLE."
+            WHERE image_id = ".$_POST['b2f_front_id'].";";
+          $result = pwg_query($query);
+          list($recto_current_verso['id']) = pwg_db_fetch_row($result);
+          
+          if (pwg_db_num_rows($result) AND $recto_current_verso['id'] != $_GET['image_id'])
+          {
+            $recto_current_verso['link'] = get_root_url().'admin.php?page=picture_modify&amp;cat_id=&amp;image_id='.$recto_current_verso['id'];
+            $template->append('errors', l10n('This picture has already a backside : ').'<a href="'.$recto_current_verso['link'].'">'.$recto_current_verso['id'].'</a>');
+          }
+          /* recto is clean */
+          else
+          {
+            $verso_categories = implode(',',array_keys($template->get_template_vars('associated_options')));
+            pwg_query("INSERT INTO ".B2F_TABLE."
+              VALUES(".$_POST['b2f_front_id'].", ".$_GET['image_id'].", '".$verso_categories."')
+              ON DUPLICATE KEY UPDATE image_id = ".$_POST['b2f_front_id'].";");
+            
+            /* move the verso ? */
+            if (isset($_POST['b2f_move_verso']))
+            {
+              pwg_query("DELETE FROM ".IMAGE_CATEGORY_TABLE."
+                WHERE image_id = ".$_GET['image_id'].";");
+                
+              pwg_query("INSERT INTO ".IMAGE_CATEGORY_TABLE."
+                VALUES(".$_GET['image_id'].", ".$conf['back2front'][0].", NULL);");
+            }
+          
+            $template->assign(array(
+              'B2F_IS_VERSO' => 'checked="checked"',
+              'B2F_FRONT_ID' => $_POST['b2f_front_id'],
+            ));
+            
+            $template->append('infos', l10n('This picture is now the backside of the picture n° ').$_POST['b2f_front_id']);
+          }
         }
         else
         {
-          $template->assign('errors', l10n('Unknown id for frontside picture'));
+          $template->append('errors', l10n('Unknown id for frontside picture : ').$_POST['b2f_front_id']);
         }
       }
@@ -103,20 +122,49 @@
       else
       {
-        $query = "
-          DELETE FROM ".B2F_TABLE." 
-          WHERE verso_id = ".$_GET['image_id']."
-        ;";
-        pwg_query($query);
+        /* search if it was a verso */
+        $query = "SELECT categories
+          FROM ".B2F_TABLE."
+          WHERE verso_id = ".$_GET['image_id'].";";
+        $result = pwg_query($query);
         
-        $query = "
-          UPDATE ".IMAGES_TABLE."
-          SET level = ".$_POST['b2f_old_level']."
-          WHERE id = ".$_GET['image_id']."
-        ;";
-        pwg_query($query);
-        
-        $template->assign(array(
-          'level_options_selected' => array($_POST['b2f_old_level']),
-        ));
+        /* it must be restored to its original categories (see criteria on maintain.inc) */
+        if (pwg_db_num_rows($result))
+        {
+          /* original categories */
+          list($item['categories']) = pwg_db_fetch_row($result);
+          /* catch current categories */
+          $versos_infos = pwg_query("SELECT category_id FROM ".IMAGE_CATEGORY_TABLE." WHERE image_id = ".$_GET['image_id'].";");
+          while (list($verso_cat) = pwg_db_fetch_row($versos_infos))
+          {
+            $current_verso_cats[] = $verso_cat;
+          }
+          /* if verso € 'versos' cat only */
+          if (count($current_verso_cats) == 1 AND $current_verso_cats[0] == $conf['back2front'][0])
+          {
+            foreach (explode(',',$item['categories']) as $cat)
+            {
+              $datas[] = array(
+                'image_id' => $_GET['image_id'],
+                'category_id' => $cat,
+                );
+            }
+            if (isset($datas))
+            {
+              mass_inserts(
+                IMAGE_CATEGORY_TABLE,
+                array('image_id', 'category_id'),
+                $datas
+                );
+            }
+          }
+          
+          pwg_query("DELETE FROM ".IMAGE_CATEGORY_TABLE."
+            WHERE image_id = ".$_GET['image_id']." AND category_id = ".$conf['back2front'][0].";");
+          
+          pwg_query("DELETE FROM ".B2F_TABLE." 
+            WHERE verso_id = ".$_GET['image_id'].";");
+            
+          $template->append('infos', l10n('This picture is no longer a backside'));
+        }
       }
     }
@@ -126,5 +174,5 @@
       /* is the pisture a verso ? */
       $query = "
-        SELECT image_id, old_level
+        SELECT image_id
         FROM ".B2F_TABLE."
         WHERE verso_id = ".$_GET['image_id']."
@@ -134,9 +182,8 @@
       if (pwg_db_num_rows($result))
       {
-        $item = pwg_db_fetch_assoc($result);
+        list($recto_id) = pwg_db_fetch_row($result);
         $template->assign(array(
           'B2F_IS_VERSO' => 'checked="checked"',
-          'B2F_FRONT_ID' => $item['image_id'],
-          'B2F_OLD_LEVEL' => $item['old_level'],
+          'B2F_FRONT_ID' => $recto_id,
         ));
       }
@@ -144,9 +191,7 @@
       else
       {
-        $query = "
-          SELECT verso_id
+        $query = "SELECT verso_id
           FROM ".B2F_TABLE."
-          WHERE image_id = ".$_GET['image_id']."
-        ;";
+          WHERE image_id = ".$_GET['image_id'].";";
         $result = pwg_query($query);
         
@@ -156,9 +201,7 @@
           
           $item = pwg_db_fetch_assoc($result);
-          $query = "
-            SELECT id, name, file
+          $query = "SELECT id, name, file
             FROM ".IMAGES_TABLE."
-            WHERE id = ".$item['verso_id']."
-          ;";
+            WHERE id = ".$item['verso_id'].";";
           $item = pwg_db_fetch_assoc(pwg_query($query));
           
@@ -188,28 +231,3 @@
 }
 
-
-$versos = null; // needs to be declared outside any function for the array_filter callback ?!
-/*
- * Change/remove navigation thumbnails
- */
-function Back2Front_items()
-{
-  global $template, $page, $versos;
-  
-  /* search all verso ids */
-  $query = "
-    SELECT verso_id as id
-    FROM ".B2F_TABLE."
-  ;";
-  $versos = array_values(array_from_query($query, 'id'));
-  
-  /* output */
-  function remove_versos($item)
-  {
-    global $versos;
-    return !in_array($item, $versos);
-  }
-  $page['items'] = array_values(array_filter($page['items'], 'remove_versos'));
-}
-
 ?>
Index: /extensions/Back2Front/language/en_UK/plugin.lang.php
===================================================================
--- /extensions/Back2Front/language/en_UK/plugin.lang.php	(revision 10820)
+++ /extensions/Back2Front/language/en_UK/plugin.lang.php	(revision 10821)
@@ -3,11 +3,15 @@
 $lang['See back'] = 'See back';
 $lang['See front'] = 'See front';
-$lang['Unknown id for frontside picture'] = 'Unknown id for frontside picture';
-$lang['Nobody (backside)'] = 'Nobody (backside)';
-$lang['Level 99'] = 'Backside';
+
 $lang['This picture is a backside...'] = 'This picture is a backside...';
 $lang['...of the picture n°'] = '...of the picture n°';
 $lang['Backside management'] = 'Backside management';
-$lang['This picture has a backside :'] = 'This picture has a backside :';
+$lang['Move backside to private album'] = 'Move backside to private album';
+$lang['This picture has a backside : '] = 'This picture has a backside : ';
+
+$lang['This picture has already a backside : '] = 'This picture has already a backside : ';
+$lang['This picture is now the backside of the picture n° '] = 'This picture is now the backside of the picture n° ';
+$lang['Unknown id for frontside picture : '] = 'Unknown id for frontside picture : ';
+$lang['This picture is no longer a backside'] = 'This picture is no longer a backside';
 
 ?>
Index: /extensions/Back2Front/language/fr_FR/plugin.lang.php
===================================================================
--- /extensions/Back2Front/language/fr_FR/plugin.lang.php	(revision 10820)
+++ /extensions/Back2Front/language/fr_FR/plugin.lang.php	(revision 10821)
@@ -3,11 +3,15 @@
 $lang['See back'] = 'Voir le verso';
 $lang['See front'] = 'Voir le recto';
-$lang['Unknown id for frontside picture'] = 'id inconnu pour le recto';
-$lang['Nobody (backside)'] = 'Personne (verso)';
-$lang['Level 99'] = 'Verso';
+
 $lang['This picture is a backside...'] = 'Cette image est le verso...';
-$lang['...of the picture n°'] = "...de l'image n°";
-$lang['Backside management'] = 'Gestion recto/verso';
-$lang['This picture has a backside :'] = 'Cette image a un verso :';
+$lang['...of the picture n°'] = '...de l\'image n°';
+$lang['Backside management'] = 'Gestion des recto-verso';
+$lang['Move backside to private album'] = 'Déplacer le verso vers un album privé';
+$lang['This picture has a backside : '] = 'Cette image a un verso : ';
+
+$lang['This picture has already a backside : '] = 'Cette image a déjà un verso : ';
+$lang['This picture is now the backside of the picture n° '] = 'Cette image est maintenant le verso de l\'image n° ';
+$lang['Unknown id for frontside picture : '] = 'Id inconnu pour le recto : ';
+$lang['This picture is no longer a backside'] = 'Cette image n\'est plus un verso';
 
 ?>
Index: /extensions/Back2Front/main.inc.php
===================================================================
--- /extensions/Back2Front/main.inc.php	(revision 10820)
+++ /extensions/Back2Front/main.inc.php	(revision 10821)
@@ -20,16 +20,5 @@
 
 add_event_handler('render_element_content', 'Back2Front_picture_content', 99, 2);
-//add_event_handler('loc_end_section_init', 'Back2Front_items');
 add_event_handler('loc_end_admin', 'Back2Front_picture_modify');
 
-
-/* 	add_event_handler('get_admin_plugin_menu_links', 'Front2Back_admin_menu');
-	function Front2Back_admin_menu($menu) 
-	{
-		array_push($menu, array(
-			'NAME' => 'Front2Back',
-			'URL' => get_root_url().'admin.php?page=plugin-' . B2F_DIR));
-		return $menu;
-	} */
-
 ?>
Index: /extensions/Back2Front/maintain.inc.php
===================================================================
--- /extensions/Back2Front/maintain.inc.php	(revision 10820)
+++ /extensions/Back2Front/maintain.inc.php	(revision 10821)
@@ -5,28 +5,91 @@
 	global $prefixeTable;
 
-	pwg_query("CREATE TABLE `" . $prefixeTable . "image_verso` (
+  /* create table for recto/veros pairs | stores original verso categories */
+	pwg_query("CREATE TABLE IF NOT EXISTS `" . $prefixeTable . "image_verso` (
     `image_id` mediumint(8) unsigned NOT NULL DEFAULT '0',
-    `verso_id` smallint(8) unsigned NOT NULL DEFAULT '0',
-    `old_level` tinyint unsigned NOT NULL DEFAULT '0',
-    PRIMARY KEY (`image_id`,`verso_id`)
+    `verso_id` mediumint(8) unsigned NOT NULL DEFAULT '0',
+    `categories` varchar(128) NULL,
+    PRIMARY KEY (`image_id`),
+    UNIQUE KEY (`verso_id`)
 	) DEFAULT CHARSET=utf8;");
-}
-
-function plugin_activate(){
-	global $conf, $prefixeTable;
-
+  
+  /* create a virtual category to store versos */
+  $versos_cat = create_virtual_category('Back2Front private album');
+  $versos_cat = array(
+    'id' => $versos_cat['id'],
+    'comment' => 'Used by Back2Front to store backsides.',
+    'status'  => 'private',
+    'visible' => 'false',
+    'commentable' => 'false',
+    );
+  mass_updates(
+    CATEGORIES_TABLE,
+    array(
+      'primary' => array('id'),
+      'update' => array_diff(array_keys($versos_cat), array('id'))
+      ),
+    array($versos_cat)
+    );
+    
+  /* config parameter */
+  pwg_query("INSERT INTO `" . CONFIG_TABLE . "`
+    VALUES ('back2front', '".$versos_cat['id']."', 'Configuration for Back2Front plugin');");
 }
 
 function plugin_uninstall() {
-	global $prefixeTable;
+	global $conf, $prefixeTable;
+  
+  $conf['back2front'] = explode(',',$conf['back2front']);
+  
+  /* versos must be restored to their original categories
+   criterias :
+    - verso  'versos' cat only => restore verso to original categories
+    - otherwise nothing is changed
+  */
 
   $query = "SELECT * FROM `" . $prefixeTable . "image_verso`;";
-  $result = pwg_query($query);
-  while ($item = pwg_db_fetch_assoc($result))
+  $images_versos = pwg_query($query);
+  
+  while ($item = pwg_db_fetch_assoc($images_versos))
   {
-    pwg_query("UPDATE ".IMAGES_TABLE." SET level = ".$item['old_level']." WHERE id = ".$item['verso_id'].";");
+    /* catch current verso categories */
+    $versos_infos = pwg_query("SELECT category_id FROM ".IMAGE_CATEGORY_TABLE." WHERE image_id = ".$item['verso_id'].";");
+    while (list($verso_cat) = pwg_db_fetch_row($versos_infos))
+    {
+      $item['current_verso_cats'][] = $verso_cat;
+    }
+    
+    /* if verso  'versos' cat only */
+    if (count($item['current_verso_cats']) == 1 AND $item['current_verso_cats'][0] == $conf['back2front'][0])
+    {
+      foreach (explode(',',$item['categories']) as $cat)
+      {
+        $datas[] = array(
+          'image_id' => $item['verso_id'],
+          'category_id' => $cat,
+          );
+      }
+    }
+    
+    pwg_query("DELETE FROM ".IMAGE_CATEGORY_TABLE."
+      WHERE image_id = ".$item['verso_id']." AND category_id = ".$conf['back2front'][0].";");
   }
   
+  if (isset($datas))
+  {
+    mass_inserts(
+      IMAGE_CATEGORY_TABLE,
+      array('image_id', 'category_id'),
+      $datas
+      );
+  }
+
 	pwg_query("DROP TABLE `" . $prefixeTable . "image_verso`;");
+  pwg_query("DELETE FROM `" . CONFIG_TABLE . "` WHERE param = 'back2front';");
+  pwg_query("DELETE FROM `" . CATEGORIES_TABLE ."`WHERE id = ".$conf['back2front'][0].";");
+  
+  /* rebuild categories cache */
+  include_once(PHPWG_ROOT_PATH.'admin/include/functions.php');
+  invalidate_user_cache(true);
 }
 ?>
Index: /extensions/Back2Front/template/picture_content.tpl
===================================================================
--- /extensions/Back2Front/template/picture_content.tpl	(revision 10820)
+++ /extensions/Back2Front/template/picture_content.tpl	(revision 10821)
@@ -2,43 +2,45 @@
 
 {footer_script require="jquery"}
-	jQuery('.reverse').click(function() {ldelim}
-		if (jQuery(this).attr('rel') == 'front') {ldelim}
-			/* picture attributes */
-			jQuery('#theImage img:first-child').attr({ldelim}
-				src: '{$VERSO_URL}',
-				style: 'width:;height:;',
-			});
-			
-			/* hd link atributes */
-			{if isset($VERSO_HD)}
-			jQuery('#theImage a:first-child').attr({ldelim}
-				href: "javascript:phpWGOpenWindow('{$VERSO_HD}','{$high.UUID}','scrollbars=yes,toolbar=no,status=no,resizable=yes')"
-			});
-			{/if}
-			
-			/* B2F link content */
-			jQuery(this).html('<img src="{$B2F_PATH}template/rotate_2.png"/> {'See front'|@translate}');
-			jQuery(this).attr('rel', 'back');
-			
-		} else if (jQuery(this).attr('rel') == 'back') {ldelim}
-			jQuery('#theImage img:first-child').attr({ldelim}
-				src: '{$SRC_IMG}',
-				style: 'width:{$WIDTH_IMG}px;height:{$HEIGHT_IMG}px;',
-			});
-			
-			{if isset($VERSO_HD)}
-			jQuery('#theImage a:first-child').attr({ldelim}
-				href: "javascript:phpWGOpenWindow('{$high.U_HIGH}','{$high.UUID}','scrollbars=yes,toolbar=no,status=no,resizable=yes')')"
-			});
-			{/if}
-			
-			jQuery(this).html('<img src="{$B2F_PATH}template/rotate_1.png"/> {'See back'|@translate}');
-			jQuery(this).attr('rel', 'front');
-		}
-	});
+jQuery(document).ready(function () {ldelim}
+  jQuery('.reverse').click(function() {ldelim}
+    if (jQuery(this).attr('rel') == 'front') {ldelim}
+      /* picture attributes */
+      jQuery('#theImage img:first-child').attr({ldelim}
+        src: '{$VERSO_URL}',
+        style: 'width:;height:;',
+      });
+      
+      /* hd link atributes */
+      {if isset($VERSO_HD)}
+      jQuery('#theImage a:first-child').attr({ldelim}
+        href: "javascript:phpWGOpenWindow('{$VERSO_HD}','{$high.UUID}','scrollbars=yes,toolbar=no,status=no,resizable=yes')"
+      });
+      {/if}
+      
+      /* B2F link content */
+      jQuery(this).html('<img src="{$B2F_PATH}template/rotate_2.png"/> {'See front'|@translate}');
+      jQuery(this).attr('rel', 'back');
+      
+    } else if (jQuery(this).attr('rel') == 'back') {ldelim}
+      jQuery('#theImage img:first-child').attr({ldelim}
+        src: '{$SRC_IMG}',
+        style: 'width:{$WIDTH_IMG}px;height:{$HEIGHT_IMG}px;',
+      });
+      
+      {if isset($VERSO_HD)}
+      jQuery('#theImage a:first-child').attr({ldelim}
+        href: "javascript:phpWGOpenWindow('{$high.U_HIGH}','{$high.UUID}','scrollbars=yes,toolbar=no,status=no,resizable=yes')')"
+      });
+      {/if}
+      
+      jQuery(this).html('<img src="{$B2F_PATH}template/rotate_1.png"/> {'See back'|@translate}');
+      jQuery(this).attr('rel', 'front');
+    }
+  });
+});
 {/footer_script}
 
 <a class="reverse" rel="front" href="#">
-	<img src="{$B2F_PATH}template/rotate_1.png"/>
-	{'See back'|@translate}
+  <img src="{$B2F_PATH}template/rotate_1.png"/>
+  {'See back'|@translate}
 </a>
Index: /extensions/Back2Front/template/picture_modify.tpl
===================================================================
--- /extensions/Back2Front/template/picture_modify.tpl	(revision 10820)
+++ /extensions/Back2Front/template/picture_modify.tpl	(revision 10821)
@@ -3,58 +3,47 @@
   $('input[name="b2f_is_verso"]').change(function () {ldelim}
     if (this.checked) {ldelim}
-      $('#frontside_id').css('visibility', '');
-      $('select[name="level"]').prepend('<option label="{'Nobody (backside)'|@translate}" value="99">{'Nobody (backside)'|@translate}</option>');
-      $('select[name="level"]').val('99').attr('readonly', 'readonly').css('opacity', '0.6');
-      
+      $('.frontside_id').css('visibility', '');
     } else {ldelim}
-      $('#frontside_id').css('visibility', 'hidden');
-      $('select[name="level"] option[value="99"]').remove();
-      $('select[name="level"]').val($('input[name="b2f_old_level"]').val()).removeAttr('readonly').css('opacity', '1');
+      $('.frontside_id').css('visibility', 'hidden');
     }
   });
-
-  {if isset($B2F_IS_VERSO)}
-  $('#frontside_id').css('visibility', '');
-  $('select[name="level"]').prepend('<option label="{'Nobody (backside)'|@translate}" value="99">{'Nobody (backside)'|@translate}</option>');
-  $('select[name="level"]').val('99').attr('readonly', 'readonly').css('opacity', '0.6');
-  {else}
-  $('#frontside_id').css('visibility', 'hidden');
-  $('select[name="level"]').val('{$level_options_selected.0}');
-  {/if}
 });
 {/footer_script}
 
 
-<form action="{$F_ACTION}#back2front" method="post" id="back2front">
+<form action="{$F_ACTION}" method="post" id="back2front">
 
   <fieldset>
     <legend>{'Backside management'|@translate}</legend>
 
+  {if isset($B2F_VERSO_ID)}
     <table>
-    {if isset($B2F_VERSO_ID)}
       <tr>
-        <td><strong>{'This picture has a backside :'|@translate}</strong></td>
+        <td><b>{'This picture has a backside :'|@translate}</b></td>
         <td><a href="{$B2F_VERSO_URL}">{$B2F_VERSO_ID} - {$B2F_VERSO_NAME}</a></td>
       </tr>
     </table>
-    {else}
-
+  {else}
+    <table>
       <tr>
-        <td><strong>{'This picture is a backside...'|@translate}</strong></td>
+        <td><b>{'This picture is a backside...'|@translate}</b></td>
         <td><input type="checkbox" name="b2f_is_verso" {$B2F_IS_VERSO}></td>
       </tr>
 
-      <tr id="frontside_id">
-        <td><strong>{'...of the picture n°'|@translate}</strong></td>
+      <tr class="frontside_id" {if !isset($B2F_IS_VERSO)}style="visibility:hidden;"{/if}>
+        <td><b>{'...of the picture n°'|@translate}</b></td>
         <td><input type="text" size="4" name="b2f_front_id" value="{$B2F_FRONT_ID}"></td>
       </tr>
-
+      
+      <tr class="frontside_id" {if !isset($B2F_IS_VERSO)}style="visibility:hidden;"{/if}>
+        <td><b>{'Move backside to private album'|@translate}</b></td>
+        <td><input type="checkbox" name="b2f_move_verso" checked="checked"></td>
+      </tr>
     </table>
 
     <p style="text-align:center;">
-      <input type="hidden" name="b2f_old_level" value="{if isset($B2F_OLD_LEVEL)}{$B2F_OLD_LEVEL}{else}{$level_options_selected.0}{/if}">
       <input class="submit" type="submit" value="{'Submit'|@translate}" name="b2f_submit">
     </p>
-    {/if}
+  {/if}
 
   </fieldset>
