Index: /extensions/AMenuManager/admin/amm_admin.tpl
===================================================================
--- /extensions/AMenuManager/admin/amm_admin.tpl	(revision 8961)
+++ /extensions/AMenuManager/admin/amm_admin.tpl	(revision 8962)
@@ -1,8 +1,15 @@
 <h2 style="float:right;top:-24px;position:relative;height:auto;font-size:12px;font-weight:normal;">{$plugin.AMM_VERSION}</h2>
 
-<div style="position:relative;top:-24px;clear:right;">
-  {if isset($page_nfo)}
-  <p>{$page_nfo}</p>
+<div class='helps'>
+  {if isset($pageNfo)}
+  <p>{$pageNfo}</p>
   {/if}
+</div>
+
+<div id='iBDProcessing' style="display:none;position:absolute;left:0;top:0;width:100%;height:100%;background:#000000;opacity:0.75;z-index:800;">
+  <img src="plugins/GrumPluginClasses/icons/processing.gif" style="margin-top:20%;">
+</div>
+
+<div id='iConfigState' style='display:none;'>
 </div>
 
Index: /extensions/AMenuManager/admin/amm_album.tpl
===================================================================
--- /extensions/AMenuManager/admin/amm_album.tpl	(revision 8962)
+++ /extensions/AMenuManager/admin/amm_album.tpl	(revision 8962)
@@ -0,0 +1,53 @@
+
+{literal}
+
+
+<script type="text/javascript">
+  var ac;
+
+  $(window).load(
+    function ()
+    {
+      ac=new albumConfig(
+        {},
+        {
+          g002_setting_randompic_periodicchange_deactivated:"{/literal}{'g002_setting_randompic_periodicchange_deactivated'|@translate}{literal}",
+          g002_setting_randompic_height_auto:"{/literal}{'g002_setting_randompic_height_auto'|@translate}{literal}"
+        },
+        '{/literal}{$token}{literal}',
+        {
+          'selectCat':{/literal}{$datas.albums}{literal}
+        }
+      );
+    }
+  );
+
+</script>
+{/literal}
+
+<div id='iBDProcessing' style="display:none;position:absolute;left:0;top:0;width:100%;height:100%;background:#000000;opacity:0.75;z-index:800;">
+  <img src="plugins/GrumPluginClasses/icons/processing.gif" style="margin-top:20%;">
+</div>
+
+<div id='iConfigState' style='display:none;'>
+</div>
+
+<form method="post" action="" class="general">
+  <fieldset>
+    <legend>{'g002_setting_albums_menus'|@translate}</legend>
+
+      <table class="formtable">
+        <tr>
+          <td>
+            <div id='iamm_album_selectedCat'></div>
+          </td>
+        </tr>
+      </table>
+  </fieldset>
+
+  <p>
+    <input type="button" id="iamm_submit_apply" value="{'g002_apply'|@translate}" onclick="ac.submit();">
+  </p>
+
+
+</form>
Index: /extensions/AMenuManager/admin/amm_coreBlocks.tpl
===================================================================
--- /extensions/AMenuManager/admin/amm_coreBlocks.tpl	(revision 8962)
+++ /extensions/AMenuManager/admin/amm_coreBlocks.tpl	(revision 8962)
@@ -0,0 +1,150 @@
+{literal}
+<script type="text/javascript">
+
+  var cbm,
+      resetValues = {
+        'cancel':new Array(),
+        'piwigo':new Array()
+      };
+  $(window).load(
+    function ()
+    {
+      {/literal}
+      // initialization for cancel et reset functions
+      {foreach from=$datas.coreBlocks.defaultValues item=value key=id}
+        resetValues.piwigo.push( {literal} { {/literal} id:"{$id}", block:"{$value.container}", order:{$value.order}, visibility:"{$value.visibility}" {literal} } {/literal} );
+      {/foreach}
+      {foreach from=$datas.coreBlocks.items item=value key=id}
+        resetValues.cancel.push( {literal} { {/literal} id:"{$id}", block:"{$value.container}", order:{$value.order}, visibility:"{$value.visibility}" {literal} } {/literal} );
+      {/foreach}
+      {literal}
+
+      cbm=new coreBlocks(
+        {},
+        {},
+        '{/literal}{$token}{literal}',
+        {
+          resetValues:resetValues,
+          tab:"{/literal}{$datas.tab}{literal}"
+        }
+
+      );
+    }
+  );
+</script>
+{/literal}
+
+
+<div style='padding-top:15px;'>
+{$blocksTabsheet}
+</div>
+
+
+<div id="containerPos" style='display:none;'>
+
+  <ul class='menuUl'>
+    {foreach from=$datas.menuBlocks item=block}
+      <li class='menuListItem connectedSortable pluginBox' blockId='{$block.id}'>
+
+        <table class='menuListAccess'>
+          <tr>
+            <td style='min-width: 250px;'>
+              <span class='menuListMove'><img src="{$themeconf.admin_icon_dir}/cat_move.png" class="drag_button" alt="{'Drag to re-order'|@translate}" title="{'Drag to re-order'|@translate}"/></span>
+              <span class='menuListName'>
+                <span style='font-weight:bold;' class='pluginBoxNameCell'>{$block.name|@translate}</span>&nbsp;[{$block.id}]<br>
+                <span style='font-style:italic;'>{if $block.owner=='piwigo'}Piwigo{else}{'g002_plugin'|@translate}&nbsp;:&nbsp;{$block.owner}{/if}</span>
+              </span>
+            </td>
+            <td style='min-width: 100px;text-align:right;'>{'g002_accessibility'|@translate}</td>
+            <td style='width:30%;'>
+              <div id='users_{$block.id}' class='menuListUsers'>
+              {ldelim}
+                "selected":{$block.users},
+                "values":
+                [
+                {foreach from=$datas.users item=user name=items}
+                  {ldelim}"value":"{$user.id}","cols":["{$user.name}"]{rdelim}{if !$smarty.foreach.items.last},{/if}
+                {/foreach}
+                ]
+              {rdelim}
+              </div>
+            </td>
+            <td style='width:30%;'>
+              <div id='groups_{$block.id}' class='menuListGroups'>
+              {ldelim}
+                "selected":{$block.groups},
+                "values":
+                [
+                {foreach from=$datas.groups item=group name=items}
+                  {ldelim}"value":"{$group.id}","cols":["{$group.name}"]{rdelim}{if !$smarty.foreach.items.last},{/if}
+                {/foreach}
+                ]
+              {rdelim}
+              </div>
+            </td>
+
+          </tr>
+        </table>
+      </li>
+    {/foreach}
+  </ul>
+
+</div>
+
+<div id="containerMenu" style='display:none;'>
+  <table>
+    <tr>
+      {foreach from=$datas.coreBlocks.blocks item=blockName key=block}
+      <td>
+        <h3>{$blockName|@translate}</h3>
+      </td>
+      {/foreach}
+      <td>&nbsp;</td>
+    </tr>
+    <tr>
+    {foreach from=$datas.coreBlocks.blocks item=blockName key=block name=items}
+      <td {if !$smarty.foreach.items.first}class='leftBar'{/if}>
+        <div id="containerMenu_{$block}" class="containerMenuBlock">
+
+          <ul class="connectedSortable categoryUl" id="menu_{$block}">
+          {foreach from=$datas.coreBlocks.items item=data key=id}
+            {if $data.container==$block}
+              <li class="categoryLi menuItem pluginBox {if $id=='qsearch'}menuItemDisabled{/if}" id="i{$id}">
+                <div class='pluginBoxNameCell'>
+                  {if $id=="qsearch"}
+                  {else}
+                  <img src="{$themeconf.admin_icon_dir}/cat_move.png" class="button drag_button" alt="{'Drag to re-order'|@translate}" title="{'Drag to re-order'|@translate}"/>
+                  {/if}
+                  {$data.translation|@translate}
+
+                    <img src="{$ROOT_URL}{$themeconf.admin_icon_dir}/permissions.png"
+                         class="button drag_button visibilitySwitch"
+                         alt="{'g002_click_to_manage_rights'|@translate}"
+                         title="{'g002_click_to_manage_rights'|@translate}"
+                         style="float:right;"/>
+
+                </div>
+                <div id="i{$id}_visibility" class="visibility">
+                  {$data.visibilityForm}
+                </div>
+              </li>
+            {/if}
+          {/foreach}
+          </ul>
+        </div>
+      </td>
+    {/foreach}
+    <td class='leftBar'>
+      <div class='containerMenuBlock'>
+        <input type="button" value="{'g002_cancel'|@translate}" onclick="cbm.reset('cancel');"/><br>
+        <input type="button" value="{'g002_piwigo_default'|@translate}" onclick="cbm.reset('piwigo');"/>
+      </div>
+    </td>
+    </tr>
+  </table>
+</div>
+
+<div style='padding-top:30px;'>
+  <input style='margin-left:20px;' type="button" value="{'g002_apply'|@translate}" onclick="cbm.submit();">
+</div>
+
Index: /extensions/AMenuManager/admin/amm_coreBlocks_detail.tpl
===================================================================
--- /extensions/AMenuManager/admin/amm_coreBlocks_detail.tpl	(revision 8962)
+++ /extensions/AMenuManager/admin/amm_coreBlocks_detail.tpl	(revision 8962)
@@ -0,0 +1,13 @@
+<h3>{'User'|@translate}</h3>
+<p>
+{foreach from=$users item=values}
+  <label><input type="checkbox" value="{$values.id}" class='visibilityUser' {if $values.allowed==true} checked{/if} />&nbsp;{$values.name}</label><br/>
+{/foreach}
+</p>
+
+<h3>{'Group'|@translate}</h3>
+<p>
+{foreach from=$groups item=values}
+  <label><input type="checkbox" value="{$values.id}" class='visibilityGroup' {if $values.allowed==true} checked{/if} />&nbsp;{$values.name}</label><br/>
+{/foreach}
+</p>
Index: /extensions/AMenuManager/admin/amm_links.tpl
===================================================================
--- /extensions/AMenuManager/admin/amm_links.tpl	(revision 8962)
+++ /extensions/AMenuManager/admin/amm_links.tpl	(revision 8962)
@@ -0,0 +1,6 @@
+<div style='padding-top:15px;'>
+{$linksTabsheet}
+</div>
+<div id="pageTabContent">
+  {$sheetContent}
+</div>
Index: /extensions/AMenuManager/admin/amm_linksconfig.tpl
===================================================================
--- /extensions/AMenuManager/admin/amm_linksconfig.tpl	(revision 8961)
+++ /extensions/AMenuManager/admin/amm_linksconfig.tpl	(revision 8962)
@@ -1,67 +1,41 @@
 {literal}
 <script type="text/javascript">
+  var ulc;
 
-  //global var ; need to not have to initialize them every time a value is changed
-  var objlang;
-  var objnames = new Array('iamm_links_title');
-  var objinput = new Array();   //input text from form => objinput[name]
-  var objhidden = new Array();  //input hidden from form => objhidden[name][lang]
-
-  function init()
-  {
-    objlang = document.getElementById('islang');
-    for(i=0;i<objnames.length;i++)
+  $(window).load(
+    function ()
     {
-      objinput[i] = document.getElementById(objnames[i]);
-      objhidden[i] = new Array();
-      for(j=0;j<objlang.options.length;j++)
-      {
-        objhidden[i][j] = document.getElementById(objnames[i]+'_'+objlang.options[j].value);
-      }
+      ulc=new userLinksConfig(
+        {}, {},
+        '{/literal}{$token}{literal}',
+        {
+          'showIcons':'{/literal}{$datas.config.showIcons}{literal}',
+          'userLang':'{/literal}{$datas.selectedLang}{literal}',
+          'titles':
+            {
+            {/literal}
+            {foreach from=$datas.config.titles name=items key=langCode item=title}
+              "{$langCode}":"{$title}"{if !$smarty.foreach.items.last},{/if}
+            {/foreach}
+            {literal}
+            },
+          'langs':[
+              {/literal}
+              {foreach from=$datas.config.titles name=items key=langCode item=title}
+                "{$langCode}"{if !$smarty.foreach.items.last},{/if}
+              {/foreach}
+              {literal}
+            ]
+        }
+      );
     }
-  }
-
-  function change_lang()
-  {
-    for(i=0;i<objnames.length;i++)
-    {
-      objinput[i].value = objhidden[i][objlang.options.selectedIndex].value;
-    }
-  }
-
-  function apply_changes(input_id)
-  {
-    var obj=document.getElementById(input_id);
-    objhidden[objnames.indexOf(input_id)][objlang.options.selectedIndex].value = obj.value;
-  }
-
-  function do_translation()
-  {
-    var inputid = document.getElementById('iamm_links_title');
-    var tolang = objlang.options[objlang.options.selectedIndex].value.substr(0,2);
-
-    google_translate(inputid.value, '{/literal}{$datas.fromlang}{literal}', tolang, inputid, 'value', apply_changes, inputid.id);
-  }
-
-
+  );
 </script>
 {/literal}
 
+<form method="post" action="" class="general">
 
-
-<h3><span style="font-weight:normal"><a href="{$datas.lnk_list}" title="{'g002_configlinks'|@translate}">{'g002_linkslist'|@translate} </span></a> / {'g002_configlinks'|@translate}
-</h3>
-
-
-<form method="post" action="" class="general">
   <fieldset>
     <legend>{'g002_setting_block_menu'|@translate}</legend>
-
-    {if isset($datas.language_list) and count($datas.language_list)}
-      {foreach from=$datas.language_list key=name item=language_row}
-        <input type="hidden" name="famm_links_title_{$language_row.LANG}"
-                id="iamm_links_title_{$language_row.LANG}" value="{$language_row.MENUBARTIT}">
-      {/foreach}
-    {/if}
 
     <table class="formtable">
@@ -69,8 +43,12 @@
         <td>{'g002_setting_block_title'|@translate}</td>
         <td>
-          <input type="text" id="iamm_links_title" value="" maxlength="50" onkeyup="apply_changes('iamm_links_title');" onblur="apply_changes('iamm_links_title');"/>
-          <select onchange="change_lang();" id="islang">
-            {html_options values=$datas.language_list_values output=$datas.language_list_labels selected=$datas.lang_selected}
-          </select><br>
+          <div id="iamm_links_title"></div>
+          <div id="islang">
+            [
+            {foreach from=$datas.langs key=langCode item=langLabel name=items}
+              {ldelim}"value":"{$langCode}","cols":["{$langLabel}"]{rdelim}{if !$smarty.foreach.items.last},{/if}
+            {/foreach}
+            ]
+          </div>
         </td>
       </tr>
@@ -78,11 +56,9 @@
         <td></td>
         <td style="font-size:80%;">
-          <a style="cursor:pointer;" onclick="do_translation()">{'g002_translate'|@translate}</a>
+          <a style="cursor:pointer;" onclick="$('#iamm_links_title').inputText('doTranslation');">{'g002_translate'|@translate}</a>
         </td>
       </tr>
 
     </table>
-
-
   </fieldset>
 
@@ -93,7 +69,8 @@
         <td>{'g002_setting_link_show_icon'|@translate}</td>
         <td>
-          <select name="famm_links_show_icons" id="iamm_links_show_icons">
-            {html_options values=$datas.yesno_values output=$datas.yesno_labels selected=$datas.show_icons_selected}
-          </select>
+          <div id='iamm_links_show_icons'>
+            <label><input type="radio" value="y">&nbsp;{'g002_yesno_y'|@translate}<br></label>
+            <label><input type="radio" value="n">&nbsp;{'g002_yesno_n'|@translate}</label>
+          </div>
         </td>
       </tr>
@@ -102,13 +79,7 @@
 
   <p>
-    <input type="submit" name="famm_submit_apply" id="iamm_submit_apply" value="{'g002_apply'|@translate}" >
+    <input type="button" id="iamm_submit_apply" value="{'g002_apply'|@translate}" onclick="ulc.submit();">
   </p>
-
-  <input type="hidden" name="famm_modeedit" value="config">
 
 </form>
 
-<script type="text/javascript">
-  init();
-  change_lang();
-</script>
Index: /extensions/AMenuManager/admin/amm_linkslinks.tpl
===================================================================
--- /extensions/AMenuManager/admin/amm_linkslinks.tpl	(revision 8962)
+++ /extensions/AMenuManager/admin/amm_linkslinks.tpl	(revision 8962)
@@ -0,0 +1,132 @@
+{literal}
+<script type="text/javascript">
+  var ulm;
+
+  $(window).load(
+    function ()
+    {
+      ulm=new userLinksManage(
+        {},
+        {
+          g002_ok:"{/literal}{'g002_ok'|@translate}{literal}",
+          g002_cancel:"{/literal}{'g002_cancel'|@translate}{literal}",
+          g002_loading:"{/literal}{'g002_loading'|@translate}{literal}",
+          g002_editoflink:"{/literal}{'g002_editoflink'|@translate}{literal}",
+          g002_createoflink:"{/literal}{'g002_createoflink'|@translate}{literal}"
+        },
+        '{/literal}{$token}{literal}'
+      );
+    }
+  );
+</script>
+{/literal}
+
+
+<div class='addLink'>
+  <a onclick="ulm.edit('');">{'g002_addlink'|@translate}</a>
+</div>
+<br>
+
+<ul id='iList' class='menuUl'>
+</ul>
+
+<div id='iListOrderButtons' style='display:none;'>
+  <input id='iBtValid' type='button' value="{'g002_valid_order'|@translate}" onclick='ulm.doUpdateOrder();'>
+  <input id='iBtReset' type='button' value="{'g002_reset_order'|@translate}" onclick='ulm.load();'>
+</div>
+
+
+
+
+<div id="iDialogDelete">
+</div>
+
+
+<div id="iDialogEdit" dialogTitle="{'g002_editLink'|@translate}">
+  <div id='iBDProcessing' style="display:none;position:absolute;width:100%;height:100%;background:#000000;opacity:0.75">
+      <img src="plugins/GrumPluginClasses/icons/processing.gif" style="margin-top:100px;">
+  </div>
+
+  <table class="formtable">
+    <tr>
+      <td>{'g002_label'|@translate}</td>
+      <td><div id='iamm_label'></div></td>
+    </tr>
+
+    <tr>
+      <td>{'g002_url'|@translate}</td>
+      <td><div id='iamm_url'></div></td>
+    </tr>
+
+    <tr>
+      <td>{'g002_icon'|@translate}</td>
+      <td>
+        <div id="iamm_icon">
+          [
+          {foreach from=$datas.iconsValues key=name item=icon name=items}
+            {ldelim}"value":"{$icon.value}","cols":["&lt;img src='{$icon.img}'&gt;", "{$icon.label}"]{rdelim}{if !$smarty.foreach.items.last},{/if}
+          {/foreach}
+          ]
+        </div>
+      </td>
+    </tr>
+
+    <tr>
+      <td>{'g002_mode'|@translate}</td>
+      <td>
+        <div id="iamm_mode">
+          [
+          {foreach from=$datas.modesValues key=name item=mode name=items}
+            {ldelim}"value":"{$mode.value}","cols":["{$mode.label}"]{rdelim}{if !$smarty.foreach.items.last},{/if}
+          {/foreach}
+          ]
+        </div>
+      </td>
+    </tr>
+
+    <tr>
+      <td>{'g002_visible'|@translate}</td>
+      <td>
+        <div id="iamm_visible">
+          <label><input type="radio" value="y">&nbsp;{'g002_yesno_y'|@translate}<br></label>
+          <label><input type="radio" value="n">&nbsp;{'g002_yesno_n'|@translate}</label>
+        </div>
+      </td>
+    </tr>
+
+    <tr>
+      <td>{'g002_accessibility'|@translate}</td>
+      <td style='min-width:475px;'>
+        <div id="iamm_access">
+          <table>
+            <tr>
+              <td style='width:50%;font-weight:bold;'>{'User'|@translate}</td>
+              <td style='width:50%;font-weight:bold;'>{'Group'|@translate}</td>
+            </tr>
+            <tr>
+              <td>
+                <div id='iamm_access_users'>
+                {foreach from=$datas.access.users item=values}
+                  <label><input type="checkbox" value="{$values.id}" class='visibilityUser' />&nbsp;{$values.name}</label><br/>
+                {/foreach}
+                </div>
+              </td>
+              <td>
+                <div id='iamm_access_groups'>
+                {foreach from=$datas.access.groups item=values}
+                  <label><input type="checkbox" value="{$values.id}" class='visibilityGroup' />&nbsp;{$values.name}</label><br/>
+                {/foreach}
+                </div>
+              </td>
+            </tr>
+          </table>
+
+
+        </div>
+      </td>
+    </tr>
+
+  </table>
+
+</div>
+
Index: /extensions/AMenuManager/admin/amm_linkslinks_detail.tpl
===================================================================
--- /extensions/AMenuManager/admin/amm_linkslinks_detail.tpl	(revision 8962)
+++ /extensions/AMenuManager/admin/amm_linkslinks_detail.tpl	(revision 8962)
@@ -0,0 +1,35 @@
+{foreach from=$datas.links key=name item=link}
+<li class='connectedSortable pluginBox' linkId='{$link.id}'>
+  <table>
+    <tr>
+      <td rowspan=2 style='width:22px'><img src="{$themeconf.admin_icon_dir}/cat_move.png" class="drag_button" alt="{'Drag to re-order'|@translate}" title="{'Drag to re-order'|@translate}"/></td>
+
+      <td rowspan=2 style='width:30px;'>{if $link.icon!=""}<img src='{$link.icon}'/>{else}&nbsp;{/if}</td>
+      <td style='width:50%;'>{$link.label}</td>
+
+
+      <td>{'g002_mode'|@translate}&nbsp;:&nbsp;{$link.mode}</td>
+
+
+      <td rowspan=2 width="40px">
+        <img src="{$themeconf.admin_icon_dir}/edit_s.png"
+             class="button" alt="{'g002_edit'|@translate}"
+             title="{'g002_edit'|@translate}"
+             onclick='ulm.edit({$link.id});'/>
+        <img src="{$themeconf.admin_icon_dir}/delete.png"
+             class="button"
+             alt="{'g002_delete'|@translate}"
+             title="{'g002_delete'|@translate}"
+             onclick='ulm.remove({$link.id});'/>
+      </td>
+    </tr>
+
+    <tr>
+      <td>{$link.url}</td>
+      <td>{'g002_visible'|@translate}&nbsp;:&nbsp;{$link.visible}</td>
+    </tr>
+
+  </table>
+</li>
+{/foreach}
+
Index: /extensions/AMenuManager/admin/amm_personalised.tpl
===================================================================
--- /extensions/AMenuManager/admin/amm_personalised.tpl	(revision 8962)
+++ /extensions/AMenuManager/admin/amm_personalised.tpl	(revision 8962)
@@ -0,0 +1,134 @@
+{literal}
+<script type="text/javascript">
+  var upbm;
+
+  $(window).load(
+    function ()
+    {
+      upbm=new userPersonnalisedBlockManage(
+        {},
+        {
+          g002_ok:"{/literal}{'g002_ok'|@translate}{literal}",
+          g002_cancel:"{/literal}{'g002_cancel'|@translate}{literal}",
+          g002_loading:"{/literal}{'g002_loading'|@translate}{literal}",
+          g002_editofpersonalised:"{/literal}{'g002_editofpersonalised'|@translate}{literal}",
+          g002_createofpersonalised:"{/literal}{'g002_createofpersonalised'|@translate}{literal}"
+        },
+        '{/literal}{$token}{literal}',
+        {
+          'userLang':'{/literal}{$datas.selectedLang}{literal}',
+          'langs':[
+              {/literal}
+              {foreach from=$datas.langs name=items key=langCode item=label}
+                "{$langCode}"{if !$smarty.foreach.items.last},{/if}
+              {/foreach}
+              {literal}
+            ]
+        }
+      );
+    }
+  );
+</script>
+{/literal}
+
+
+<div class='addBlock'>
+  <a onclick="upbm.edit('');">{'g002_addsection'|@translate}</a>
+</div>
+
+
+<table id='iHeaderList' class="littlefont">
+  <tr>
+    <th>{'g002_setting_personalised_nfo'|@translate}</th>
+    <th style='width:40%;'>{'g002_title'|@translate}</th>
+    <th style='width:80px;'>{'g002_visible'|@translate}</th>
+    <th style='width:40px;'>&nbsp;</th>
+  </tr>
+</table>
+
+
+<div id='iList' class="{$themeconf.name}">
+</div>
+<div id="iListNb"></div>
+
+
+
+
+<div id="iDialogDelete">
+</div>
+
+
+<div id="iDialogEdit" dialogTitle="{'g002_editLink'|@translate}">
+  <div id='iBDProcessing' style="display:none;position:absolute;width:100%;height:100%;background:#000000;opacity:0.75">
+      <img src="plugins/GrumPluginClasses/icons/processing.gif" style="margin-top:100px;">
+  </div>
+
+  <table class="formtable">
+
+    <tr>
+      <th class='gcText2' colspan='2'>
+        {'g002_setting_personalised_properties'|@translate}
+      </th>
+    </tr>
+
+    <tr>
+      <td>{'g002_setting_personalised_nfo'|@translate}</td>
+      <td><div id='iamm_personalised_nfo'></div></td>
+    </tr>
+
+    <tr>
+      <td>{'g002_setting_block_active'|@translate}</td>
+      <td>
+        <div id='iamm_personalised_visible'>
+          <label><input type="radio" value="y">&nbsp;{'g002_yesno_y'|@translate}<br></label>
+          <label><input type="radio" value="n">&nbsp;{'g002_yesno_n'|@translate}</label>
+        </div>
+      </td>
+    </tr>
+
+
+    <tr>
+      <td colspan='2'>
+        &nbsp;
+      </td>
+    </tr>
+
+    <tr>
+      <th class='gcText2' colspan='2'>
+        {'g002_setting_block_menu'|@translate}
+      </th>
+    </tr>
+
+
+    <tr style='border-bottom:1px dotted;'>
+      <td>{'g002_setting_block_langchoice'|@translate}</td>
+      <td>
+        <div id="islang">
+          [
+          {foreach from=$datas.langs key=langCode item=langLabel name=items}
+            {ldelim}"value":"{$langCode}","cols":["{$langLabel}"]{rdelim}{if !$smarty.foreach.items.last},{/if}
+          {/foreach}
+          ]
+        </div>
+      </td>
+    </tr>
+
+    <tr>
+      <td>{'g002_setting_block_title'|@translate}</td>
+      <td>
+        <div id="iamm_personalised_title"></div>
+        <a style="cursor:pointer;font-size:80%;"  onclick="$('#iamm_personalised_title').inputText('doTranslation');">{'g002_translate'|@translate}</a>
+      </td>
+    </tr>
+
+    <tr>
+      <td>{'g002_setting_personalised_content'|@translate}</td>
+      <td>
+        <div id="iamm_personalised_content"></div>
+      </td>
+    </tr>
+
+  </table>
+
+</div>
+
Index: /extensions/AMenuManager/admin/amm_personalised_detail.tpl
===================================================================
--- /extensions/AMenuManager/admin/amm_personalised_detail.tpl	(revision 8962)
+++ /extensions/AMenuManager/admin/amm_personalised_detail.tpl	(revision 8962)
@@ -0,0 +1,24 @@
+
+<table class="littlefont">
+  {foreach from=$datas.blocks key=name item=block}
+  <tr>
+    <td>{$block.nfo}</td>
+    <td style='width:40%;'>{$block.title}</td>
+    <td style='width:80px;'>{$block.visible}</td>
+
+    <td width="40px">
+      <img src="{$themeconf.admin_icon_dir}/edit_s.png"
+           class="button" alt="{'g002_edit'|@translate}"
+           title="{'g002_edit'|@translate}"
+           onclick='upbm.edit({$block.id});'/>
+      <img src="{$themeconf.admin_icon_dir}/delete.png"
+           class="button"
+           alt="{'g002_delete'|@translate}"
+           title="{'g002_delete'|@translate}"
+           onclick='upbm.remove({$block.id});'/>
+    </td>
+  </tr>
+  {/foreach}
+</table>
+
+
Index: /extensions/AMenuManager/admin/amm_randompicconfig.tpl
===================================================================
--- /extensions/AMenuManager/admin/amm_randompicconfig.tpl	(revision 8961)
+++ /extensions/AMenuManager/admin/amm_randompicconfig.tpl	(revision 8962)
@@ -1,9 +1,6 @@
-{known_script id="jquery.ui" src=$ROOT_URL|@cat:"themes/default/js/ui/packed/ui.core.packed.js"}
-{known_script id="jquery.ui.slider" src=$ROOT_URL|@cat:"themes/default/js/ui/packed/ui.slider.packed.js"}
-
 {literal}
 <style>
  .ui-slider {
-    width:350px;
+    width:360px;
     height:10px;
     border-width:1px;
@@ -22,113 +19,55 @@
   }
 </style>
+
 <script type="text/javascript">
+  var rpc;
 
-  //global var ; need to not have to initialize them every time a value is changed
-  var objlang;
-  var objnames = new Array('iamm_randompicture_title');
-  var objinput = new Array();   //input text from form => objinput[name]
-  var objhidden = new Array();  //input hidden from form => objhidden[name][lang]
-
-  function init()
-  {
-    objlang = document.getElementById('islang');
-    for(i=0;i<objnames.length;i++)
+  $(window).load(
+    function ()
     {
-      objinput[i] = document.getElementById(objnames[i]);
-      objhidden[i] = new Array();
-      for(j=0;j<objlang.options.length;j++)
-      {
-        objhidden[i][j] = document.getElementById(objnames[i]+'_'+objlang.options[j].value);
-      }
+      rpc=new randomPictConfig(
+        {},
+        {
+          g002_setting_randompic_periodicchange_deactivated:"{/literal}{'g002_setting_randompic_periodicchange_deactivated'|@translate}{literal}",
+          g002_setting_randompic_height_auto:"{/literal}{'g002_setting_randompic_height_auto'|@translate}{literal}"
+        },
+        '{/literal}{$token}{literal}',
+        {
+          'selectMode':"{/literal}{$datas.config.selectMode}{literal}",
+          'selectCat':{/literal}{$datas.config.selectCat}{literal},
+          'infosName':"{/literal}{$datas.config.infosName}{literal}",
+          'infosComment':"{/literal}{$datas.config.infosComment}{literal}",
+          'freqDelay':"{/literal}{$datas.config.freqDelay}{literal}",
+          'blockHeight':"{/literal}{$datas.config.blockHeight}{literal}",
+          'blockTitles':
+            {
+            {/literal}
+            {foreach from=$datas.config.blockTitles name=items key=langCode item=title}
+              "{$langCode}":"{$title}"{if !$smarty.foreach.items.last},{/if}
+            {/foreach}
+            {literal}
+            },
+          'userLang':'{/literal}{$datas.selectedLang}{literal}',
+          'langs':[
+              {/literal}
+              {foreach from=$datas.config.blockTitles name=items key=langCode item=title}
+                "{$langCode}"{if !$smarty.foreach.items.last},{/if}
+              {/foreach}
+              {literal}
+            ]
+        }
+      );
     }
-
-    formatDelay({/literal}{$datas.periodic_change}{literal});
-    $("#iamm_rp_pc_slider").slider(
-      {
-        min:0,
-        max:60000,
-        steps:120,
-        value:{/literal}{$datas.periodic_change}{literal},
-        slide: function(event, ui) { formatDelay(ui.value); }
-      });
-    $("#iamm_rp_pc_slider a").addClass('gcBgInput');
-
-    formatHeight({/literal}{$datas.height}{literal});
-    $("#iamm_rp_height_slider").slider(
-      {
-        min:99,
-        max:300,
-        steps:201,
-        value:affectHeight({/literal}{$datas.height}{literal}),
-        slide: function(event, ui) { formatHeight(ui.value); }
-      });
-    $("#iamm_rp_height_slider a").addClass('gcBgInput');
-  }
-
-  function formatDelay(delay)
-  {
-    $("#iamm_randompicture_periodicchange").val(delay);
-    if(delay==0)
-    {
-      $("#iamm_rp_pc_display").html("{/literal}{'g002_setting_randompic_periodicchange_deactivated'|@translate}{literal}");
-    }
-    else
-    {
-      $("#iamm_rp_pc_display").html((delay/1000).toFixed(2)+"s");
-    }
-  }
-
-  function formatHeight(height)
-  {
-    (height==99)?vheight=0:vheight=height;
-
-    $("#iamm_randompicture_height").val(vheight);
-    if(vheight==0)
-    {
-      $("#iamm_rp_height_display").html("{/literal}{'g002_setting_randompic_height_auto'|@translate}{literal}");
-    }
-    else
-    {
-      $("#iamm_rp_height_display").html(vheight+"px");
-    }
-  }
-
-  function affectHeight(height)
-  {
-    if(height==0)
-    {return(0);}else{return(height);}
-  }
-
-  function change_lang()
-  {
-    for(i=0;i<objnames.length;i++)
-    {
-      objinput[i].value = objhidden[i][objlang.options.selectedIndex].value;
-    }
-  }
-
-  function apply_changes(input_id)
-  {
-    var obj=document.getElementById(input_id);
-    objhidden[objnames.indexOf(input_id)][objlang.options.selectedIndex].value = obj.value;
-  }
-
-  function do_translation()
-  {
-    var inputid = document.getElementById('iamm_randompicture_title');
-    var tolang = objlang.options[objlang.options.selectedIndex].value.substr(0,2);
-
-    google_translate(inputid.value, '{/literal}{$datas.fromlang}{literal}', tolang, inputid, 'value', apply_changes, inputid.id);
-
-  }
-
+  );
 
 </script>
 {/literal}
 
+<div id='iBDProcessing' style="display:none;position:absolute;left:0;top:0;width:100%;height:100%;background:#000000;opacity:0.75;z-index:800;">
+  <img src="plugins/GrumPluginClasses/icons/processing.gif" style="margin-top:20%;">
+</div>
 
-
-<h3>{'g002_configrandompic'|@translate}</h3>
-
+<div id='iConfigState' style='display:none;'>
+</div>
 
 <form method="post" action="" class="general">
@@ -136,25 +75,24 @@
     <legend>{'g002_setting_block_menu'|@translate}</legend>
 
-    {if isset($datas.language_list) and count($datas.language_list)}
-      {foreach from=$datas.language_list key=name item=language_row}
-        <input type="hidden" name="famm_randompicture_title_{$language_row.LANG}"
-                id="iamm_randompicture_title_{$language_row.LANG}" value="{$language_row.MENUBARTIT}">
-      {/foreach}
-    {/if}
-
     <table class="formtable">
       <tr>
         <td>{'g002_setting_block_title'|@translate}</td>
         <td colspan="2">
-          <input type="text" id="iamm_randompicture_title" value="" maxlength="50" onkeyup="apply_changes('iamm_randompicture_title');" onblur="apply_changes('iamm_randompicture_title');"/>
-          <select onchange="change_lang();" id="islang">
-            {html_options values=$datas.language_list_values output=$datas.language_list_labels selected=$datas.lang_selected}
-          </select><br>
+          <div id="iamm_randompicture_title"></div>
+
+          <div id="islang">
+            [
+            {foreach from=$datas.langs key=langCode item=langLabel name=items}
+              {ldelim}"value":"{$langCode}","cols":["{$langLabel}"]{rdelim}{if !$smarty.foreach.items.last},{/if}
+            {/foreach}
+            ]
+          </div>
         </td>
       </tr>
+
       <tr>
         <td></td>
         <td style="font-size:80%;" colspan="2">
-          <a style="cursor:pointer;" onclick="do_translation()">{'g002_translate'|@translate}</a>
+          <a style="cursor:pointer;" onclick="$('#iamm_randompicture_title').inputText('doTranslation');">{'g002_translate'|@translate}</a>
         </td>
       </tr>
@@ -163,5 +101,4 @@
         <td>{'g002_setting_randompic_height'|@translate}</td>
         <td>
-          <input type="hidden" name="famm_randompicture_height" id="iamm_randompicture_height" value="{$datas.height}">
           <div id="iamm_rp_height_slider" class="gcBgInput gcBorderInput"></div>
         </td>
@@ -178,11 +115,15 @@
   <fieldset>
     <legend>{'g002_setting_randompic_aboutpicture'|@translate}</legend>
-      <table class="formclass">
+      <table class="formtable">
         <tr>
           <td>{'g002_setting_randompic_showname'|@translate}</td>
           <td>
-            <select name="famm_randompicture_showname" id="iamm_randompicture_showname">
-              {html_options values=$datas.show_values output=$datas.show_labels selected=$datas.showname_selected}
-            </select>
+            <div id="iamm_randompicture_showname">
+              [
+                {ldelim}"value":"n","cols":["{'g002_show_n'|@translate}"]{rdelim},
+                {ldelim}"value":"o","cols":["{'g002_show_o'|@translate}"]{rdelim},
+                {ldelim}"value":"u","cols":["{'g002_show_u'|@translate}"]{rdelim}
+              ]
+            </div>
           </td>
         </tr>
@@ -191,7 +132,11 @@
           <td>{'g002_setting_randompic_showcomment'|@translate}</td>
           <td>
-            <select name="famm_randompicture_showcomment" id="iamm_randompicture_showcomment">
-              {html_options values=$datas.show_values output=$datas.show_labels selected=$datas.showcomment_selected}
-            </select>
+            <div id="iamm_randompicture_showcomment">
+              [
+                {ldelim}"value":"n","cols":["{'g002_show_n'|@translate}"]{rdelim},
+                {ldelim}"value":"o","cols":["{'g002_show_o'|@translate}"]{rdelim},
+                {ldelim}"value":"u","cols":["{'g002_show_u'|@translate}"]{rdelim}
+              ]
+            </div>
           </td>
         </tr>
@@ -203,9 +148,8 @@
   <fieldset>
     <legend>{'g002_setting_randompic_periodicchange'|@translate}</legend>
-      <table class="formclass">
+      <table class="formtable">
         <tr>
           <td>{'g002_setting_randompic_periodicchange_delay'|@translate}</td>
           <td>
-            <input type="hidden" name="famm_randompicture_periodicchange" id="iamm_randompicture_periodicchange" value="{$datas.periodic_change}">
             <div id="iamm_rp_pc_slider" class="gcBgInput gcBorderInput"></div>
           </td>
@@ -214,19 +158,28 @@
           </td>
         </tr>
+      </table>
+  </fieldset>
 
 
+  <fieldset>
+    <legend>{'g002_selectedpict'|@translate}</legend>
+      <table class="formtable">
+        <tr>
+          <td>
+            <div id='iamm_randompicture_selectedMode'>
+              <label><input type="radio" value="a">&nbsp;{'g002_selected_all_gallery'|@translate}<br></label>
+              <label><input type="radio" value="f">&nbsp;{'g002_selected_favorites_wm'|@translate}<br></label>
+              <label><input type="radio" value="c">&nbsp;{'g002_selected_categories'|@translate}<br></label>
+                <div id='iamm_randompicture_selectedCat'></div>
+            </div>
+          </td>
+        </tr>
       </table>
   </fieldset>
 
   <p>
-    <input type="submit" name="famm_submit_apply" id="iamm_submit_apply" value="{'g002_apply'|@translate}" >
+    <input type="button" id="iamm_submit_apply" value="{'g002_apply'|@translate}" onclick="rpc.submit();">
   </p>
 
-  <input type="hidden" name="famm_modeedit" value="config">
 
 </form>
-
-<script type="text/javascript">
-  init();
-  change_lang();
-</script>
Index: /extensions/AMenuManager/admin/plugin_admin.php
===================================================================
--- /extensions/AMenuManager/admin/plugin_admin.php	(revision 8961)
+++ /extensions/AMenuManager/admin/plugin_admin.php	(revision 8962)
@@ -3,5 +3,5 @@
   Plugin     : Advanced Menu Manager
   Author     : Grum
-    email    : grum@grum.dnsalias.com
+    email    : grum@piwigo.org
     website  : http://photos.grum.dnsalias.com
     PWG user : http://forum.phpwebgallery.net/profile.php?id=3706
Index: /extensions/AMenuManager/amm.css
===================================================================
--- /extensions/AMenuManager/amm.css	(revision 8961)
+++ /extensions/AMenuManager/amm.css	(revision 8962)
@@ -1,2 +1,19 @@
+#iHeaderList { width:100%; border:1px solid; border-collapse: collapse; margin-top:3px; }
+div#iList { width:100%; border:1px solid; height:280px; border-top:0px; overflow:auto; position:relative; left:-1px;}
+#iListNb { width:99%; text-align:right; margin-bottom:8px; padding:2px; font-size:80%; }
+
+#iList table, table.listLinks { width:100%; text-align:left; border-collapse: collapse; }
+
+div#iList.roma table tr:hover { background:#303030; }
+div#iList.clear table tr:hover { color: #D54E21; background:#dbe8f3; }
+#iList table tr.connectedSortable,
+#iList li.connectedSortable { cursor: move; }
+#iList table tr.alignTop { vertical-align:top; }
+
+div.addLink, div.addBlock { text-align:left; }
+
+img.button { cursor:pointer; }
+
+
 
 .littlefont { font-size:90%; }
@@ -4,10 +21,73 @@
 table.littlefont td { text-align:left; padding:0px;padding-left:3px;padding-right:3px; }
 
-.containerMenuSection { width:250px;  margin:auto; padding:10px; display:inline-block; vertical-align:top; }
-li.menuItem { padding:4px; width:230px; cursor:move;}
+.containerMenuBlock { width:250px;  margin:auto; padding:10px; display:inline-block; vertical-align:top; }
+li.menuItem { padding:0px; cursor:move; border:none; }
+li.menuItem div { padding:4px; width:auto; min-height: 19px;}
+li.menuItem div.visibility { overflow:hidden;display:none;padding-left:20px; }
 li.menuItemDisabled { cursor:defaut;}
-div.visibility { width:100%;overflow:hidden;display:none;margin-left:30px; }
 
 div.visibility p { margin:0px; }
 div.visibility input { margin-right:8px; }
 div.visibility h3 { position:relative; font-size:14px; height:auto; margin:5px 0px 0px;padding:0px;text-align:left;}
+
+
+.ui-inputList-value span.iconColImg {
+}
+.ui-inputList-value span.iconColImg img {
+  float: left;
+  margin-left: 2px;
+}
+.ui-inputList-value span.iconColText {
+  position:relative;
+  top:-2px;
+  display:inline;
+}
+
+#iamm_album_selectedCat, #iamm_randompicture_selectedCat { min-width:300px; }
+#iamm_randompicture_selectedCat { margin-left:30px; }
+img.visibilitySwitch { cursor:pointer; }
+
+#containerMenu { text-align:left; }
+#containerMenu table { text-align:left; margin-left:0; }
+#containerMenu table tr { vertical-align:top; }
+#containerMenu table td.leftBar { border-left:1px dotted; }
+#containerMenu input[type="button"] { margin-bottom:4px; }
+
+li.menuListItem {
+  margin-bottom:5px;
+  padding:3px;
+  cursor:move;
+  min-height:30px;
+}
+li.menuListItem span.menuListMove {
+  position:absolute;
+  width:22px;
+  display:inline-block;
+}
+li.menuListItem span.menuListName {
+  margin-left:26px;
+  display:inline-block;
+}
+li.menuListItem div.menuListUsers,
+li.menuListItem div.menuListGroups {
+  display:inline-block;
+  min-width:150px;
+  width:100%;
+  margin-right: 2px;
+}
+li.menuListItem .ui-inputList-value li.ui-inputList-selected-item {
+  float:left;
+}
+li.menuListItem .ui-inputList-value li span.ui-inputList-delete-item {
+  top:0;
+}
+li.menuListItem .ui-inputList-value span {
+  height:13px;
+  min-height:0px;
+}
+table.menuListAccess {
+  width:100%;
+}
+table.menuListAccess tr {
+  vertical-align:top;
+}
Index: /extensions/AMenuManager/amm_aim.class.inc.php
===================================================================
--- /extensions/AMenuManager/amm_aim.class.inc.php	(revision 8961)
+++ /extensions/AMenuManager/amm_aim.class.inc.php	(revision 8962)
@@ -3,5 +3,5 @@
   Plugin     : Advanced Menu Manager
   Author     : Grum
-    email    : grum@grum.dnsalias.com
+    email    : grum@piwigo.org
     website  : http://photos.grum.dnsalias.com
     PWG user : http://forum.phpwebgallery.net/profile.php?id=3706
@@ -33,4 +33,12 @@
     parent::initEvents();
     add_event_handler('get_admin_plugin_menu_links', array(&$this, 'pluginAdminMenu') );
+    add_event_handler('loc_end_page_header', array(&$this, 'adminPanel'));
+  }
+
+  public function adminPanel()
+  {
+    global $template;
+
+    $template->append('footer_elements', "<script>$(document).ready(function () { $('li a[href=".$template->get_template_vars('U_CONFIG_MENUBAR')."]').attr('href', '".$this->getAdminLink()."&amp;fAMM_tabsheet=setmenu&amp;fAMM_page=position'); });</script>");
   }
 
Index: /extensions/AMenuManager/amm_aip.class.inc.php
===================================================================
--- /extensions/AMenuManager/amm_aip.class.inc.php	(revision 8961)
+++ /extensions/AMenuManager/amm_aip.class.inc.php	(revision 8962)
@@ -3,5 +3,5 @@
   Plugin     : Advanced Menu Manager
   Author     : Grum
-    email    : grum@grum.dnsalias.com
+    email    : grum@piwigo.org
     website  : http://photos.grum.fr
     PWG user : http://forum.phpwebgallery.net/profile.php?id=3706
@@ -19,17 +19,15 @@
 include_once(PHPWG_ROOT_PATH.'include/block.class.php');
 include_once(PHPWG_ROOT_PATH.'admin/include/tabsheet.class.php');
-include_once(PHPWG_PLUGINS_PATH.'GrumPluginClasses/classes/GPCAjax.class.inc.php');
-include_once(PHPWG_PLUGINS_PATH.'GrumPluginClasses/classes/genericjs.class.inc.php');
-include_once(PHPWG_PLUGINS_PATH.'GrumPluginClasses/classes/GPCTranslate.class.inc.php');
+include_once(PHPWG_PLUGINS_PATH.'GrumPluginClasses/classes/GPCTabSheet.class.inc.php');
+
 
 class AMM_AIP extends AMM_root
 {
-  protected $google_translate;
+  protected $googleTranslate;
   protected $tabsheet;
-  protected $sectionsId=array('menu' => 'Menu', 'special' => 'Specials');
-
-  protected $urls_modes=array(0 => 'new_window', 1 => 'current_window');
-
-  function AMM_AIP($prefixeTable, $filelocation)
+  protected $blocksId=array('menu' => 'Menu', 'special' => 'Specials');
+
+
+  public function __construct($prefixeTable, $filelocation)
   {
     parent::__construct($prefixeTable, $filelocation);
@@ -51,16 +49,14 @@
                           l10n('g002_personnalblock'),
                           $this->getAdminLink().'&amp;fAMM_tabsheet=personnalblock');
+    $this->tabsheet->add('album',
+                          l10n('g002_album'),
+                          $this->getAdminLink().'&amp;fAMM_tabsheet=album');
     $this->css = new GPCCss(dirname($this->getFileLocation()).'/'.$this->getPluginNameFiles().".css");
-    $this->google_translate = new GPCTranslate();
-  }
-
-
-  /* ---------------------------------------------------------------------------
-  Public classe functions
-  --------------------------------------------------------------------------- */
-
-  /*
-    manage plugin integration into piwigo's admin interface
-  */
+  }
+
+
+  /**
+   * manage plugin integration into piwigo's admin interface
+   */
   public function manage()
   {
@@ -69,7 +65,5 @@
     $template->set_filename('plugin_admin_content', dirname(__FILE__)."/admin/amm_admin.tpl");
 
-    $this->return_ajax_content();
-
-    $this->init_request();
+    $this->initRequest();
 
     $this->tabsheet->select($_REQUEST['fAMM_tabsheet']);
@@ -83,685 +77,421 @@
 
     $template->assign('plugin', $template_plugin);
-
-
-    if(isset($_POST['famm_modeedit']))
-    {
-      $post_action=$_POST['famm_modeedit'];
-    }
-    else
-    {
-      $post_action="";
-    }
-
-    $page_nfo="";
+    $template->assign('token', get_pwg_token());
+
+
+    switch($_REQUEST['fAMM_tabsheet'])
+    {
+      case 'links':
+        $this->displayLinksPage($_REQUEST['fAMM_page']);
+        break;
+
+      case 'randompict':
+        $this->displayRandompicPage();
+        break;
+
+      case 'personnalblock':
+        $this->displayPersonalisedBlockPage();
+        break;
+
+      case 'setmenu':
+        $this->displayBlocksPage($_REQUEST['fAMM_page']);
+        break;
+
+      case 'album':
+        $this->displayAlbumPage();
+        break;
+    }
+
+    $template->assign_var_from_handle('ADMIN_CONTENT', 'plugin_admin_content');
+  }
+
+
+  /**
+   * initialize events call for the plugin
+   */
+  public function initEvents()
+  {
+    add_event_handler('loc_end_page_header', array(&$this->css, 'applyCSS'));
+    GPCCss::applyGpcCss();
+  }
+
+
+  /**
+   * if empty, initialize the $_REQUEST var
+   *
+   * if not empty, check validity for the request values
+   *
+   */
+  private function initRequest()
+  {
+    //initialise $REQUEST values if not defined
+    if(!array_key_exists('fAMM_tabsheet', $_REQUEST)) $_REQUEST['fAMM_tabsheet']='setmenu';
+
+    if(!($_REQUEST['fAMM_tabsheet']=='links' or
+         $_REQUEST['fAMM_tabsheet']=='randompict' or
+         $_REQUEST['fAMM_tabsheet']=='personnalblock' or
+         $_REQUEST['fAMM_tabsheet']=='setmenu' or
+         $_REQUEST['fAMM_tabsheet']=='album'
+        )
+      ) $_REQUEST['fAMM_tabsheet']='setmenu';
+
+
+    /*
+     * checks for links page
+     */
     if($_REQUEST['fAMM_tabsheet']=='links')
     {
-      $page_nfo=l10n('g002_addlinks_nfo');
-
-      switch($_REQUEST['action'])
-      {
-        case 'list':
-          $this->display_links_list_page();
-          break;
-        case 'create':
-        case 'modify':
-          if($post_action==$_REQUEST['action'])
-          {
-            if(!$this->adviser_abort())
-            {
-              $this->action_create_modify_url();
-            }
-            $this->display_links_list_page();
-          }
-          else
-          {
-            ($_REQUEST['action']=='modify')?$urlid=$_REQUEST['fItem']:$urlid=0;
-            $this->display_links_manage_page($_REQUEST['action'], $urlid);
-          }
-          break;
-        case 'config':
-          if($post_action==$_REQUEST['action'])
-          {
-            if(!$this->adviser_abort())
-            {
-              $this->action_links_modify_config();
-            }
-          }
-          $this->display_links_config_page();
-          break;
-      }
-    }
-    elseif($_REQUEST['fAMM_tabsheet']=='randompict')
-    {
-      $page_nfo=l10n('g002_randompict_nfo');
-      if($post_action=='config')
-      {
-        if(!$this->adviser_abort())
-        {
-          $this->action_randompic_modify_config();
-        }
-      }
-      $this->display_randompic_config_page();
-    }
-    elseif($_REQUEST['fAMM_tabsheet']=='personnalblock')
-    {
-      $page_nfo=l10n('g002_personnalblock_nfo');
-
-      switch($_REQUEST['action'])
-      {
-        case 'list':
-          $this->display_personalised_list_page();
-          break;
-        case 'create':
-        case 'modify':
-          if($post_action==$_REQUEST['action'])
-          {
-            if(!$this->adviser_abort())
-            {
-              $this->action_create_modify_personalised();
-            }
-            $this->display_personalised_list_page();
-          }
-          else
-          {
-            ($_REQUEST['action']=='modify')?$sectionid=$_REQUEST['fItem']:$sectionid=0;
-            $this->display_personalised_manage_page($_REQUEST['action'], $sectionid);
-          }
-          break;
-      }
-    }
-    elseif($_REQUEST['fAMM_tabsheet']=='setmenu')
-    {
-      $page_nfo=l10n('g002_setmenu_nfo');
-      $this->display_sections_page();
-    }
-
-    $template->assign('page_nfo', $page_nfo);
-
-    $template->assign_var_from_handle('ADMIN_CONTENT', 'plugin_admin_content');
-
-
-  }
-
-  /*
-    initialize events call for the plugin
-  */
-  public function initEvents()
-  {
-    add_event_handler('loc_end_page_header', array(&$this->css, 'applyCSS'));
-  }
-
-  /* ---------------------------------------------------------------------------
-  Private classe functions
-  --------------------------------------------------------------------------- */
-
-  /*
-    return ajax content
-  */
-  protected function return_ajax_content()
-  {
-    global $ajax, $template;
-
-    if(isset($_REQUEST['ajaxfct']))
-    {
-      //$this->debug("AJAXFCT:".$_REQUEST['ajaxfct']);
-      $result="<p class='errors'>".l10n('g002_error_invalid_ajax_call')."</p>";
-      switch($_REQUEST['ajaxfct'])
-      {
-        case 'links_list':
-          $result=$this->ajax_amm_links_list();
-          break;
-        case 'links_permut':
-          $result=$this->ajax_amm_links_permut($_REQUEST['fItem'], $_REQUEST['fPermut']);
-          break;
-        case 'links_delete':
-          $result=$this->ajax_amm_links_delete($_REQUEST['fItem']);
-          break;
-
-/*
-        case 'setmenu_modmenu_sections_list':
-          $result=$this->ajax_amm_setmenu_mod_section_list('amm_sections_modmenu');
-          break;
-        case 'setmenu_modmenu_sections_showhide':
-          $result=$this->ajax_amm_setmenu_mod_section_showhide('amm_sections_modmenu', $_REQUEST['fItem']);
-          break;
-
-        case 'setmenu_modspecial_sections_list':
-          $result=$this->ajax_amm_setmenu_mod_section_list('amm_sections_modspecials');
-          break;
-        case 'setmenu_modspecial_sections_showhide':
-          $result=$this->ajax_amm_setmenu_mod_section_showhide('amm_sections_modspecials', $_REQUEST['fItem']);
-          break;
-*/
-
-        case 'personalised_list':
-          $result=$this->ajax_amm_personalised_list();
-          break;
-        case 'personalised_delete':
-          $result=$this->ajax_amm_personalised_delete($_REQUEST['fItem']);
-          break;
-      }
-
-      GPCAjax::returnResult($result);
-    }
-  }
-
-  /*
-    if empty, initialize $_request
-  */
-  private function init_request()
-  {
-    //initialise $REQUEST values if not defined
-    if(!array_key_exists('fAMM_tabsheet', $_REQUEST))
-    {
-      $_REQUEST['fAMM_tabsheet']='setmenu';
-    }
-
-    if((($_REQUEST['fAMM_tabsheet']=='links') or
-        ($_REQUEST['fAMM_tabsheet']=='personnalblock')) and !isset($_REQUEST['action']))
-    {
-      $_REQUEST['action']='list';
-    }
-    elseif((($_REQUEST['fAMM_tabsheet']=='setmenu')) and !isset($_REQUEST['action']))
-    {
-      $_REQUEST['action']='modmenu';
-    }
-
-
-
-  } //init_request
-
-
-  /*
-    manage display for urls table page
-  */
-  private function display_links_list_page()
+      if(!isset($_REQUEST['fAMM_page'])) $_REQUEST['fAMM_page']='links';
+
+      if(!($_REQUEST['fAMM_page']=='links' or
+           $_REQUEST['fAMM_page']=='config'
+          )
+        ) $_REQUEST['fAMM_page']='config';
+    }
+
+
+    /*
+     * checks for blocks menu page
+     */
+    if($_REQUEST['fAMM_tabsheet']=='setmenu')
+    {
+      if(!isset($_REQUEST['fAMM_page'])) $_REQUEST['fAMM_page']='position';
+
+      if(!($_REQUEST['fAMM_page']=='position' or
+           $_REQUEST['fAMM_page']=='blocksContent'
+          )
+        ) $_REQUEST['fAMM_page']='position';
+    }
+
+  } //initRequest
+
+
+  /**
+   * display the links management page
+   */
+  private function displayLinksPage($tab)
   {
     global $template, $user;
+
+    GPCCore::addHeaderJS('jquery.ui', 'themes/default/js/ui/packed/ui.core.packed.js');
+    GPCCore::addHeaderJS('jquery.ui.sortable', 'themes/default/js/ui/packed/ui.sortable.packed.js');
+    GPCCore::addHeaderJS('jquery.ui.dialog', 'themes/default/js/ui/packed/ui.dialog.packed.js');
+
     $template->set_filename('body_page',
-                            dirname($this->getFileLocation()).'/admin/amm_linkslist.tpl');
-
-    $tmp=$this->get_count_url();
-    if($tmp==0)
-    {
-      $tmp=l10n("g002_nolinks");
-    }
-    elseif($tmp==1)
-    {
-      $tmp="1 ".l10n("g002_link");
-    }
-    else
-    {
-      $tmp=$tmp." ".l10n("g002_links");
-    }
-
-
-    $template_datas=array(
-      'lnk_create' => $this->getAdminLink().'&amp;fAMM_tabsheet=links&amp;action=create',
-      'lnk_config' => $this->getAdminLink().'&amp;fAMM_tabsheet=links&amp;action=config',
-      'AMM_AJAX_URL_LIST' => $this->getAdminLink()."&ajaxfct=",
-      'nburl' => $tmp
+                            dirname($this->getFileLocation()).'/admin/amm_links.tpl');
+
+    $linksTabsheet = new GPCTabSheet('linksTabsheet', $this->tabsheet->get_titlename(), 'tabsheet2 gcBorder', 'itab2');
+    $linksTabsheet->select($tab);
+    $linksTabsheet->add('links',
+                          l10n('g002_setting_link_links'),
+                          $this->getAdminLink().'&amp;fAMM_tabsheet=links&amp;fAMM_page=links');
+    $linksTabsheet->add('config',
+                          l10n('g002_configlinks'),
+                          $this->getAdminLink().'&amp;fAMM_tabsheet=links&amp;fAMM_page=config');
+    $linksTabsheet->assign();
+
+    switch($tab)
+    {
+      case 'links':
+        $template->assign('sheetContent', $this->displayLinksPageLinks());
+        break;
+      case 'config':
+        $template->assign('sheetContent', $this->displayLinksPageConfig());
+        break;
+    }
+
+    $template->assign_var_from_handle('AMM_BODY_PAGE', 'body_page');
+    $template->assign('pageNfo', l10n('g002_addlinks_nfo'));
+  }
+
+  /**
+   * display the randompict management page
+   */
+  private function displayRandompicPage()
+  {
+    global $template, $user;
+
+    GPCCore::addHeaderJS('jquery.ui', 'themes/default/js/ui/packed/ui.core.packed.js');
+    GPCCore::addHeaderJS('jquery.ui.slider', 'themes/default/js/ui/packed/ui.slider.packed.js');
+    GPCCore::addHeaderJS('gpc.categorySelector', 'plugins/GrumPluginClasses/js/ui.categorySelector'.GPCCore::getMinified().'.js');
+    GPCCore::addUI('inputList,inputText,inputRadio,categorySelector,googleTranslate');
+    GPCCore::addHeaderJS('amm.rpc', 'plugins/AMenuManager/js/amm_randomPictConfig'.GPCCore::getMinified().'.js');
+
+    $template->set_filename('body_page',
+                            dirname($this->getFileLocation()).'/admin/amm_randompicconfig.tpl');
+
+    $datas=array(
+      'config' => array(
+          'infosName' => $this->config['amm_randompicture_showname'],
+          'infosComment' => $this->config['amm_randompicture_showcomment'],
+          'freqDelay' => $this->config['amm_randompicture_periodicchange'],
+          'selectMode' => $this->config['amm_randompicture_selectMode'],
+          'selectCat' => json_encode($this->config['amm_randompicture_selectCat']),
+          'blockHeight' => $this->config['amm_randompicture_height'],
+          'blockTitles' => array()
+        ),
+      'selectedLang' => $user['language'],
+      'fromLang' => substr($user['language'],0,2),
+      'langs' => array()
     );
-
-    $template->assign("datas", $template_datas);
-    $template->assign_var_from_handle('AMM_BODY_PAGE', 'body_page');
-  }
-
-  /*
-    manage display for urls config page
-  */
-  private function display_links_config_page()
-  {
-    global $template, $user;
-    $template->set_filename('body_page',
-                            dirname($this->getFileLocation()).'/admin/amm_linksconfig.tpl');
-
-    $template_datas=array(
-      'lnk_list' => $this->getAdminLink().'&amp;fAMM_tabsheet=links',
-      'AMM_AJAX_URL_LIST' => $this->getAdminLink()."&ajaxfct=",
-      'show_icons_selected' => $this->config['amm_links_show_icons'],
-      'lang_selected' => $user['language'],
-      'fromlang' => substr($user['language'],0,2)
-    );
-
-    $template_datas['language_list'] = array();
-    foreach($this->config['amm_links_title'] as $key => $val)
-    {
-      $template_datas['language_list'][] = array(
-        'LANG' => $key,
-        'MENUBARTIT' => base64_decode($val)
-      );
-    }
-
-
 
     $lang=get_languages();
     foreach($lang as $key => $val)
     {
-      $template_datas['language_list_values'][] = $key;
-      $template_datas['language_list_labels'][] = $val;
-    }
-
-
-    $template_datas['yesno_values'] = array('y','n');
-    $template_datas['yesno_labels'][] = l10n('g002_yesno_y');
-    $template_datas['yesno_labels'][] = l10n('g002_yesno_n');
-
-
-    $template->assign("datas", $template_datas);
+      $datas['langs'][$key] = $val;
+      $datas['config']['blockTitles'][$key] = isset($this->config['amm_randompicture_title'][$key])?base64_decode($this->config['amm_randompicture_title'][$key]):'';
+    }
+
+    $template->assign("datas", $datas);
+
     $template->assign_var_from_handle('AMM_BODY_PAGE', 'body_page');
-  }
+    $template->assign('pageNfo', l10n('g002_randompict_nfo'));
+  }
+
+  /**
+   * display the personnal blocks management page
+   */
+  private function displayPersonalisedBlockPage()
+  {
+    global $template, $user;
+
+    GPCCore::addHeaderJS('jquery.ui', 'themes/default/js/ui/packed/ui.core.packed.js');
+    GPCCore::addHeaderJS('jquery.ui.dialog', 'themes/default/js/ui/packed/ui.dialog.packed.js');
+    GPCCore::addUI('inputList,inputText,inputRadio,googleTranslate');
+    GPCCore::addHeaderJS('amm.upbm', 'plugins/AMenuManager/js/amm_personalisedBlocks'.GPCCore::getMinified().'.js');
+
+
+    $template->set_filename('body_page',
+                            dirname($this->getFileLocation()).'/admin/amm_personalised.tpl');
+
+    $datas=array(
+      'selectedLang' => $user['language'],
+      'fromLang' => substr($user['language'],0,2),
+      'langs' => get_languages()
+    );
+
+    $template->assign("datas", $datas);
+
+    $template->assign_var_from_handle('AMM_BODY_PAGE', 'body_page');
+    $template->assign('pageNfo', l10n('g002_personnalblock_nfo'));
+  }
+
+  /**
+   * display the core blocks menu management page
+   */
+  private function displayBlocksPage($tab)
+  {
+    global $template, $conf;
+
+    GPCCore::addHeaderJS('jquery.ui', 'themes/default/js/ui/packed/ui.core.packed.js');
+    GPCCore::addHeaderJS('jquery.ui.sortable', 'themes/default/js/ui/packed/ui.sortable.packed.js');
+    GPCCore::addUI('inputList');
+    GPCCore::addHeaderJS('amm.cbm', 'plugins/AMenuManager/js/amm_blocks'.GPCCore::getMinified().'.js');
+
+    $template->set_filename('body_page',
+                            dirname($this->getFileLocation()).'/admin/amm_coreBlocks.tpl');
+
+    $blocksTabsheet = new GPCTabSheet('blocksTabsheet', $this->tabsheet->get_titlename(), 'tabsheet2 gcBorder', 'itab2');
+    $blocksTabsheet->add('position',
+                          l10n('g002_setting_blocks_position'),
+                          '', false, "cbm.displayTabContent('position');");
+    $blocksTabsheet->add('config',
+                          l10n('g002_setting_core_blocks_content'),
+                          '', false, "cbm.displayTabContent('blocksContent');");
+    $blocksTabsheet->select($tab);
+    $blocksTabsheet->assign();
+
+
+    $users=new GPCUsers();
+    $groups=new GPCGroups();
+
+    $this->sortCoreBlocksItems();
+
+    foreach($this->config['amm_blocks_items'] as $menuId=>$menu)
+    {
+      $this->config['amm_blocks_items'][$menuId]['visibilityForm'] = $this->makeBlockVisibility($menu['visibility'], $menuId);
+      $this->config['amm_blocks_items'][$menuId]['translation']=$this->defaultMenus[$menuId]['translation'];
+      $this->defaultMenus[$menuId]['visibilityForm'] = $this->makeBlockVisibility("/", $menuId);
+    }
+
+    $registeredBlocks=$this->getRegisteredBlocks();
+    foreach($registeredBlocks as $key=>$val)
+    {
+      $registeredBlocks[$key]['users']=json_encode($registeredBlocks[$key]['users']);
+      $registeredBlocks[$key]['groups']=json_encode($registeredBlocks[$key]['groups']);
+    }
+
+    $datas=array(
+      'tab' => $tab,
+      'users' => $users->getList(),
+      'groups' => $groups->getList(),
+      'coreBlocks' => array(
+            'blocks' => $this->blocksId,
+            'defaultValues' => $this->defaultMenus,
+            'items' => $this->config['amm_blocks_items']
+          ),
+      'menuBlocks' => $registeredBlocks
+    );
+
+    $template->assign("datas", $datas);
+
+    $template->assign_var_from_handle('AMM_BODY_PAGE', 'body_page');
+    $template->assign('pageNfo', l10n('g002_setmenu_nfo'));
+  }
+
+
+
+  /**
+   * display the album to menu management page
+   */
+  private function displayAlbumPage()
+  {
+    global $template, $user;
+
+    GPCCore::addHeaderCSS('gpc.categorySelector', 'plugins/GrumPluginClasses/css/categorySelector_'.$template->get_themeconf('name').'.css');
+    GPCCore::addHeaderJS('jquery.ui', 'themes/default/js/ui/packed/ui.core.packed.js');
+    GPCCore::addHeaderJS('gpc.categorySelector', 'plugins/GrumPluginClasses/js/ui.categorySelector'.GPCCore::getMinified().'.js');
+    GPCCore::addHeaderJS('amm.ac', 'plugins/AMenuManager/js/amm_albumConfig'.GPCCore::getMinified().'.js');
+
+    $template->set_filename('body_page',
+                            dirname($this->getFileLocation()).'/admin/amm_album.tpl');
+
+    $datas=array(
+      'albums' => json_encode($this->config['amm_albums_to_menu'])
+    );
+
+    $template->assign("datas", $datas);
+
+    $template->assign_var_from_handle('AMM_BODY_PAGE', 'body_page');
+    $template->assign('pageNfo', l10n('g002_album_nfo'));
+  }
+
 
   /*
-    manage display for urls create/modify page
-  */
-  private function display_links_manage_page($modeedit = 'create', $urlid=0)
+   *  ---------------------------------------------------------------------------
+   * links functionnalities
+   * ---------------------------------------------------------------------------
+   */
+
+  /**
+   * display the links management page
+   */
+  private function displayLinksPageLinks()
   {
     global $template, $user;
-    $template->set_filename('body_page',
-                            dirname($this->getFileLocation()).'/admin/amm_linkslist_edit.tpl');
-
-    $extensions_list=array('jpg'=>0,'jpeg'=>0,'gif'=>0,'png'=>0);
-    $template_icons_list=array();
+
+    GPCCore::addUI('inputList,inputRadio,inputText,inputCheckbox');
+    GPCCore::addHeaderJS('amm.ulm', 'plugins/AMenuManager/js/amm_links'.GPCCore::getMinified().'.js');
+
+    $template->set_filename('sheet_page',
+                            dirname($this->getFileLocation()).'/admin/amm_linkslinks.tpl');
+
+    $users=new GPCUsers();
+    $groups=new GPCGroups();
+
+    $datas=array(
+      'access' => array('users' => $users->getList(), 'groups' => $groups->getList()),
+      'iconsValues' => array(),
+      'modesValues' => array(
+        array(
+          'value' => 0,
+          'label' => l10n("g002_mode_".$this->urlsModes[0])
+        ),
+        array(
+          'value' => 1,
+          'label' => l10n("g002_mode_".$this->urlsModes[1])
+        )
+      )
+    );
+
     $directory=dir(dirname($this->getFileLocation()).'/links_pictures/');
     while($file=$directory->read())
     {
-      if(isset($extensions_list[get_extension(strtolower($file))]))
+      if(in_array(get_extension(strtolower($file)), array('jpg', 'jpeg','gif','png')))
       {
-        $template_icons_list[]=$file;
+        $datas['iconsValues'][] = array(
+          'img' => AMM_PATH."links_pictures/".$file,
+          'value' => $file,
+          'label' => $file
+        );
       }
     }
 
-
-    if($modeedit=='modify')
-    {
-      $url=$this->get_url($urlid);
-
-      $template_datas=array(
-        'id' => $urlid,
-        'modeedit' => 'modify',
-        'label' => htmlentities($url['label'], ENT_QUOTES, 'UTF-8'),
-        'url' => $url['url'],
-        'icons_selected' => $url['icon'],
-        'mode_selected' => $url['mode'],
-        'visible_selected' => $url['visible']
-      );
-    }
-    else
-    {
-      $template_datas=array(
-        'id' => '',
-        'modeedit' => 'create',
-        'label' => '',
-        'url' => '',
-        'icons_selected' => $template_icons_list[0],
-        'mode_selected' => 0,
-        'visible_selected' => 'y'
-      );
-    }
-
-    $template_datas['lnk_list'] = $this->getAdminLink().'&amp;fAMM_tabsheet=links';
-    $template_datas['icons_img'] = AMM_PATH."links_pictures/".$template_datas['icons_selected'];
-    $template_datas['icons_values'] = array();
-    foreach($template_icons_list as $key => $val)
-    {
-      $template_datas['icons_values'][] = array(
-        'img' => AMM_PATH."links_pictures/".$val,
-        'value' => $val,
-        'label' => $val
-      );
-    }
-    $template_datas['mode_values'] = array(0,1);
-    $template_datas['mode_labels'][] = l10n("g002_mode_".$this->urls_modes[0]);
-    $template_datas['mode_labels'][] = l10n("g002_mode_".$this->urls_modes[1]);
-    $template_datas['visible_values'] = array('y','n');
-    $template_datas['visible_labels'][] = l10n('g002_yesno_y');
-    $template_datas['visible_labels'][] = l10n('g002_yesno_n');
-
-    $template->assign("datas", $template_datas);
-    $template->assign_var_from_handle('AMM_BODY_PAGE', 'body_page');
-  }
-
-  /*
-    manage create/modify url into database and display result
-  */
-  protected function action_create_modify_url()
-  {
+    $template->assign("datas", $datas);
+
+    return($template->parse('sheet_page', true));
+  }
+
+  /**
+   * display the links config page
+   */
+  private function displayLinksPageConfig()
+  {
+    global $template, $user;
+
+    GPCCore::addUI('inputList,inputRadio,inputText,googleTranslate');
+    GPCCore::addHeaderJS('amm.ulc', 'plugins/AMenuManager/js/amm_linksConfig'.GPCCore::getMinified().'.js');
+
+    $template->set_filename('sheet_page',
+                            dirname($this->getFileLocation()).'/admin/amm_linksconfig.tpl');
+
     $datas=array(
-      'id' => $_POST['famm_id'],
-      'label' => $_POST['famm_label'],
-      'url' => $_POST['famm_url'],
-      'mode' => $_POST['famm_mode'],
-      'icon' => $_POST['famm_icon'],
-      'position' => 0,
-      'visible' => $_POST['famm_visible']
+      'config' => array(
+          'showIcons' => $this->config['amm_links_show_icons'],
+          'titles' => array()
+        ),
+      'selectedLang' => $user['language'],
+      'fromLang' => substr($user['language'],0,2),
+      'langs' => array()
     );
-
-    switch($_POST['famm_modeedit'])
-    {
-      case 'create':
-        $this->add_url($datas);
-        break;
-      case 'modify':
-        $this->modify_url($datas);
-    }
-  }
-
-  /*
-    manage urls config save into database
-  */
-  protected function action_links_modify_config()
-  {
-    $this->config['amm_links_show_icons']=$_POST['famm_links_show_icons'];
-    $languages=get_languages();
-    foreach($languages as $key => $val)
-    {
-      $this->config['amm_links_title'][$key]=base64_encode($_POST['famm_links_title_'.$key]);
-    }
-    $this->saveConfig();
-  }
-
-  /*
-    manage randompic config save into database
-  */
-  protected function action_randompic_modify_config()
-  {
-    $this->config['amm_randompicture_height']=$_POST['famm_randompicture_height'];
-    $this->config['amm_randompicture_periodicchange']=$_POST['famm_randompicture_periodicchange'];
-    $this->config['amm_randompicture_showname']=$_POST['famm_randompicture_showname'];
-    $this->config['amm_randompicture_showcomment']=$_POST['famm_randompicture_showcomment'];
-    $languages=get_languages();
-    foreach($languages as $key => $val)
-    {
-      $this->config['amm_randompicture_title'][$key]=base64_encode(stripslashes($_POST['famm_randompicture_title_'.$key]));
-    }
-    $this->saveConfig();
-  }
-
-
-
-  /*
-    manage display for sections table page
-  */
-  private function display_sections_page()
-  {
-    global $template, $user, $page;
-    $template->set_filename('body_page', dirname($this->getFileLocation()).'/admin/amm_sections.tpl');
-
-    if(isset($_POST['fList']) && !$this->adviser_abort())
-    {
-      /* the returned information in the fList form element are
-       *  a list of ecah item, separate with a ";"
-       *  each item have properties separated by a ","
-       *   id, container, order, visibility
-      */
-      $items=explode(";",$_POST['fList']);
-      for($i=0;$i<count($items)-1;$i++)
-      {
-        $properties=explode("#", $items[$i]);
-        $properties[0]=explode(",", $properties[0]);
-        $this->config['amm_sections_items'][$properties[0][0]]['container']=$properties[0][1];
-        $this->config['amm_sections_items'][$properties[0][0]]['order']=$properties[0][2];
-        $this->config['amm_sections_items'][$properties[0][0]]['visibility']=$properties[1];
-      }
-      $this->sortSectionsItems();
-      if($this->saveConfig())
-      {
-        array_push($page['infos'], l10n('g002_config_saved'));
-      }
-      else
-      {
-        array_push($page['errors'], l10n('g002_adviser_not_allowed'));
-      }
-    }
-
-    foreach($this->config['amm_sections_items'] as $key=>$val)
-    {
-      $this->config['amm_sections_items'][$key]['visibilityForm'] = $this->makeVisibility($val['visibility'], $key);
-      $this->defaultMenus[$key]['visibilityForm'] = $this->makeVisibility("guest,generic,normal,webmaster,admin/", $key);
-    }
-
-    $this->sortSectionsItems();
-
-    $users=new GPCUsers("");
-    $groups=new GPCGroups("");
-
-
-    $template->assign("visibility", Array('users' => $users->access_list, 'groups' => $groups->access_list));
-    $template->assign("sections", $this->sectionsId);
-    $template->assign("defaultValues", $this->defaultMenus);
-    $template->assign("items", $this->config['amm_sections_items']);
-    $template->assign_var_from_handle('AMM_BODY_PAGE', 'body_page');
-  }
-
-
-  /*
-    manage display for randompic config page
-  */
-  private function display_randompic_config_page()
-  {
-    global $template, $user;
-    $template->set_filename('body_page',
-                            dirname($this->getFileLocation()).'/admin/amm_randompicconfig.tpl');
-
-    $template_datas=array(
-      'lnk_list' => $this->getAdminLink().'&amp;fAMM_tabsheet=links',
-      'showname_selected' => $this->config['amm_randompicture_showname'],
-      'showcomment_selected' => $this->config['amm_randompicture_showcomment'],
-      'periodic_change' => $this->config['amm_randompicture_periodicchange'],
-      'height' => $this->config['amm_randompicture_height'],
-      'lang_selected' => $user['language'],
-      'fromlang' => substr($user['language'],0,2)
-    );
-
-    $template_datas['language_list'] = array();
-    foreach($this->config['amm_randompicture_title'] as $key => $val)
-    {
-      $template_datas['language_list'][] = array(
-        'LANG' => $key,
-        'MENUBARTIT' => htmlentities(base64_decode($val), ENT_QUOTES, 'UTF-8')
-      );
-    }
-
-
 
     $lang=get_languages();
     foreach($lang as $key => $val)
     {
-      $template_datas['language_list_values'][] = $key;
-      $template_datas['language_list_labels'][] = $val;
-    }
-
-
-    $template_datas['yesno_values'] = array('y','n');
-    $template_datas['yesno_labels'][] = l10n('g002_yesno_y');
-    $template_datas['yesno_labels'][] = l10n('g002_yesno_n');
-
-    $template_datas['show_values'] = array('n', 'o', 'u');
-    $template_datas['show_labels'][] = l10n('g002_show_n');
-    $template_datas['show_labels'][] = l10n('g002_show_o');
-    $template_datas['show_labels'][] = l10n('g002_show_u');
-
-
-    $template->assign("datas", $template_datas);
-    $template->assign_var_from_handle('AMM_BODY_PAGE', 'body_page');
-  }
-
-
-
-
+      $datas['langs'][$key] = $val;
+      $datas['config']['titles'][$key] = isset($this->config['amm_links_title'][$key])?base64_decode($this->config['amm_links_title'][$key]):'';
+    }
+
+    $template->assign("datas", $datas);
+    return($template->parse('sheet_page', true));
+  }
 
 
 
   /*
-    manage display for personalised sections list page
+   * ---------------------------------------------------------------------------
+   * blocks functionnalities
+   * ---------------------------------------------------------------------------
+   */
+
+  /**
+   * this function returns an HTML FORM to use with each menu items
+   *
+   * @param String $visibility : a formatted string like :
+   *                              users type1(,users typeX)/(groupId0)(,groupIdX)
+   * @param String $blockId    : block Id
+   * @return String : html ready to use
   */
-  private function display_personalised_list_page()
-  {
-    global $template, $user;
-    $template->set_filename('body_page',
-                            dirname($this->getFileLocation()).'/admin/amm_personalisedlist.tpl');
-
-    $sql="SELECT COUNT(DISTINCT ID) as countid FROM ".$this->tables['personalised'];
-    $result=pwg_query($sql);
-    if($result)
-    {
-      $tmp=pwg_db_fetch_row($result);
-      $tmp=$tmp[0];
-    }
-    else
-    {
-      $tmp=0;
-    }
-
-    if($tmp==0)
-    {
-      $tmp=l10n("g002_nosections");
-    }
-    elseif($tmp==1)
-    {
-      $tmp="1 ".l10n("g002_section");
-    }
-    else
-    {
-      $tmp=$tmp." ".l10n("g002_sections");
-    }
-
-
-    $template_datas=array(
-      'lnk_create' => $this->getAdminLink().'&amp;fAMM_tabsheet=personnalblock&amp;action=create',
-      'AMM_AJAX_URL_LIST' => $this->getAdminLink()."&ajaxfct=",
-      'nbsections' => $tmp
-    );
-
-    $template->assign("datas", $template_datas);
-    $template->assign_var_from_handle('AMM_BODY_PAGE', 'body_page');
-  }
-
-
-
-  /*
-    manage display for personalised sections create/modify page
-  */
-  private function display_personalised_manage_page($modeedit = 'create', $sectionid=0)
-  {
-    global $template, $user;
-    $template->set_filename('body_page',
-                            dirname($this->getFileLocation()).'/admin/amm_personalisedlist_edit.tpl');
-
-    $template_datas=array();
-
-    $lang=get_languages();
-    $lang['all']=l10n('g002_all_languages');
-    foreach($lang as $key => $val)
-    {
-      $template_datas['language_list_values'][] = $key;
-      $template_datas['language_list_labels'][] = $val;
-      $template_datas['language_list'][$key]=array(
-        'LANG' => $key,
-        'MENUBARTIT' => '',
-        'MENUBARCONTENT' => ''
-      );
-    }
-
-
-    if($modeedit=='modify')
-    {
-      $sections=$this->get_personalised($sectionid);
-
-      $template_datas['id'] = $sectionid;
-      $template_datas['modeedit'] = 'modify';
-      $template_datas['visible_selected'] = $sections[0]['visible'];
-      $template_datas['nfo'] = htmlentities($sections[0]['nfo'], ENT_QUOTES, 'UTF-8');
-
-      foreach($sections as $key => $val)
-      {
-        $lang=($val['lang']=='*')?'all':$val['lang'];
-        $template_datas['language_list'][$lang] = array(
-          'LANG' => $lang,
-          'MENUBARTIT' => htmlentities($val['title'], ENT_QUOTES, 'UTF-8'),
-          'MENUBARCONTENT' => htmlentities($val['content'], ENT_QUOTES, 'UTF-8'),
-        );
-      }
-    }
-    else
-    {
-      $template_datas['nfo'] = '';
-      $template_datas['id'] = '';
-      $template_datas['modeedit'] = 'create';
-      $template_datas['visible_selected'] = 'y';
-    }
-
-    $template_datas['lang_selected'] = $user['language'];
-
-    $template_datas['personalised_list'] = $this->getAdminLink().'&amp;fAMM_tabsheet=personnalblock';
-    $template_datas['yesno_values'] = array('y','n');
-    $template_datas['yesno_labels'][] = l10n('g002_yesno_y');
-    $template_datas['yesno_labels'][] = l10n('g002_yesno_n');
-
-    $template->assign("datas", $template_datas);
-    $template->assign_var_from_handle('AMM_BODY_PAGE', 'body_page');
-  }
-
-  /*
-    manage create/modify pesonalised sections into database and display result
-  */
-  protected function action_create_modify_personalised()
-  {
-    global $user;
-
-    if($_POST['famm_modeedit']=='create')
-    {
-      $id=$this->get_personalised_id();
-    }
-    else
-    {
-      $id=$_POST['famm_id'];
-    }
-    $languages=get_languages();
-    $languages['all']='*';
-    foreach($languages as $key => $val)
-    {
-      $datas=array(
-        'id' => $id,
-        'lang' => ($key=='all')?'*':$key,
-        'visible' => $_POST['famm_personalised_visible'],
-        'nfo' => ($_POST['famm_personalised_nfo']=='')?$_POST['famm_personalised_title_'.$user['language']]:$_POST['famm_personalised_nfo'],
-        'title' => $_POST['famm_personalised_title_'.$key],
-        'content' => $_POST['famm_personalised_content_'.$key]
-      );
-      switch($_POST['famm_modeedit'])
-      {
-        case 'create':
-          $this->add_personalised($datas);
-          break;
-        case 'modify':
-          $this->modify_personalised($datas);
-      }
-    }
-  }
-
-
-
-  /* this function returns an HTML FORM to use with each menu items
-   * $visibility is a formatted string looking this :
-   *   users type1(,users typeX)/(groupId0)(,groupIdX))
-  */
-  private function makeVisibility($visibility, $id)
+  private function makeBlockVisibility($visibility, $menuId)
   {
     $local_tpl = new Template(AMM_PATH."admin/", "");
     $local_tpl->set_filename('body_page',
-                  dirname($this->getFileLocation()).'/admin/amm_sections_visibility.tpl');
+                  dirname($this->getFileLocation()).'/admin/amm_coreBlocks_detail.tpl');
 
 
     $parameters=explode("/", $visibility);
 
-    $users=new GPCUsers(str_replace(",", "/", $parameters[0]));
-    $users->setAllowed('admin', true);
-    $groups=new GPCGroups(str_replace(",", "/", $parameters[1]));
-
-    $local_tpl->assign('name', $id);
-    $local_tpl->assign('users', $users->access_list);
-    $local_tpl->assign('groups', $groups->access_list);
+    /* submenu access system is :
+     *  - by default, everything is accesible
+     *  - items not accessible are defined
+     */
+    $users=new GPCUsers();
+    $users->setAlloweds(explode(',', $parameters[0]), false);
+    $groups=new GPCGroups();
+    $groups->setAlloweds(explode(',', $parameters[1]), false);
+
+    $local_tpl->assign('name', $menuId);
+    $local_tpl->assign('users', $users->getList());
+    $local_tpl->assign('groups', $groups->getList());
 
     return($local_tpl->parse('body_page', true));
@@ -769,275 +499,4 @@
 
 
-
-  /*
-    manage adviser profile
-      return true if user is adviser
-  */
-  protected function adviser_abort()
-  {
-    if(is_adviser())
-    {
-      $this->displayResult(l10n("g002_adviser_not_allowed"), false);
-      return(true);
-    }
-    return(false);
-  }
-
-
-
-  /* ---------------------------------------------------------------------------
-    functions to manage urls tables
-  --------------------------------------------------------------------------- */
-  // protected function get_urls()
-  // protected function get_count_url()
-  // => defined in root class
-
-  // return properties of an given url
-  private function get_url($url_id)
-  {
-    $returned=array();
-    $sql="SELECT * FROM ".$this->tables['urls']." WHERE id = '".$url_id."'";
-    $result=pwg_query($sql);
-    if($result)
-    {
-      $returned=pwg_db_fetch_assoc($result);
-      //$returned['label']=stripslashes($returned['label']);
-    }
-    return($returned);
-  }
-
-  // permut position of two 2 urls
-  private function permut_url($url_id, $url_permut)
-  {
-    $sql="SELECT id, position FROM ".$this->tables['urls']." WHERE id IN ('".$url_id."','".$url_permut."')";
-    $result=pwg_query($sql);
-    if($result)
-    {
-      $tmp=array();
-      while($row=pwg_db_fetch_assoc($result))
-      {
-        $tmp[$row['id']]=$row['position'];
-      }
-      $sql="UPDATE ".$this->tables['urls']." SET position = ".$tmp[$url_id]." WHERE id = '".$url_permut."'";
-      pwg_query($sql);
-      $sql="UPDATE ".$this->tables['urls']." SET position = ".$tmp[$url_permut]." WHERE id = '".$url_id."'";
-      pwg_query($sql);
-    }
-  }
-
-  // delete an url
-  private function delete_url($url_id)
-  {
-    $sql="DELETE FROM ".$this->tables['urls']." WHERE id = '".$url_id."' ";
-    return(pwg_query($sql));
-  }
-
-  // add an url
-  private function add_url($datas)
-  {
-    $numurl=$this->get_count_url();
-    $sql="INSERT INTO ".$this->tables['urls']." (label, url, mode, icon, position, visible)
-          VALUES ('".$datas['label']."', '".$datas['url']."', '".$datas['mode']."',
-                  '".$datas['icon']."', '".$numurl."', '".$datas['visible']."')";
-    return(pwg_query($sql));
-  }
-
-  // modify an url
-  private function modify_url($datas)
-  {
-    $sql="UPDATE ".$this->tables['urls']." SET label = '".$datas['label']."',
-          url = '".$datas['url']."', mode = '".$datas['mode']."', icon = '".$datas['icon']."',
-          visible = '".$datas['visible']."'
-          WHERE id = '".$datas['id']."'";
-    return(pwg_query($sql));
-  }
-
-  // just modify url visibility
-  private function set_url_visibility($urlid, $visible)
-  {
-    $sql="UPDATE ".$this->tables['urls']." SET visible = '".$visible."'
-          WHERE id = '".$urlid."'";
-    return(pwg_query($sql));
-  }
-
-
-
-  /* ---------------------------------------------------------------------------
-    functions to manage sections tables
-  --------------------------------------------------------------------------- */
-  // protected function get_sections($only_visible=false, $lang="")
-  // => defined in root class
-
-  // return properties of a given section (return each languages)
-  private function get_personalised($section_id)
-  {
-    $returned=array();
-    $sql="SELECT * FROM ".$this->tables['personalised']." WHERE id = '".$section_id."'";
-    $result=pwg_query($sql);
-    if($result)
-    {
-      while($returned[]=pwg_db_fetch_assoc($result));
-    }
-    return($returned);
-  }
-
-  // delete a section
-  private function delete_personalised($section_id)
-  {
-    $sql="DELETE FROM ".$this->tables['personalised']." WHERE id = '".$section_id."' ";
-    return(pwg_query($sql));
-  }
-
-  // add a section
-  private function add_personalised($datas)
-  {
-    $sql="INSERT INTO ".$this->tables['personalised']." (id, lang, title, content, visible, nfo)
-          VALUES ('".$datas['id']."', '".$datas['lang']."', '".$datas['title']."', '".$datas['content']."', '".$datas['visible']."', '".$datas['nfo']."')";
-    return(pwg_query($sql));
-  }
-
-  // modify a section
-  private function modify_personalised($datas)
-  {
-    $sql="UPDATE ".$this->tables['personalised']." SET title = '".$datas['title']."',
-          content = '".$datas['content']."',  visible = '".$datas['visible']."',
-          nfo = '".$datas['nfo']."'
-          WHERE id = '".$datas['id']."'
-          AND lang = '".$datas['lang']."'";
-    return(pwg_query($sql));
-  }
-
-  // return the next personalised id
-  private function get_personalised_id()
-  {
-    $sql='SELECT MAX(ID) FROM '.$this->tables['personalised'];
-    $result=pwg_query($sql);
-    if($result)
-    {
-      $row=pwg_db_fetch_row($result);
-      if(is_array($row))
-      {
-        return($row[0]+1);
-      }
-    }
-    return(0);
-  }
-
-
-
-
-
-  /* ---------------------------------------------------------------------------
-    ajax functions
-  --------------------------------------------------------------------------- */
-
-  // return a html formatted list of urls
-  private function ajax_amm_links_list()
-  {
-    global $template, $user;
-    $local_tpl = new Template(AMM_PATH."admin/", "");
-    $local_tpl->set_filename('body_page',
-                  dirname($this->getFileLocation()).'/admin/amm_linkslist_detail.tpl');
-
-    $template_datas['urls']=array();
-    $urls=$this->get_urls();
-    for($i=0;$i<count($urls);$i++)
-    {
-      $template_datas['urls'][]=array(
-        'img' => AMM_PATH."links_pictures/".$urls[$i]['icon'],
-        'label' => $urls[$i]['label'],
-        'url' => $urls[$i]['url'],
-        'mode' => l10n("g002_mode_".$this->urls_modes[$urls[$i]['mode']]),
-        'up' =>  ($i==0)?false:true,
-        'down' =>  ($i<(count($urls)-1))?true:false,
-        'edit' => $this->getAdminLink().'&amp;fAMM_tabsheet=links&amp;action=modify&amp;fItem='.$urls[$i]['id'],
-        'ID' => $urls[$i]['id'],
-        'IDPREV' => ($i==0)?0:$urls[$i-1]['id'],
-        'IDNEXT' => ($i<(count($urls)-1))?$urls[$i+1]['id']:0,
-        'visible' => l10n('g002_yesno_'.$urls[$i]['visible'])
-      );
-    }
-
-    $themeconf=array(
-      'icon_dir' => $template->get_themeconf('icon_dir')
-    );
-
-    $local_tpl->assign('themeconf', $themeconf);
-    $local_tpl->assign('datas', $template_datas);
-    $local_tpl->assign('plugin', array('PATH' => AMM_PATH));
-
-    return($local_tpl->parse('body_page', true));
-  }
-
-  // permut position of 2 urls and returns a html formatted list of urls
-  private function ajax_amm_links_permut($urlid, $urlpermut)
-  {
-    $this->permut_url($urlid, $urlpermut);
-    return($this->ajax_amm_links_list());
-  }
-
-  // delete an url and returns a html formatted list of urls
-  private function ajax_amm_links_delete($urlid)
-  {
-    if(!$this->adviser_abort())
-    {
-      $this->delete_url($urlid);
-    }
-    return($this->ajax_amm_links_list());
-  }
-
-
-
-
-
-  // return a html formatted list of personalised sections
-  private function ajax_amm_personalised_list()
-  {
-    global $template, $user;
-    $local_tpl = new Template(AMM_PATH."admin/", "");
-    $local_tpl->set_filename('body_page',
-                  dirname($this->getFileLocation()).'/admin/amm_personalisedlist_detail.tpl');
-
-    $template_datas['sections']=array();
-
-    $sections=$this->get_sections(false, '', false);
-    $is_done=array();
-    foreach($sections as $key => $val)
-    {
-      if(!isset($is_done[$val['id']]))
-      {
-        $template_datas['sections'][]=array(
-          'title' => ($val['title']!='')?$val['title']:l10n('g002_notitle'),
-          'edit' => $this->getAdminLink().'&amp;fAMM_tabsheet=personnalblock&amp;action=modify&amp;fItem='.$val['id'],
-          'ID' => $val['id'],
-          'visible' => l10n('g002_yesno_'.$val['visible']),
-          'nfo' => $val['nfo']
-        );
-        $is_done[$val['id']]='';
-      }
-    }
-
-    $themeconf=array(
-      'icon_dir' => $template->get_themeconf('icon_dir')
-    );
-
-    $local_tpl->assign('themeconf', $themeconf);
-    $local_tpl->assign('datas', $template_datas);
-    $local_tpl->assign('plugin', array('PATH' => AMM_PATH));
-
-    return($local_tpl->parse('body_page', true));
-  }
-
-  // delete a section and returns a html formatted list
-  private function ajax_amm_personalised_delete($sectionid)
-  {
-    if(!$this->adviser_abort())
-    {
-      $this->delete_personalised($sectionid);
-    }
-    return($this->ajax_amm_personalised_list());
-  }
-
-
 } // AMM_AIP class
 
Index: /extensions/AMenuManager/amm_ajax.php
===================================================================
--- /extensions/AMenuManager/amm_ajax.php	(revision 8962)
+++ /extensions/AMenuManager/amm_ajax.php	(revision 8962)
@@ -0,0 +1,653 @@
+<?php
+/*
+ * -----------------------------------------------------------------------------
+ * Plugin Name: Advanced Menu Manager
+ * -----------------------------------------------------------------------------
+ * Author     : Grum
+ *   email    : grum@piwigo.org
+ *   website  : http://photos.grum.fr
+ *   PWG user : http://forum.piwigo.org/profile.php?id=3706
+ *
+ *   << May the Little SpaceFrog be with you ! >>
+ *
+ * -----------------------------------------------------------------------------
+ *
+ * See main.inc.php for release information
+ *
+ * manage all the ajax requests
+ * -----------------------------------------------------------------------------
+ */
+
+
+  define('PHPWG_ROOT_PATH',dirname(dirname(dirname(__FILE__))).'/');
+
+  /*
+   * set ajax module in admin mode if request is used for admin interface
+   */
+  if(!isset($_REQUEST['ajaxfct'])) $_REQUEST['ajaxfct']='';
+  if(preg_match('/^admin\./i', $_REQUEST['ajaxfct']))
+  {
+    define('IN_ADMIN', true);
+  }
+
+  // the common.inc.php file loads all the main.inc.php plugins files
+  include_once(PHPWG_ROOT_PATH.'include/common.inc.php' );
+  include_once(PHPWG_PLUGINS_PATH.'GrumPluginClasses/classes/GPCAjax.class.inc.php');
+  include_once('amm_root.class.inc.php');
+
+  load_language('plugin.lang', AMM_PATH);
+
+
+  class AMM_Ajax extends AMM_root
+  {
+    /**
+     * constructor
+     */
+    public function __construct($prefixeTable, $filelocation)
+    {
+      parent::__construct($prefixeTable, $filelocation);
+      $this->loadConfig();
+      $this->checkRequest();
+      $this->returnAjaxContent();
+    }
+
+    /**
+     * check the $_REQUEST values and set default values
+     *
+     */
+    protected function checkRequest()
+    {
+      global $user;
+
+      if(!isset($_REQUEST['ajaxfct'])) $_REQUEST['ajaxfct']='';
+      if(!isset($_REQUEST['errcode'])) $_REQUEST['errcode']='';
+      if(!isset($_REQUEST['token'])) $_REQUEST['token']='';
+
+      // check if asked function is valid
+      if(!($_REQUEST['ajaxfct']=='admin.links.get' or
+           $_REQUEST['ajaxfct']=='admin.links.set' or
+           $_REQUEST['ajaxfct']=='admin.links.list' or
+           $_REQUEST['ajaxfct']=='admin.links.delete' or
+           $_REQUEST['ajaxfct']=='admin.links.order' or
+           $_REQUEST['ajaxfct']=='admin.links.setConfig' or
+           $_REQUEST['ajaxfct']=='admin.randomPict.setConfig' or
+           $_REQUEST['ajaxfct']=='admin.blocks.get' or
+           $_REQUEST['ajaxfct']=='admin.blocks.set' or
+           $_REQUEST['ajaxfct']=='admin.blocks.delete' or
+           $_REQUEST['ajaxfct']=='admin.blocks.list' or
+           $_REQUEST['ajaxfct']=='admin.album.setConfig' or
+           $_REQUEST['ajaxfct']=='admin.coreBlocks.setConfig'
+           )) $_REQUEST['ajaxfct']='';
+
+      if(preg_match('/^admin\./i', $_REQUEST['ajaxfct']) and !is_admin()) $_REQUEST['ajaxfct']='';
+
+
+      if($_REQUEST['ajaxfct']!='')
+      {
+        /*
+         * no check for admin.links.list request
+         */
+
+        /*
+         * check admin.links.get request
+         * check admin.blocks.get request
+         */
+        if($_REQUEST['ajaxfct']=='admin.links.get' or
+           $_REQUEST['ajaxfct']=='admin.blocks.get request')
+        {
+          if(!isset($_REQUEST['id'])) $_REQUEST['id']='';
+
+          if($_REQUEST['id']=='') $_REQUEST['ajaxfct']='';
+        }
+
+        /*
+         * check admin.links.set request
+         */
+        if($_REQUEST['ajaxfct']=='admin.links.set')
+        {
+          if(!isset($_REQUEST['id'])) $_REQUEST['id']='';
+          if(!isset($_REQUEST['datas']['label'])) $_REQUEST['datas']['label']='';
+          if(!isset($_REQUEST['datas']['url'])) $_REQUEST['datas']['url']='';
+          if(!isset($_REQUEST['datas']['icon'])) $_REQUEST['datas']['icon']='';
+          if(!isset($_REQUEST['datas']['mode'])) $_REQUEST['datas']['mode']='0';
+          if(!isset($_REQUEST['datas']['visible'])) $_REQUEST['datas']['visible']='n';
+          if(!isset($_REQUEST['datas']['accessUsers'])) $_REQUEST['datas']['accessUsers']=array();
+          if(!isset($_REQUEST['datas']['accessGroups'])) $_REQUEST['datas']['accessGroups']=array();
+
+          if($_REQUEST['token']!=get_pwg_token() or
+             $_REQUEST['datas']['label']=='' or
+             $_REQUEST['datas']['url']=='' or
+             $_REQUEST['datas']['icon']=='' or
+             !($_REQUEST['datas']['mode']=='0' or $_REQUEST['datas']['mode']=='1') or
+             !($_REQUEST['datas']['visible']=='y' or $_REQUEST['datas']['visible']=='n')
+            ) $_REQUEST['ajaxfct']='';
+        }
+
+        /*
+         * check admin.links.delete request
+         * check admin.blocks.delete request
+         *
+         */
+        if($_REQUEST['ajaxfct']=='admin.links.delete' or
+           $_REQUEST['ajaxfct']=='admin.blocks.delete')
+        {
+          if(!isset($_REQUEST['id'])) $_REQUEST['id']='';
+
+          if($_REQUEST['id']=='' or
+             $_REQUEST['token']!=get_pwg_token()
+            ) $_REQUEST['ajaxfct']='';
+        }
+
+        /*
+         * check admin.links.order request
+         */
+        if($_REQUEST['ajaxfct']=='admin.links.order')
+        {
+          if(!isset($_REQUEST['datas']['links'])) $_REQUEST['datas']['links']=array();
+
+          if(count($_REQUEST['datas']['links'])<=1 or
+             $_REQUEST['token']!=get_pwg_token()
+            ) $_REQUEST['ajaxfct']='';
+        }
+
+
+        /*
+         * check admin.links.setConfig request
+         */
+        if($_REQUEST['ajaxfct']=='admin.links.setConfig')
+        {
+          if(!isset($_REQUEST['datas']['showIcons'])) $_REQUEST['datas']['showIcons']='';
+          if(!isset($_REQUEST['datas']['title'])) $_REQUEST['datas']['title']=array();
+
+          if($_REQUEST['token']!=get_pwg_token() or
+             $_REQUEST['datas']['showIcons']=='' or
+             count($_REQUEST['datas']['title'])==0
+            ) $_REQUEST['ajaxfct']='';
+        }
+
+
+
+        /*
+         * check admin.randomPict.setConfig request
+         */
+        if($_REQUEST['ajaxfct']=='admin.randomPict.setConfig')
+        {
+          if(!isset($_REQUEST['datas']['blockHeight'])) $_REQUEST['datas']['blockHeight']='';
+          if(!isset($_REQUEST['datas']['blockTitles'])) $_REQUEST['datas']['blockTitles']=array();
+          if(!isset($_REQUEST['datas']['infosName'])) $_REQUEST['datas']['infosName']='';
+          if(!isset($_REQUEST['datas']['infosComment'])) $_REQUEST['datas']['infosComment']='';
+          if(!isset($_REQUEST['datas']['freqDelay'])) $_REQUEST['datas']['freqDelay']='';
+          if(!isset($_REQUEST['datas']['selectMode'])) $_REQUEST['datas']['selectMode']='';
+          if(!isset($_REQUEST['datas']['selectCat'])) $_REQUEST['datas']['selectCat']=array();
+
+          if($_REQUEST['token']!=get_pwg_token() or
+             !is_numeric($_REQUEST['datas']['blockHeight']) or
+             count($_REQUEST['datas']['blockTitles'])==0 or
+             !($_REQUEST['datas']['infosName']=='n' or
+               $_REQUEST['datas']['infosName']=='o' or
+               $_REQUEST['datas']['infosName']=='u') or
+             !($_REQUEST['datas']['infosComment']=='n' or
+               $_REQUEST['datas']['infosComment']=='o' or
+               $_REQUEST['datas']['infosComment']=='u') or
+             !is_numeric($_REQUEST['datas']['freqDelay']) or
+             !($_REQUEST['datas']['selectMode']=='a' or
+               $_REQUEST['datas']['selectMode']=='f' or
+               $_REQUEST['datas']['selectMode']=='c') or
+             ($_REQUEST['datas']['selectMode']=='c' and
+              count($_REQUEST['datas']['selectCat'])==0)
+            ) $_REQUEST['ajaxfct']='';
+        }
+
+
+        /*
+         * check admin.blocks.set request
+         */
+        if($_REQUEST['ajaxfct']=='admin.blocks.set')
+        {
+          if(!isset($_REQUEST['id'])) $_REQUEST['id']='';
+          if(!isset($_REQUEST['datas']['nfo'])) $_REQUEST['datas']['nfo']='';
+          if(!isset($_REQUEST['datas']['visible'])) $_REQUEST['datas']['visible']='';
+          if(!isset($_REQUEST['datas']['langs'])) $_REQUEST['datas']['langs']=array();
+
+          if($_REQUEST['token']!=get_pwg_token() or
+             $_REQUEST['datas']['nfo']=='' or
+             !($_REQUEST['datas']['visible']=='y' or $_REQUEST['datas']['visible']=='n') or
+             count($_REQUEST['datas']['langs'])==0
+            ) $_REQUEST['ajaxfct']='';
+        }
+
+
+
+
+        /*
+         * check admin.coreBlocks.setConfig request
+         */
+        if($_REQUEST['ajaxfct']=='admin.coreBlocks.setConfig')
+        {
+          if(!isset($_REQUEST['datas']['menuItems'])) $_REQUEST['datas']['menuItems']=array();
+          if(!isset($_REQUEST['datas']['blocks'])) $_REQUEST['datas']['blocks']=array();
+
+          if($_REQUEST['token']!=get_pwg_token() or
+             count($_REQUEST['datas']['menuItems'])!=count($this->defaultMenus)
+            ) $_REQUEST['ajaxfct']='';
+        }
+
+
+        /*
+         * check admin.album.setConfig request
+         */
+        if($_REQUEST['ajaxfct']=='admin.album.setConfig')
+        {
+          if(!isset($_REQUEST['datas']['selectCat'])) $_REQUEST['datas']['selectCat']=array();
+
+          if($_REQUEST['token']!=get_pwg_token()) $_REQUEST['ajaxfct']='';
+        }
+
+
+      }
+
+    } //checkRequest
+
+
+    /**
+     * return ajax content
+     */
+    protected function returnAjaxContent()
+    {
+      $result="KO!".l10n('g002_error_invalid_ajax_call');
+      switch($_REQUEST['ajaxfct'])
+      {
+        case 'admin.links.get':
+          $result=$this->ajax_amm_admin_linksGet($_REQUEST['id']);
+          break;
+        case 'admin.links.set':
+          $result=$this->ajax_amm_admin_linksSet($_REQUEST['id'],$_REQUEST['datas']['label'],$_REQUEST['datas']['url'],$_REQUEST['datas']['mode'],$_REQUEST['datas']['icon'],$_REQUEST['datas']['visible'],$_REQUEST['datas']['accessUsers'],$_REQUEST['datas']['accessGroups']);
+          break;
+        case 'admin.links.list':
+          $result=$this->ajax_amm_admin_linksList();
+          break;
+        case 'admin.links.order':
+          $result=$this->ajax_amm_admin_linksOrder($_REQUEST['datas']['links']);
+          break;
+        case 'admin.links.delete':
+          $result=$this->ajax_amm_admin_linksDelete($_REQUEST['id']);
+          break;
+        case 'admin.links.setConfig':
+          $result=$this->ajax_amm_admin_linksSetConfig($_REQUEST['datas']);
+          break;
+
+        case 'admin.randomPict.setConfig':
+          $result=$this->ajax_amm_admin_randomPictSetConfig($_REQUEST['datas']);
+          break;
+
+        case 'admin.blocks.get':
+          $result=$this->ajax_amm_admin_blocksGet($_REQUEST['id']);
+          break;
+        case 'admin.blocks.set':
+          $result=$this->ajax_amm_admin_blocksSet($_REQUEST['id'],$_REQUEST['datas']['visible'],$_REQUEST['datas']['nfo'],$_REQUEST['datas']['langs']);
+          break;
+        case 'admin.blocks.list':
+          $result=$this->ajax_amm_admin_blocksList();
+          break;
+        case 'admin.blocks.delete':
+          $result=$this->ajax_amm_admin_blocksDelete($_REQUEST['id']);
+          break;
+
+        case 'admin.coreBlocks.setConfig':
+          $result=$this->ajax_amm_admin_coreBlocksSetConfig($_REQUEST['datas']['menuItems'], $_REQUEST['datas']['blocks']);
+          break;
+
+        case 'admin.album.setConfig':
+          $result=$this->ajax_amm_admin_albumSetConfig($_REQUEST['datas']);
+          break;
+      }
+      GPCAjax::returnResult($result);
+    }
+
+
+    /*
+     * -------------------------------------------------------------------------
+     *
+     * ADMIN FUNCTIONS
+     *
+     * -------------------------------------------------------------------------
+     */
+
+
+    /*
+     * -------------------------------------------------------------------------
+     * Links
+     * -------------------------------------------------------------------------
+     */
+
+    /**
+     * return a html formatted list of urls
+     */
+    private function ajax_amm_admin_linksList()
+    {
+      global $template, $user;
+      $local_tpl = new Template(AMM_PATH."admin/", "");
+      $local_tpl->set_filename('body_page',
+                    dirname($this->getFileLocation()).'/admin/amm_linkslinks_detail.tpl');
+
+
+
+      $datas['links']=array();
+
+      $links=$this->getLinks();
+      foreach($links as $link)
+      {
+        $datas['links'][]=array(
+          'id' => $link['id'],
+          'label' => $link['label'],
+          'url' => $link['url'],
+          'mode' => l10n("g002_mode_".$this->urlsModes[$link['mode']]),
+          'icon' => "plugins/".AMM_DIR."/links_pictures/".$link['icon'],
+          'visible' => l10n('g002_yesno_'.$link['visible'])
+        );
+      }
+
+      $local_tpl->assign('themeconf', $template->get_template_vars('themeconf'));
+      $local_tpl->assign('datas', $datas);
+      $local_tpl->assign('plugin', array('PATH' => AMM_PATH));
+
+      return($local_tpl->parse('body_page', true));
+    }
+
+
+    /**
+     * update links order
+     *
+     * @param Array $links
+     * @return String : OK or KO
+     */
+    private function ajax_amm_admin_linksOrder($links)
+    {
+      return($this->setLinksOrder($links)?'OK':'KO');
+    }
+
+
+    /**
+     * delete a link
+     *
+     * @param Integer $id : link id
+     * @return String : OK or KO
+     */
+    private function ajax_amm_admin_linksDelete($id)
+    {
+      return($this->deleteLink($id)?'OK':'KO');
+    }
+
+    /**
+     * return link content as a json string
+     *
+     * @param Integer $id : link id
+     * @return String : json string
+     */
+    private function ajax_amm_admin_linksGet($id)
+    {
+      $link=$this->getLink($id);
+      $link['accessUsers']=explode(',', $link['accessUsers']);
+      $link['accessGroups']=explode(',', $link['accessGroups']);
+      return(json_encode($link));
+    }
+
+    /**
+     * set link values
+     * if id is empty, create a new link
+     *
+     * @param String $id : link id
+     * @param String $label : link label
+     * @param String $url : link url
+     * @param String $mode : link mode (open a new window or not)
+     * @param String $icon : displayed icon
+     * @param String $visible : link visibility
+     * @return String : $id if OK, otherwise -1
+     */
+    private function ajax_amm_admin_linksSet($id, $label, $url, $mode, $icon, $visible, $accessUsers, $accessGroups)
+    {
+      return($this->setLink($id, $label, $url, $mode, $icon, $visible, implode(',', $accessUsers), implode(',', $accessGroups)));
+    }
+
+    /**
+     * set the links config
+     *
+     * $config is an array with keys :
+     *  String 'showIcons' : values 'y' or 'n'
+     *  Array  'titles'    : each array occurs is an array('id' => '', 'value' => '')
+     *                            id = lang id ('fr_FR', 'en_UK', ...)
+     *
+     * @param Array $config
+     * @return String : OK or KO
+     */
+    private function ajax_amm_admin_linksSetConfig($config)
+    {
+      $this->config['amm_links_show_icons']=$config['showIcons'];
+
+      $this->config['amm_links_title']=array();
+      foreach($config['title'] as $title)
+      {
+        $this->config['amm_links_title'][$title['id']]=base64_encode($title['value']);
+      }
+
+      $this->saveConfig();
+
+      return('OK!'.l10n('g002_config_saved'));
+    }
+
+
+    /*
+     * -------------------------------------------------------------------------
+     * random picture
+     * -------------------------------------------------------------------------
+     */
+
+
+    /**
+     * set the random picture config
+     *
+     * $config is an array with keys :
+     *  Integer 'blockHeight' : if value=0, the browser assume an automatic size
+     *  Array  'blockTitles'  : each array occurs is an array('id' => '', 'value' => '')
+     *                            id = lang id ('fr_FR', 'en_UK', ...)
+     *  String 'infosName'      : allow to display picture's name ;
+     *                              can take 'n' (no), 'o' (over), or 'u' (under)
+     *  String 'infosComment'   : allow to display picture's comment ;
+     *                              can take 'n' (no), 'o' (over), or 'u' (under)
+     *  Integer 'freqDelay'     : allow to choose change frequency (delay is in
+     *                            milliseconds)
+     *                            if value=0, there is no change
+     *  String 'selectMode'     : allows to choose picture to be randomly selected
+     *                              can take 'a' (all), 'f' (webmaster's favorites), 'c' (from categories)
+     *  Array  'selectCat'      : list of selected categories (choosing a cat implies to choose all sub cat)
+     *
+     * @param Array $config
+     * @return String : OK or KO
+     */
+    private function ajax_amm_admin_randomPictSetConfig($config)
+    {
+      $this->config['amm_randompicture_selectMode']=$config['selectMode'];
+      $this->config['amm_randompicture_selectCat']=$config['selectCat'];
+      $this->config['amm_randompicture_showname']=$config['infosName'];
+      $this->config['amm_randompicture_showcomment']=$config['infosComment'];
+      $this->config['amm_randompicture_periodicchange']=$config['freqDelay'];
+      $this->config['amm_randompicture_height']=$config['blockHeight'];
+      $this->config['amm_randompicture_title']=array();
+      foreach($config['blockTitles'] as $title)
+      {
+        $this->config['amm_randompicture_title'][$title['id']]=base64_encode($title['value']);
+      }
+
+      $this->saveConfig();
+      return('OK!'.l10n('g002_config_saved'));
+    }
+
+
+
+    /*
+     * -------------------------------------------------------------------------
+     * personalised blocks
+     * -------------------------------------------------------------------------
+     */
+
+    /**
+     * return a html formatted list of blocks
+     */
+    private function ajax_amm_admin_blocksList()
+    {
+      global $template, $user;
+
+      $local_tpl = new Template(AMM_PATH."admin/", "");
+      $local_tpl->set_filename('body_page',
+                    dirname($this->getFileLocation()).'/admin/amm_personalised_detail.tpl');
+
+
+
+      $datas=array(
+        'blocks'=>array()
+      );
+
+      $blocks=$this->getPersonalisedBlocks(false, '', true);
+      foreach($blocks as $block)
+      {
+        $datas['blocks'][]=array(
+          'id' => $block['id'],
+          'nfo' => $block['nfo'],
+          'title' => $block['title'],
+          'visible' => l10n('g002_yesno_'.$block['visible'])
+        );
+      }
+
+      $local_tpl->assign('themeconf', $template->get_template_vars('themeconf'));
+      $local_tpl->assign('datas', $datas);
+      $local_tpl->assign('plugin', array('PATH' => AMM_PATH));
+
+      return($local_tpl->parse('body_page', true));
+    }
+
+    /**
+     * delete a block
+     *
+     * @param Integer $id : block id
+     * @return String : OK or KO
+     */
+    private function ajax_amm_admin_blocksDelete($id)
+    {
+      return($this->deletePersonalisedBlock($id)?'OK':'KO');
+    }
+
+    /**
+     * return block content as a json string
+     *
+     * @param Integer $id : block id
+     * @return String : json string
+     */
+    private function ajax_amm_admin_blocksGet($id)
+    {
+      return(json_encode($this->getPersonalisedBlock($id)));
+    }
+
+    /**
+     * set block values
+     * if id is empty, create a new block
+     *
+     * @param String $id      : block id
+     * @param String $visible : block visibility ('y' or 'n')
+     * @param String $nfo     : block description
+     * @param Array  $langs   : block langs, each record is an array
+     *                                  array('title' => '', 'content' => '')
+     * @return String : $id if OK, otherwise -1
+     */
+    private function ajax_amm_admin_blocksSet($id, $visible, $nfo, $lang)
+    {
+      return($this->setPersonalisedBlock($id, $visible, $nfo, $lang));
+    }
+
+    /*
+     * -------------------------------------------------------------------------
+     * core blocks
+     * -------------------------------------------------------------------------
+     */
+
+    /**
+     * set the menu config
+     *  - core blocks content
+     *  - blocks order&visibility
+     *
+     * @param Array $subMenus : for core blocks, sub menu items
+     *                          array(
+     *                            'subMenuId' => array(
+     *                                          'visibility' => (String),
+     *                                          'order' => (Integer),
+     *                                          'container' => (String),
+     *                                        )
+     *                          )
+     * @param Array $menus    : menu blocks order&visibility
+     *                          array(
+     *                            'block1' => array(
+     *                                'id'    => (String),
+     *                                'order' => (Integer),
+     *                                'users' => array(),
+     *                                'groups' => array()
+     *                            )
+     *                          )
+     * @return String : OK or KO
+     */
+    private function ajax_amm_admin_coreBlocksSetConfig($subMenu, $menus)
+    {
+      foreach($subMenu as $key=>$val)
+      {
+        if(!isset($subMenu[$key]['visibilityUser'])) $subMenu[$key]['visibilityUser']=array();
+        if(!isset($subMenu[$key]['visibilityGroup'])) $subMenu[$key]['visibilityGroup']=array();
+
+        $subMenu[$key]['visibility']=implode(',', $subMenu[$key]['visibilityUser']).'/'.implode(',', $subMenu[$key]['visibilityGroup']);
+        unset($subMenu[$key]['visibilityUser']);
+        unset($subMenu[$key]['visibilityGroup']);
+      }
+      $this->config['amm_blocks_items']=$subMenu;
+      $this->saveConfig();
+
+
+      foreach($menus as $key=>$val)
+      {
+        if(!isset($menus[$key]['users'])) $menus[$key]['users']=array();
+        if(!isset($menus[$key]['groups'])) $menus[$key]['groups']=array();
+      }
+      $this->setRegisteredBlocks($menus);
+
+      return('OK!'.l10n('g002_config_saved'));
+    }
+
+
+
+    /*
+     * -------------------------------------------------------------------------
+     * album to menu
+     * -------------------------------------------------------------------------
+     */
+
+
+    /**
+     * set the album to menu config
+     *
+     * $config is an array with keys :
+     *  Array  'selectCat'      : list of selected categories
+     *
+     * @param Array $config
+     * @return String : OK or KO
+     */
+    private function ajax_amm_admin_albumSetConfig($config)
+    {
+      $this->config['amm_albums_to_menu']=$config['selectCat'];
+
+      $this->saveConfig();
+      return('OK!'.l10n('g002_config_saved'));
+    }
+
+
+  } //class
+
+
+  $returned=new AMM_Ajax($prefixeTable, __FILE__);
+?>
+
Index: /extensions/AMenuManager/amm_install.class.inc.php
===================================================================
--- /extensions/AMenuManager/amm_install.class.inc.php	(revision 8961)
+++ /extensions/AMenuManager/amm_install.class.inc.php	(revision 8962)
@@ -3,5 +3,5 @@
   Plugin     : Advanced Menu Manager
   Author     : Grum
-    email    : grum@grum.dnsalias.com
+    email    : grum@piwigo.org
     website  : http://photos.grum.fr
     PWG user : http://forum.phpwebgallery.net/profile.php?id=3706
@@ -21,18 +21,25 @@
   class AMM_install extends AMM_root
   {
-    private $tablesManager;
-    private $exportfile;
-
-    public function AMM_install($prefixeTable, $filelocation)
+    private $tablef;
+
+    public function __construct($prefixeTable, $filelocation)
     {
       parent::__construct($prefixeTable, $filelocation);
-      $this->tablesManager= new GPCTables($this->tables);
-      $this->exportfile=dirname($this->getFileLocation()).'/'.$this->getPluginNameFiles().'.sql';
-    }
-
-    /*
-        function for installation process
-        return true if install process is ok, otherwise false
-    */
+      $this->tablef= new GPCTables($this->tables);
+    }
+
+    public function __destruct()
+    {
+      unset($this->tablesManager);
+      unset($this->tablef);
+      parent::__destruct();
+    }
+
+
+    /**
+     * function for installation process
+     *
+     * @return Bool : true if install process is ok, otherwise false
+     */
     public function install()
     {
@@ -40,4 +47,5 @@
       $this->loadConfig();
       $this->config['installed']=AMM_VERSION2;
+      $this->config['newInstall']='y';
       $this->saveConfig();
 
@@ -51,4 +59,6 @@
   `position` int(11) NOT NULL default '0',
   `visible` char(1) NOT NULL default 'y',
+  `accessUsers` varchar(1024) NOT NULL,
+  `accessGroups` varchar(1024) NOT NULL,
   PRIMARY KEY  (`id`),
   KEY `order_key` (`position`)
@@ -56,28 +66,47 @@
 
 "CREATE TABLE  `".$this->tables['personalised']."` (
-  `id` int(11) NOT NULL default '0',
-  `lang` varchar(5) NOT NULL default '',
-  `title` varchar(255) NOT NULL default '',
-  `content` text NOT NULL,
+  `id` int(11) NOT NULL auto_increment,
   `visible` char(1) NOT NULL default 'y',
   `nfo` varchar(255) NOT NULL default '',
-  PRIMARY KEY  (`id`,`lang`)
+  PRIMARY KEY  (`id`)
+)",
+
+"CREATE TABLE `".$this->tables['personalised_langs']."` (
+  `id` INTEGER UNSIGNED NOT NULL DEFAULT 0,
+  `lang` CHAR(5)  NOT NULL default '*',
+  `title` VARCHAR(255)  NOT NULL default '',
+  `content` TEXT  NOT NULL,
+  PRIMARY KEY (`id`, `lang`)
+)",
+
+"CREATE TABLE `".$this->tables['blocks']."` (
+  `id` VARCHAR(40)  NOT NULL,
+  `order` INTEGER UNSIGNED NOT NULL,
+  `users` VARCHAR(1024)  NOT NULL,
+  `groups` VARCHAR(1024)  NOT NULL,
+  PRIMARY KEY (`id`),
+  INDEX `byOrder`(`order`)
 )"
+
 );
       //$table_def array
       $tables_def = create_table_add_character_set($tables_def);
-      $result=$this->tablesManager->create($tables_def);
+      $result=$this->tablef->create($tables_def);
+      unset($tables_def);
+
+      GPCCore::register($this->getPluginName(), AMM_VERSION, AMM_GPC_NEEDED);
+
       return($result);
     }
 
 
-    /*
-        function for uninstall process
-    */
+    /**
+     * function for uninstall process
+     */
     public function uninstall()
     {
-      $this->tablesManager->export($this->exportfile);
       $this->deleteConfig();
-      $this->tablesManager->drop();
+      $this->tablef->drop();
+      GPCCore::unregister($this->getPluginName());
     }
 
@@ -91,10 +120,16 @@
       $this->udpateTablesDef();
 
+      $this->config['newInstall']='n';
       $this->config['installed']=AMM_VERSION2; //update the installed release number
       $this->saveConfig();
+
+      GPCCore::register($this->getPluginName(), AMM_VERSION, AMM_GPC_NEEDED);
     }
 
     public function deactivate()
     {
+      $this->initConfig();
+      $this->loadConfig();
+      $this->restoreMenuConfig();
     }
 
@@ -106,8 +141,10 @@
     protected function udpateTablesDef()
     {
+      global $conf;
+
       /* AMM release earlier than the 2.1.3 uses two parameters to manage the display
        * of the menu items ("amm_sections_modspecials" and "amm_sections_modmenu")
        *
-       * These two parameters are replaced by a single parameter "amm_sections_items"
+       * These two parameters are replaced by a single parameter "amm_blocks_items"
        *
        * This function aim to import the old conf into the new conf property
@@ -117,5 +154,5 @@
         foreach($this->config['amm_sections_modspecials'] as $key=>$val)
         {
-          $this->config['amm_sections_items'][$key]['visibility']=($val=="y")?"guest,generic,normal,admin/":"admin/";
+          $this->config['amm_blocks_items'][$key]['visibility']=($val=="y")?"guest,generic,normal,admin/":"admin/";
         }
         unset($this->config['amm_sections_modspecials']);
@@ -126,5 +163,5 @@
         foreach($this->config['amm_sections_modmenu'] as $key=>$val)
         {
-          $this->config['amm_sections_items'][$key]['visibility']=($val=="y")?"guest,generic,normal,admin/":"admin/";
+          $this->config['amm_blocks_items'][$key]['visibility']=($val=="y")?"guest,generic,normal,admin/":"admin/";
         }
         unset($this->config['amm_sections_modmenu']);
@@ -140,24 +177,157 @@
       }
 
-      if($this->config['installed']<="02.01.06")
-      {
-        /*
-         * 2.2.0 updates
-         *
-         * - update fields length for table 'personalised'
-         * - update config for menu translation
-         */
-        $sql="ALTER TABLE `".$this->tables['personalised']."`
-              MODIFY COLUMN `title` VARCHAR(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
-              MODIFY COLUMN `nfo` VARCHAR(255)  CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL;";
-        pwg_query($sql);
-
-        foreach($this->config['amm_sections_items'] as $key => $val)
+      switch($this->config['installed'])
+      {
+        case '02.01.06':
+          $this->config['newInstall']='n';
+          $this->updateFrom_020106();
+        case '02.02.00':
+          $this->config['newInstall']='n';
+          $this->updateFrom_020200();
+        default:
+          /*
+           * default is applied for fresh install
+           */
+
+          if($this->config['installed']<='02.02.02' or
+             $this->config['newInstall']=='y')
+          {
+            /*
+             * if    new install
+             *    or plugin updated from a release <= 2.2.0
+             *    or plugin
+             *
+             * update AMM menu from piwigo's menu
+             */
+            $this->backupMenuConfig(true);
+          }
+          else
+          {
+            /*
+             * plugin actived without being installed or updated, only backup
+             * the piwigo's menu
+             */
+            $this->backupMenuConfig(false);
+          }
+          break;
+      }
+
+    }
+
+    /**
+     * update the database from the release 2.1.6
+     *
+     * - update config for menu translation
+     * - update fields length for table 'personalised'
+     */
+    private function updateFrom_020106()
+    {
+      $sql="ALTER TABLE `".$this->tables['personalised']."`
+            MODIFY COLUMN `id` INTEGER  NOT NULL AUTO_INCREMENT,
+            MODIFY COLUMN `title` VARCHAR(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
+            MODIFY COLUMN `nfo` VARCHAR(255)  CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL;";
+      pwg_query($sql);
+
+      foreach($this->config['amm_blocks_items'] as $key => $val)
+      {
+        $this->config['amm_blocks_items'][$key]['translation'] = $this->defaultMenus[$key]['translation'];
+      }
+    }
+
+
+
+    /**
+     * update the database from the release 2.2.0
+     *
+     * - create 'personalised_lang' table ; filled from the 'personalised' table
+     *   values
+     * - modify 'personalised' table structure (remove lang attributes)
+     * - modify 'urls' table structure (add users&group access)
+     * - update 'urls' table values (default values for users access)
+     * - update config (parameter 'amm_sections_items' is renamed into 'amm_blocks_items')
+     */
+    private function updateFrom_020200()
+    {
+      $tables_def=array(
+"CREATE TABLE `".$this->tables['personalised_langs']."` (
+  `id` INTEGER UNSIGNED NOT NULL DEFAULT 0,
+  `lang` CHAR(5)  NOT NULL default '*',
+  `title` VARCHAR(255)  NOT NULL default '',
+  `content` TEXT  NOT NULL,
+  PRIMARY KEY (`id`, `lang`)
+)",
+
+"CREATE TABLE `".$this->tables['blocks']."` (
+  `id` VARCHAR(40)  NOT NULL,
+  `order` INTEGER UNSIGNED NOT NULL,
+  `users` VARCHAR(1024)  NOT NULL,
+  `groups` VARCHAR(1024)  NOT NULL,
+  PRIMARY KEY (`id`),
+  INDEX `byOrder`(`order`)
+)"
+      );
+
+      $tables_def = create_table_add_character_set($tables_def);
+      $result=$this->tablef->create($tables_def);
+
+      $sql="INSERT INTO `".$this->tables['personalised_langs']."`
+              SELECT pap.id, pap.lang, pap.title, pap.content
+              FROM `".$this->tables['personalised']."` pap
+              WHERE pap.title!='' OR pap.content!='';";
+      pwg_query($sql);
+
+      $sql="ALTER TABLE `".$this->tables['personalised']."` DROP COLUMN `lang`,
+             DROP COLUMN `title`,
+             DROP COLUMN `content`;";
+      pwg_query($sql);
+
+      $sql="ALTER TABLE `".$this->tables['urls']."`
+            ADD COLUMN `accessUsers` VARCHAR(1024)  NOT NULL AFTER `visible`,
+            ADD COLUMN `accessGroups` VARCHAR(1024)  NOT NULL AFTER `accessUser`;";
+      pwg_query($sql);
+
+
+      $users=new GPCUsers();
+      $sql="UPDATE `".$this->tables['urls']."`
+            SET accessUsers='".pwg_db_real_escape_string(implode(',', $users->getList()))."';";
+      pwg_query($sql);
+
+      if(isset($this->config['amm_sections_items']))
+      {
+        $this->config['amm_blocks_items']=$this->config['amm_sections_items'];
+        unset($this->config['amm_sections_items']);
+      }
+    }
+
+    /**
+     * report hidden menu from piwigo's config to AMM config
+     */
+    private function backupMenuConfig($updateMenu=false)
+    {
+      global $conf;
+
+      $this->config['amm_old_blk_menubar']=$conf['blk_menubar'];
+      pwg_query("UPDATE ".CONFIG_TABLE." SET value = '' WHERE param='blk_menubar';");
+
+      if($updateMenu)
+      {
+        $tmp=unserialize($conf['blk_menubar']);
+        foreach($tmp as $key => $val)
         {
-          $this->config['amm_sections_items'][$key]['translation'] = $this->defaultMenus[$key]['translation'];
+          pwg_query("REPLACE INTO ".$this->tables['blocks']." VALUES ('$key', '".abs($val)."', '".($val<0?'guest,generic,normal,webmaster,admin':'')."', '');");
         }
       }
     }
 
+    /**
+     * restore piwigo's menu
+     */
+    private function restoreMenuConfig()
+    {
+      pwg_query("UPDATE ".CONFIG_TABLE." SET value = '".pwg_db_real_escape_string($this->config['amm_old_blk_menubar'])."' WHERE param='blk_menubar';");
+    }
+
+
+
   } //class
 
Index: /extensions/AMenuManager/amm_pip.class.inc.php
===================================================================
--- /extensions/AMenuManager/amm_pip.class.inc.php	(revision 8961)
+++ /extensions/AMenuManager/amm_pip.class.inc.php	(revision 8962)
@@ -22,4 +22,9 @@
 {
   protected $displayRandomImageBlock=true;
+  protected $registeredBlocks;
+  protected $randomPictProp=null;
+  protected $users;
+  protected $groups;
+  protected $currentBuiltMenu=-1;
 
   function AMM_PIP($prefixeTable, $filelocation)
@@ -28,4 +33,7 @@
     $this->css = new GPCCss(dirname($this->getFileLocation()).'/'.$this->getPluginNameFiles()."2.css");
 
+    $this->users=new GPCUsers();
+    $this->groups=new GPCGroups();
+
     $this->loadConfig();
     $this->initEvents();
@@ -33,54 +41,60 @@
 
 
-  /* ---------------------------------------------------------------------------
-  Public classe functions
-  --------------------------------------------------------------------------- */
-
-
-  /*
-    initialize events call for the plugin
-  */
+  /**
+   * initialize events call for the plugin
+   */
   public function initEvents()
   {
-    //TODELETE: add_event_handler('loc_begin_menubar', array(&$this, 'modify_menu') );
     parent::initEvents();
-    add_event_handler('loading_lang', array(&$this, 'load_lang'));
-    add_event_handler('blockmanager_apply', array(&$this, 'blockmanager_apply') );
+
+    add_event_handler('blockmanager_prepare_display', array(&$this, 'blockmanagerSortBlocks') );
+    add_event_handler('blockmanager_apply', array(&$this, 'blockmanagerApply') );
     add_event_handler('loc_end_page_header', array(&$this->css, 'applyCSS'));
-    add_event_handler('loc_end_page_tail', array(&$this, 'applyJS'));
-  }
-
-  /*
-    load language file
-  */
-  public function load_lang()
-  {
-    global $lang;
-
-    //load_language('plugin.lang', AMM_PATH);
-
-    // ajax is managed here ; this permit to use user&language properties inside
-    // ajax content
-    $this->return_ajax_content();
-  }
-
-  public function blockmanager_apply( $menu_ref_arr )
-  {
-    global $user, $page;
-    $menu = & $menu_ref_arr[0];
-
-
-    /*
-      Add a new random picture section
-    */
-    if ( ( ($block = $menu->get_block( 'mbAMM_randompict' ) ) != null ) && ($user['nb_total_images'] > 0) )
-    {
-      $block->set_title(  base64_decode($this->config['amm_randompicture_title'][$user['language']]) );
-      $block->data = array(
-        "delay" => $this->config['amm_randompicture_periodicchange'],
-        "blockHeight" => $this->config['amm_randompicture_height'],
-        "firstPicture" => $this->ajax_amm_get_random_picture()
+    add_event_handler('loc_end_page_header', array(&$this, 'applyJS'));
+    add_event_handler('get_categories_menu_sql_where', array(&$this, 'buildMenuFromCat'), 75);
+  }
+
+
+  public function blockmanagerApply($menu_ref_arr)
+  {
+    $menu=&$menu_ref_arr[0];
+
+    $this->addBlockRandomPicture($menu);
+    $this->addBlockLinks($menu);
+    $this->addBlockPersonnal($menu);
+    $this->addBlockAlbum($menu);
+    $this->manageBlocksContent($menu);
+    $this->manageBlocks($menu);
+  }
+
+
+  /**
+   * Add a new random picture block
+   */
+  private function addBlockRandomPicture(&$menu)
+  {
+    global $user;
+
+    if((
+        ($block=$menu->get_block('mbAMM_randompict'))!=null) and
+        ($user['nb_total_images']>0) and
+        isset($this->config['amm_randompicture_title'][$user['language']])
+      )
+    {
+      GPCCore::addHeaderJS('jquery', 'themes/default/js/jquery.packed.js');
+      GPCCore::addHeaderJS('amm.randomPictPublic', 'plugins/AMenuManager/js/amm_randomPictPublic'.GPCCore::getMinified().'.js');
+
+      $block->set_title(base64_decode($this->config['amm_randompicture_title'][$user['language']]));
+      $block->template=dirname(__FILE__).'/menu_templates/menubar_randompic.tpl';
+
+      $this->randomPictProp = array(
+        'delay' => $this->config['amm_randompicture_periodicchange'],
+        'blockHeight' => $this->config['amm_randompicture_height'],
+        'showname' => $this->config['amm_randompicture_showname'],
+        'showcomment' => $this->config['amm_randompicture_showcomment'],
+        'pictures' => $this->getRandomPictures($this->config['amm_randompicture_preload'])
       );
-      $block->template = dirname(__FILE__).'/menu_templates/menubar_randompic.tpl';
+
+      if(count($this->randomPictProp['pictures'])==0) $this->displayRandomImageBlock=false;
     }
     else
@@ -88,23 +102,56 @@
       $this->displayRandomImageBlock=false;
     }
-
-    /*
-      Add a new section (links)
-    */
-    if ( ($block = $menu->get_block( 'mbAMM_links' ) ) != null )
-    {
-      $urls=$this->get_urls(true);
-      if ( count($urls)>0 )
-      {
+  }
+
+
+  /**
+   * Add a new block (links)
+   */
+  private function addBlockLinks(&$menu)
+  {
+    global $user;
+
+    $nbLink=0;
+
+    if(($block=$menu->get_block('mbAMM_links'))!=null &&
+       isset($this->config['amm_links_title'][$user['language']])
+      )
+    {
+      $urls=$this->getLinks(true);
+
+      if(count($urls)>0)
+      {
+        $userGroups=$this->getUserGroups($user['id']);;
+
+        foreach($urls as $key => $val)
+        {
+          $this->users->setAlloweds(explode(",", $val['accessUsers']), false);
+          $this->groups->setAlloweds(explode(",", $val['accessGroups']), false);
+
+          if(!$this->users->isAllowed($user['status']))
+          {
+            unset($urls[$key]);
+          }
+          else
+          {
+            $ok=true;
+            foreach($userGroups as $group)
+            {
+              if(!$this->groups->isAllowed($group)) $ok=false;
+            }
+            if(!$ok) unset($urls[$key]);
+          }
+        }
+
         if($this->config['amm_links_show_icons']=='y')
         {
-          for($i=0;$i<count($urls);$i++)
+          foreach($urls as $key => $url)
           {
-            $urls[$i]['icon']=get_root_url().'plugins/'.AMM_DIR."/links_pictures/".$urls[$i]['icon'];
+            $urls[$key]['icon']=get_root_url().'plugins/'.AMM_DIR."/links_pictures/".$url['icon'];
           }
         }
 
-        $block->set_title( base64_decode($this->config['amm_links_title'][$user['language']]) );
-        $block->template = dirname(__FILE__).'/menu_templates/menubar_links.tpl';
+        $block->set_title(base64_decode($this->config['amm_links_title'][$user['language']]));
+        $block->template=dirname(__FILE__).'/menu_templates/menubar_links.tpl';
 
         $block->data = array(
@@ -114,39 +161,88 @@
       }
     }
-
-    /*
-      Add personnal blocks random picture section
-    */
-    $sections=$this->get_sections(true);
+  }
+
+
+  /**
+   * Add personnal blocks
+   */
+  private function addBlockPersonnal(&$menu)
+  {
+    $sections=$this->getPersonalisedBlocks(true);
 
     if(count($sections))
     {
-      $id_done=array();
+      $idDone=array();
       foreach($sections as $key => $val)
       {
-        if(!isset($id_done[$val['id']]))
+        if(!isset($idDone[$val['id']]))
         {
-          if ( ($block = $menu->get_block( 'mbAMM_personalised'.$val['id'] ) ) != null )
+          if(($block=$menu->get_block('mbAMM_personalised'.$val['id']))!= null)
           {
-            $block->set_title( $val['title'] );
+            $block->set_title($val['title']);
             $block->template = dirname(__FILE__).'/menu_templates/menubar_personalised.tpl';
             $block->data = stripslashes($val['content']);
           }
-          $id_done[$val['id']]="";
+          $idDone[$val['id']]="";
         }
       }
     }
-
-
-    /* manage items from special & menu sections
-     *  reordering items
-     *  grouping items
-     *  managing rights to access
-    */
+  }
+
+
+
+
+  /**
+   * Add album to menu
+   */
+  private function addBlockAlbum(&$menu)
+  {
+    if(count($this->config['amm_albums_to_menu'])>0)
+    {
+      $sql="SELECT id, name, permalink, global_rank
+            FROM ".CATEGORIES_TABLE."
+            WHERE id IN(".implode(',', $this->config['amm_albums_to_menu']).");";
+
+      $result=pwg_query($sql);
+      if($result)
+      {
+        while($row=pwg_db_fetch_assoc($result))
+        {
+          $this->currentBuiltMenu=$row['id'];
+
+          $row['name']=trigger_event('render_category_name', $row['name'], 'amm_album_to_menu');
+
+          if(($block=$menu->get_block('mbAMM_album'.$row['id']))!= null)
+          {
+            $block->set_title($row['name']);
+            $block->template = dirname(__FILE__).'/menu_templates/menubar_album.tpl';
+            $block->data = array(
+              'album' => get_categories_menu(),
+              'name' => $row['name'],
+              'link' => make_index_url(array('category' => $row)),
+              'nbPictures' => ''
+            );
+          }
+        }
+      }
+      $this->currentBuiltMenu=-1;
+    }
+  }
+
+  /**
+   * manage items from special & menu blocks
+   *  - reordering items
+   *  - grouping items
+   *  - managing rights to access
+   */
+  private function manageBlocksContent(&$menu)
+  {
+    global $user;
+
     $blocks=Array();
 
     if($menu->is_hidden('mbMenu'))
     {
-      // if block is hidden, make a fake to manage AMM features
+      // if block is hidden, make a fake to manage AMM submenu features
       // the fake block isn't displayed
       $blocks['menu']=new DisplayBlock('amm_mbMenu');
@@ -160,5 +256,5 @@
     if($menu->is_hidden('mbSpecials'))
     {
-      // if block is hidden, make a fake to manage AMM features
+      // if block is hidden, make a fake to manage AMM submenu features
       // the fake block isn't displayed
       $blocks['special']=new DisplayBlock('amm_mbSpecial');
@@ -171,30 +267,30 @@
 
     $menuItems=array_merge($blocks['menu']->data, $blocks['special']->data);
-    $this->sortSectionsItems();
+    $this->sortCoreBlocksItems();
 
     $blocks['menu']->data=Array();
     $blocks['special']->data=Array();
-
-    $users=new GPCUsers("");
-    $groups=new GPCGroups("");
-    $user_groups=$this->get_user_groups($user['id']);
-
-    foreach($this->config['amm_sections_items'] as $key => $val)
+    $userGroups=$this->getUserGroups($user['id']);
+
+    foreach($this->config['amm_blocks_items'] as $key => $val)
     {
       if(isset($menuItems[$key]))
       {
         $access=explode("/",$val['visibility']);
-        $users->setAlloweds(str_replace(",", "/", $access[0]));
-        $groups->setAlloweds(str_replace(",", "/", $access[1]));
-
-        /* test if user status is allowed to access the menu item
+        $this->users->setAlloweds(str_replace(",", "/", $access[0]), false);
+        $this->groups->setAlloweds(str_replace(",", "/", $access[1]), false);
+
+        /*
+         * test if user status is allowed to access the menu item
          * if access is managed by group, the user have to be associated with an allowed group to access the menu item
-        */
-        if($users->isAllowed($user['status']) && (
-            ($access[1]=='') ||
-            (($access[1]!='') && $groups->areAllowed($user_groups)))
-        )
+         */
+        if($this->users->isAllowed($user['status']))
         {
-          $blocks[$val['container']]->data[$key]=$menuItems[$key];
+          $ok=true;
+          foreach($userGroups as $group)
+          {
+            if(!$this->groups->isAllowed($group)) $ok=false;
+          }
+          if($ok) $blocks[$val['container']]->data[$key]=$menuItems[$key];
         }
       }
@@ -205,9 +301,17 @@
 
 
-  protected function get_user_groups($user_id)
-  {
+  /**
+   * return groups for a user
+   *
+   * @param String $userId
+   * @return Array
+   */
+  private function getUserGroups($userId)
+  {
+    global $user;
+
     $returned=array();
-    $sql="SELECT group_id FROM ".USER_GROUP_TABLE."
-          WHERE user_id = ".$user_id." ";
+
+    $sql="SELECT group_id FROM ".USER_GROUP_TABLE." WHERE user_id='".$user['id']."';";
     $result=pwg_query($sql);
     if($result)
@@ -215,5 +319,5 @@
       while($row=pwg_db_fetch_assoc($result))
       {
-        array_push($returned, $row['group_id']);
+        $returned[]=$row['group_id'];
       }
     }
@@ -221,80 +325,125 @@
   }
 
-  /*
-    return ajax content
-  */
-  protected function return_ajax_content()
-  {
-    global $ajax, $template;
-
-    if(isset($_REQUEST['ajaxfct']))
-    {
-      if($_REQUEST['ajaxfct']=='randompic')
-      {
-        $result="<p class='errors'>".l10n('g002_error_invalid_ajax_call')."</p>";
-        switch($_REQUEST['ajaxfct'])
+
+  /**
+   * reordering blocks and manage access right
+   *
+   */
+  private function manageBlocks($menu)
+  {
+    $this->registeredBlocks=$this->getRegisteredBlocks(true);
+
+    foreach($menu->get_registered_blocks() as $key => $block)
+    {
+      if(!isset($this->registeredBlocks[$block->get_id()]))
+      {
+        $menu->hide_block($block->get_id());
+      }
+    }
+
+  }
+
+
+  /**
+   * sort menu blocks according to AMM rules (overriding piwigo's sort rules)
+   */
+  public function blockmanagerSortBlocks($blocks)
+  {
+    $this->registeredBlocks=$this->getRegisteredBlocks(true);
+
+    foreach($blocks[0]->get_registered_blocks() as $key => $block)
+    {
+      if(isset($this->registeredBlocks[$block->get_id()]))
+      {
+        $blocks[0]->set_block_position($block->get_id(), $this->registeredBlocks[$block->get_id()]['order']);
+      }
+    }
+  }
+
+
+
+
+
+
+
+  /**
+   * return a list of thumbnails
+   * each array items is an array
+   *  'imageId'   => (integer)
+   *  'imageFile' => (String)
+   *  'comment'   => (String)
+   *  'path'      => (String)
+   *  'tn_ext'    => (String)
+   *  'catId'     => (String)
+   *  'name'      => (String)
+   *  'permalink' => (String)
+   *  'imageName' => (String)
+   *
+   * @param Integer $number : number of returned images
+   * @return Array
+   */
+  private function getRandomPictures($num=25)
+  {
+    global $user;
+
+    $returned=array();
+
+    $sql=array();
+
+    $sql['select']="SELECT i.id as image_id, i.file as image_file, i.comment, i.path, i.tn_ext, c.id as catid, c.name, c.permalink, RAND() as rndvalue, i.name as imgname ";
+    $sql['from']="FROM ".CATEGORIES_TABLE." c, ".IMAGES_TABLE." i, ".IMAGE_CATEGORY_TABLE." ic ";
+    $sql['where']="WHERE c.id = ic.category_id
+            AND ic.image_id = i.id
+            AND i.level <= ".$user['level']." ";
+
+    if($user['forbidden_categories']!="")
+    {
+      $sql['where'].=" AND c.id NOT IN (".$user['forbidden_categories'].") ";
+    }
+
+    switch($this->config['amm_randompicture_selectMode'])
+    {
+      case 'f':
+        $sql['from'].=", ".USER_INFOS_TABLE." ui
+          LEFT JOIN ".FAVORITES_TABLE." f ON ui.user_id=f.user_id ";
+        $sql['where'].=" AND ui.status='webmaster'
+                         AND f.image_id = i.id ";
+        break;
+      case 'c':
+        $sql['where'].="AND (";
+        foreach($this->config['amm_randompicture_selectCat'] as $key => $val)
         {
-          case 'randompic':
-            $result=$this->ajax_amm_get_random_picture();
-            break;
+          $sql['where'].=($key==0?'':' OR ')." FIND_IN_SET($val, c.uppercats) ";
         }
-        GPCAjax::returnResult($result);
-      }
-    }
-  }
-
-
-  // return the html content for the random picture block
-  private function ajax_amm_get_random_picture()
-  {
-    global $user;
-
-    $local_tpl = new Template(AMM_PATH."menu_templates/", "");
-    $local_tpl->set_filename('body_page',
-                  dirname($this->getFileLocation()).'/menu_templates/menubar_randompic_inner.tpl');
-
-      $sql="SELECT i.id as image_id, i.file as image_file, i.comment, i.path, i.tn_ext, c.id as catid, c.name, c.permalink, RAND() as rndvalue, i.name as imgname
-            FROM ".CATEGORIES_TABLE." c, ".IMAGES_TABLE." i, ".IMAGE_CATEGORY_TABLE." ic
-            WHERE c.id = ic.category_id
-              AND ic.image_id = i.id
-              AND i.level <= ".$user['level']." ";
-      if($user['forbidden_categories']!="")
-      {
-        $sql.=" AND c.id NOT IN (".$user['forbidden_categories'].") ";
-      }
-
-      $sql.=" ORDER BY rndvalue
-            LIMIT 0,1";
-
-
-      $result = pwg_query($sql);
-      if($result and $nfo = pwg_db_fetch_assoc($result))
-      {
-        $nfo['section']='category';
-        $nfo['category']=array(
-          'id' => $nfo['catid'],
-          'name' => $nfo['name'],
-          'permalink' => $nfo['permalink']
+        $sql['where'].=") ";
+        break;
+    }
+
+    $sql=$sql['select'].$sql['from'].$sql['where']." ORDER BY rndvalue LIMIT 0,$num";
+
+
+    $result = pwg_query($sql);
+    if($result)
+    {
+      while($row=pwg_db_fetch_assoc($result))
+      {
+        $row['section']='category';
+        $row['category']=array(
+          'id' => $row['catid'],
+          'name' => $row['name'],
+          'permalink' => $row['permalink']
         );
 
-        $template_datas = array(
-          'LINK' => make_picture_url($nfo),
-          'IMG' => get_thumbnail_url($nfo),
-          'IMGNAME' => $nfo['imgname'],
-          'IMGCOMMENT' => $nfo['comment'],
-          'SHOWNAME' => $this->config['amm_randompicture_showname'],
-          'SHOWCOMMENT' => $this->config['amm_randompicture_showcomment']
-        );
-      }
-      else
-      {
-        $template_datas = array();
-      }
-
-    $local_tpl->assign('datas', $template_datas);
-    $local_tpl->assign('plugin', array('PATH' => AMM_PATH));
-
-    return($local_tpl->parse('body_page', true));
-  }
+        $row['link']=make_picture_url($row);
+        $row['thumb']=get_thumbnail_url($row);
+
+        $returned[]=$row;
+      }
+    }
+
+    return($returned);
+  }
+
+
 
 
@@ -315,4 +464,5 @@
     }
 
+
     if($this->displayRandomImageBlock && $page['body_id'] == 'theCategoryPage')
     {
@@ -320,15 +470,31 @@
       $local_tpl->set_filename('body_page', dirname($this->getFileLocation()).'/menu_templates/menubar_randompic.js.tpl');
 
-      $data = array(
-        "delay" => $this->config['amm_randompicture_periodicchange'],
-        "blockHeight" => $this->config['amm_randompicture_height'],
-        "firstPicture" => $this->ajax_amm_get_random_picture()
-      );
-
-      $local_tpl->assign('data', $data);
-
-      $template->append('footer_elements', $local_tpl->parse('body_page', true));
-    }
-
+      $local_tpl->assign('data', $this->randomPictProp);
+
+      $template->append('head_elements', $local_tpl->parse('body_page', true));
+    }
+  }
+
+
+
+  public function buildMenuFromCat($where)
+  {
+    global $user;
+
+    if($this->currentBuiltMenu>-1)
+    {
+      if($user['expand'])
+      {
+        $where=preg_replace('/id_uppercat\s+is\s+NULL/i', 'id_uppercat is NOT NULL', $where);
+      }
+      else
+      {
+        $where=preg_replace('/id_uppercat\s+is\s+NULL/i', 'id_uppercat is NULL OR id_uppercat IN ('.$this->currentBuiltMenu.')', $where);
+      }
+
+      $where.=" AND FIND_IN_SET(".$this->currentBuiltMenu.", uppercats) AND cat_id!=".$this->currentBuiltMenu." ";
+    }
+
+    return($where);
   }
 
Index: /extensions/AMenuManager/amm_root.class.inc.php
===================================================================
--- /extensions/AMenuManager/amm_root.class.inc.php	(revision 8961)
+++ /extensions/AMenuManager/amm_root.class.inc.php	(revision 8962)
@@ -17,4 +17,5 @@
 if (!defined('PHPWG_ROOT_PATH')) { die('Hacking attempt!'); }
 
+include_once(PHPWG_ROOT_PATH.'include/block.class.php');
 include_once(PHPWG_PLUGINS_PATH.'GrumPluginClasses/classes/CommonPlugin.class.inc.php');
 include_once(PHPWG_PLUGINS_PATH.'GrumPluginClasses/classes/GPCUsersGroups.class.inc.php');
@@ -26,18 +27,27 @@
   protected $css;   //the css object
   protected $defaultMenus = array(
-    'favorites' => array('container' => 'special', 'visibility' => 'guest,generic,normal,webmaster,admin/', 'order' => 0, 'translation' => 'My favorites'),
-    'most_visited' => array('container' => 'special', 'visibility' => 'guest,generic,normal,webmaster,admin/', 'order' => 1, 'translation' => 'Most visited'),
-    'best_rated' => array('container' => 'special', 'visibility' => 'guest,generic,normal,webmaster,admin/', 'order' => 2, 'translation' => 'Best rated'),
-    'random' => array('container' => 'special', 'visibility' => 'guest,generic,normal,webmaster,admin/', 'order' => 3, 'translation' => 'Random pictures'),
-    'recent_pics' => array('container' => 'special', 'visibility' => 'guest,generic,normal,webmaster,admin/', 'order' => 4, 'translation' => 'Recent pictures'),
-    'recent_cats' => array('container' => 'special', 'visibility' => 'guest,generic,normal,webmaster,admin/', 'order' => 5, 'translation' => 'Recent categories'),
-    'calendar' => array('container' => 'special', 'visibility' => 'guest,generic,normal,webmaster,admin/', 'order' => 6, 'translation' => 'Calendar'),
-    'qsearch' => array('container' => 'menu', 'visibility' => 'guest,generic,normal,webmaster,admin/', 'order' => 0, 'translation' => 'Quick search'),
-    'tags' => array('container' => 'menu', 'visibility' => 'guest,generic,normal,webmaster,admin/', 'order' => 1, 'translation' => 'Tags'),
-    'search' => array('container' => 'menu', 'visibility' => 'guest,generic,normal,webmaster,admin/', 'order' => 2, 'translation' => 'Search'),
-    'comments' => array('container' => 'menu', 'visibility' => 'guest,generic,normal,webmaster,admin/', 'order' => 3, 'translation' => 'Comments'),
-    'about' => array('container' => 'menu', 'visibility' => 'guest,generic,normal,webmaster,admin/', 'order' => 4, 'translation' => 'About'),
-    'rss' => array('container' => 'menu', 'visibility' => 'guest,generic,normal,webmaster,admin/', 'order' => 5, 'translation' => 'Notification')
+    /* about visibility & accessibility system :
+     *  - by default, everything is visible (users & groups)
+     *  - items not visibles are listed (in release < 3.3.4, this rule wa applied to groups only)
+     *
+     * on the user interface, checked items are visibles => not checked items are stored
+     */
+    'favorites' => array('container' => 'special', 'visibility' => '/', 'order' => 0, 'translation' => 'My favorites'),
+    'most_visited' => array('container' => 'special', 'visibility' => '/', 'order' => 1, 'translation' => 'Most visited'),
+    'best_rated' => array('container' => 'special', 'visibility' => '/', 'order' => 2, 'translation' => 'Best rated'),
+    'random' => array('container' => 'special', 'visibility' => '/', 'order' => 3, 'translation' => 'Random pictures'),
+    'recent_pics' => array('container' => 'special', 'visibility' => '/', 'order' => 4, 'translation' => 'Recent pictures'),
+    'recent_cats' => array('container' => 'special', 'visibility' => '/', 'order' => 5, 'translation' => 'Recent categories'),
+    'calendar' => array('container' => 'special', 'visibility' => '/', 'order' => 6, 'translation' => 'Calendar'),
+    'qsearch' => array('container' => 'menu', 'visibility' => '/', 'order' => 0, 'translation' => 'Quick search'),
+    'tags' => array('container' => 'menu', 'visibility' => '/', 'order' => 1, 'translation' => 'Tags'),
+    'search' => array('container' => 'menu', 'visibility' => '/', 'order' => 2, 'translation' => 'Search'),
+    'comments' => array('container' => 'menu', 'visibility' => '/', 'order' => 3, 'translation' => 'Comments'),
+    'about' => array('container' => 'menu', 'visibility' => '/', 'order' => 4, 'translation' => 'About'),
+    'rss' => array('container' => 'menu', 'visibility' => '/', 'order' => 5, 'translation' => 'Notification')
   );
+  protected $urlsModes=array(0 => 'new_window', 1 => 'current_window');
+
+
 
   public function __construct($prefixeTable, $filelocation)
@@ -47,5 +57,5 @@
     parent::__construct($prefixeTable, $filelocation);
 
-    $list=array('urls', 'personalised');
+    $list=array('urls', 'personalised', 'personalised_langs', 'blocks');
     $this->setTablesList($list);
   }
@@ -58,9 +68,13 @@
   }
 
-  /* ---------------------------------------------------------------------------
-  common AIP & PIP functions
-  --------------------------------------------------------------------------- */
-
-  /* this function initialize var $my_config with default values */
+  /*
+   * ---------------------------------------------------------------------------
+   * common AIP & PIP functions
+   * ---------------------------------------------------------------------------
+   */
+
+  /**
+   * this function initialize config var with default values
+   */
   public function initConfig()
   {
@@ -68,4 +82,5 @@
       'amm_links_show_icons' => 'y',
       'amm_links_title' => array(),
+      'amm_randompicture_preload' => 25,     //number preloaded random pictures
       'amm_randompicture_showname' => 'n',     //n:no, o:over, u:under
       'amm_randompicture_showcomment' => 'n',   //n:no, o:over, u:under
@@ -73,5 +88,9 @@
       'amm_randompicture_height' => 0,           //0: automatic, otherwise it's the fixed height in pixels
       'amm_randompicture_title' => array(),
-      'amm_sections_items' => $this->defaultMenus
+      'amm_randompicture_selectMode' => 'a',     // a:all, f:webmaster's favorites, c:categories
+      'amm_randompicture_selectCat' => array(),  // categories id list
+      'amm_blocks_items' => $this->defaultMenus,
+      'amm_albums_to_menu' => array(),
+      'amm_old_blk_menubar' => ''                // keep a copy of piwigo's menubar config
     );
 
@@ -99,40 +118,75 @@
   public function initEvents()
   {
-    add_event_handler('blockmanager_register_blocks', array(&$this, 'register_blocks') );
-  }
-
-  public function register_blocks( $menu_ref_arr )
+    add_event_handler('blockmanager_register_blocks', array(&$this, 'registerBlocks') );
+  }
+
+  public function registerBlocks( $menu_ref_arr )
   {
     $menu = & $menu_ref_arr[0];
-    if ($menu->get_id() != 'menubar')
-      return;
+    if ($menu->get_id() != 'menubar') return;
+
     $menu->register_block( new RegisteredBlock( 'mbAMM_randompict', 'Random pictures', 'AMM'));
     $menu->register_block( new RegisteredBlock( 'mbAMM_links', 'Links', 'AMM'));
 
-    $sections=$this->get_sections(true);
-    if(count($sections))
-    {
-      $id_done=array();
-      foreach($sections as $key => $val)
-      {
-        if(!isset($id_done[$val['id']]))
+    $blocks=$this->getPersonalisedBlocks();
+    if(count($blocks))
+    {
+      $idDone=array();
+      foreach($blocks as $key => $val)
+      {
+        if(!isset($idDone[$val['id']]))
         {
           $menu->register_block( new RegisteredBlock( 'mbAMM_personalised'.$val['id'], $val['title'], 'AMM'));
-          $id_done[$val['id']]="";
+          $idDone[$val['id']]="";
         }
       }
     }
-  }
-
-  // return an array of urls (each url is an array)
-  protected function get_urls($only_visible=false)
+
+    $this->loadConfig();
+
+    if(count($this->config['amm_albums_to_menu'])>0)
+    {
+      $sql="SELECT id, name
+            FROM ".CATEGORIES_TABLE."
+            WHERE id IN(".implode(',', $this->config['amm_albums_to_menu']).");";
+
+      $result=pwg_query($sql);
+      if($result)
+      {
+        while($row=pwg_db_fetch_assoc($result))
+        {
+          $row['name']=trigger_event('render_category_name', $row['name'], 'amm_album_to_menu');
+
+          $menu->register_block( new RegisteredBlock( 'mbAMM_album'.$row['id'], $row['name'].' ('.l10n('g002_album2menu').') ', 'AMM'));
+        }
+      }
+    }
+  }
+
+
+  /*
+   *  ---------------------------------------------------------------------------
+   *
+   * Links functions
+   *
+   * ---------------------------------------------------------------------------
+   */
+
+  /**
+   * return an array of links (each url is an array)
+   *
+   * @param Bool onlyVisible : if true, only visible links are returned
+   * @return Array
+   */
+  protected function getLinks($onlyVisible=false)
   {
     $returned=array();
-    $sql="SELECT * FROM ".$this->tables['urls'];
-    if($only_visible)
+    $sql="SELECT id, label, url, mode, icon, position, visible, accessUsers, accessGroups
+          FROM ".$this->tables['urls'];
+    if($onlyVisible)
     {
       $sql.=" WHERE visible = 'y' ";
     }
-    $sql.=" ORDER BY position";
+    $sql.=" ORDER BY position ASC, id ASC";
     $result=pwg_query($sql);
     if($result)
@@ -140,5 +194,4 @@
       while($row=pwg_db_fetch_assoc($result))
       {
-        $row['label']=stripslashes($row['label']);
         $returned[]=$row;
       }
@@ -147,10 +200,107 @@
   }
 
-  //return number of url
-  protected function get_count_url($only_visible=false)
+  /**
+   * return values for a given link
+   *
+   * @param String $id : link id
+   * @return Array
+   */
+  protected function getLink($id)
+  {
+    $returned=array();
+    $sql="SELECT id, label, url, mode, icon, position, visible, accessUsers, accessGroups
+          FROM ".$this->tables['urls']."
+          WHERE id = '$id';";
+    $result=pwg_query($sql);
+    if($result)
+    {
+      while($row=pwg_db_fetch_assoc($result))
+      {
+        $returned=$row;
+      }
+    }
+    return($returned);
+  }
+
+  /**
+   * set values for a link
+   * if link id is empty : create a new link
+   * if not, update link
+   *
+   * @param String $id : link id
+   * @return Integer : -1 if fails
+   *                   otherwise link id
+   */
+  protected function setLink($id, $label, $url, $mode, $icon, $visible, $accessUsers, $accessGroups)
+  {
+    if($id=='')
+    {
+      $sql="INSERT INTO ".$this->tables['urls']." VALUES
+            ('',
+             '".pwg_db_real_escape_string($label)."',
+             '".pwg_db_real_escape_string($url)."',
+             '$mode',
+             '$icon',
+             0,
+             '$visible',
+             '$accessUsers',
+             '$accessGroups'
+            );";
+    }
+    else
+    {
+      $sql="UPDATE ".$this->tables['urls']."
+            SET label='".pwg_db_real_escape_string($label)."',
+                url='".pwg_db_real_escape_string($url)."',
+                mode='$mode',
+                icon='$icon',
+                visible='$visible',
+                accessUsers='".pwg_db_real_escape_string($accessUsers)."',
+                accessGroups='".pwg_db_real_escape_string($accessGroups)."'
+            WHERE id='$id';";
+    }
+    $result=pwg_query($sql);
+    if($result)
+    {
+      if($id=='')
+      {
+        return(pwg_db_insert_id());
+      }
+      else
+      {
+        return($id);
+      }
+    }
+    return(-1);
+  }
+
+  /**
+   * delete a given link
+   *
+   * @param String $id : link id
+   * @return Bool : true if deleted, otherwise false
+   */
+  protected function deleteLink($id)
+  {
+    $sql="DELETE FROM ".$this->tables['urls']."
+          WHERE id = '$id';";
+    $result=pwg_query($sql);
+    if($result) return(true);
+    return(false);
+  }
+
+
+
+  /**
+   * return number of links
+   *
+   * @param Bool onlyVisible : if true, only visible links are counted
+   * @return Array
+   */
+  protected function getLinksCount($onlyVisible=false)
   {
     $returned=0;
     $sql="SELECT count(id) FROM ".$this->tables['urls'];
-    if($only_visible)
+    if($onlyVisible)
     {
       $sql.=" WHERE visible = 'y' ";
@@ -165,26 +315,60 @@
   }
 
-  // return an array of sections (each section is an array)
-  protected function get_sections($only_visible=false, $lang="", $only_with_content=true)
+  /**
+   * set order from given links
+   *
+   * @param Array $links : array
+   *                        each item is an array ('id' => '', 'order' =>'')
+   * @return Bool :
+   */
+  protected function setLinksOrder($links)
+  {
+    $returned=true;
+
+    foreach($links as $link)
+    {
+      $sql="UPDATE ".$this->tables['urls']."
+            SET position='".$link['order']."'
+            WHERE id='".$link['id']."';";
+      $result=pwg_query($sql);
+      if(!$result) $returned=false;
+    }
+    return($returned);
+  }
+
+
+  /*
+   *  ---------------------------------------------------------------------------
+   *
+   * Personalised Blocks functions
+   *
+   * ---------------------------------------------------------------------------
+   */
+
+
+  /**
+   * return an array of personalised blocks (each block is an array)
+   *
+   * @param Bool onlyVisible : if true, only visibles blocks are returned
+   * @return Array
+   */
+  protected function getPersonalisedBlocks($onlyVisible=false, $lang='', $emptyContent=false)
   {
     global $user;
 
-    if($lang=="")
-    {
-      $lang=$user['language'];
-    }
+    if($lang=="") $lang=$user['language'];
 
     $returned=array();
-    $sql="SELECT * FROM ".$this->tables['personalised']."
-WHERE (lang = '*' OR lang = '".$lang."') ";
-    if($only_visible)
-    {
-      $sql.=" AND visible = 'y' ";
-    }
-    if($only_with_content)
-    {
-      $sql.=" AND content != '' ";
-    }
-    $sql.=" ORDER BY id, lang DESC ";
+    $sql="SELECT pt.id, pt.visible, pt.nfo, ptl.lang, ptl.title, ptl.content
+          FROM ".$this->tables['personalised']." pt
+            LEFT JOIN ".$this->tables['personalised_langs']." ptl
+            ON pt.id=ptl.id
+          WHERE (ptl.lang = '*' OR ptl.lang = '".$lang."') ";
+
+    if($onlyVisible) $sql.=" AND pt.visible = 'y' ";
+    if($emptyContent==false) $sql.=" AND ptl.content != '' ";
+
+    $sql.=" ORDER BY pt.id, ptl.lang ASC ";
+
     $result=pwg_query($sql);
     if($result)
@@ -198,6 +382,272 @@
   }
 
-
-  protected function sortSectionsItemsCompare($a, $b)
+  /**
+   * return values for a given personalised block
+   *
+   * @param String $id : link id
+   * @return Array
+   */
+  protected function getPersonalisedBlock($id)
+  {
+    $returned=array(
+      'visible' => false,
+      'nfo' => '',
+      'langs' => array()
+    );
+
+    $sql="SELECT visible, nfo
+          FROM ".$this->tables['personalised']."
+          WHERE id='$id';";
+
+    $result=pwg_query($sql);
+    if($result)
+    {
+      while($row=pwg_db_fetch_assoc($result))
+      {
+        $returned['visible']=$row['visible'];
+        $returned['nfo']=$row['nfo'];
+      }
+
+      $sql="SELECT lang, title, content
+            FROM ".$this->tables['personalised_langs']."
+            WHERE id='$id'
+            ORDER BY lang ASC;";
+
+      $result=pwg_query($sql);
+      if($result)
+      {
+        while($row=pwg_db_fetch_assoc($result))
+        {
+          $returned['langs'][$row['lang']]=$row;
+        }
+      }
+    }
+    return($returned);
+  }
+
+  /**
+   * set values for a personalised block
+   * if block id is empty : create a new block
+   * if not, update block
+   *
+   * @param String $id : block id
+   * @return Integer : -1 if fails
+   *                   otherwise block id
+   */
+  protected function setPersonalisedBlock($id, $visible, $nfo, $langs)
+  {
+    $ok=false;
+
+    if($id=='')
+    {
+      $sql="INSERT INTO ".$this->tables['personalised']." VALUES
+            ('',
+             '$visible',
+             '".pwg_db_real_escape_string($nfo)."'
+            );";
+      $result=pwg_query($sql);
+      if($result) $ok=true;
+      $id=pwg_db_insert_id();
+    }
+    else
+    {
+      $sql="UPDATE ".$this->tables['personalised']."
+            SET visible='$visible',
+                nfo='".pwg_db_real_escape_string($nfo)."'
+            WHERE id='$id';";
+      $result=pwg_query($sql);
+      if($result)
+      {
+        $sql="DELETE FROM ".$this->tables['personalised_langs']."
+              WHERE id='$id';";
+        $result=pwg_query($sql);
+
+        if($result) $ok=true;
+      }
+    }
+
+    if($ok)
+    {
+      $values=array();
+      foreach($langs as $key => $lang)
+      {
+        $values[]="('$id',
+                    '".$lang['lang']."',
+                    '".pwg_db_real_escape_string($lang['title'])."',
+                    '".pwg_db_real_escape_string($lang['content'])."')";
+      }
+      $sql="INSERT INTO ".$this->tables['personalised_langs']." VALUES ".implode(',', $values);
+      $result=pwg_query($sql);
+
+      if($result) $ok=true;
+    }
+
+    if($ok) return($id);
+    return(-1);
+  }
+
+  /**
+   * delete a given personalised block
+   *
+   * @param String $id : block id
+   * @return Bool : true if deleted, otherwise false
+   */
+  protected function deletePersonalisedBlock($id)
+  {
+    $sql="DELETE FROM ".$this->tables['personalised']."
+          WHERE id = '$id';";
+    $result=pwg_query($sql);
+    if($result)
+    {
+      $sql="DELETE FROM ".$this->tables['personalised_langs']."
+            WHERE id = '$id';";
+      $result=pwg_query($sql);
+
+      if($result) return(true);
+    }
+
+    return(false);
+  }
+
+
+
+  /**
+   * return an array of all registered blocks
+   * each array item is an array :
+   *  String  'id'      => ''
+   *  Integer 'order'   => 0
+   *  Array   'users'   => array()
+   *  Array   'groups'  => array()
+   *  String  'name'    => ''
+   *  String  'owner'   => ''
+   *
+   * @param Bool $userFiltered : true if returned blocks are filtered to current
+   *                             user
+   * @return Array
+   */
+  protected function getRegisteredBlocks($userFiltered=false)
+  {
+    global $conf, $user;
+
+    $returned=array();
+    $order=0;
+    $users=new GPCUsers();
+    $groups=new GPCGroups();
+
+    $menu = new BlockManager('menubar');
+    $menu->load_registered_blocks();
+    $registeredBlocks = $menu->get_registered_blocks();
+
+    $sql="SELECT id, `order`, users, groups
+          FROM ".$this->tables['blocks']."
+          ORDER BY `order`;";
+    $result=pwg_query($sql);
+    if($result)
+    {
+      while($row=pwg_db_fetch_assoc($result))
+      {
+        $row['users']=explode(',', $row['users']);
+        $row['groups']=explode(',', $row['groups']);
+
+        if(isset($registeredBlocks[$row['id']]))
+        {
+          $ok=true;
+          if($userFiltered)
+          {
+            $users->setAlloweds($row['users'], false);
+            if($users->isAllowed($user['status']))
+            {
+              $groups->setAlloweds($row['groups'], false);
+              foreach($row['groups'] as $val)
+              {
+                if(!$groups->isAllowed($val)) $ok=false;
+              }
+            }
+            else
+            {
+              $ok=false;
+            }
+          }
+
+          if($ok)
+          {
+            $returned[$row['id']]=array(
+              'id'    => $row['id'],
+              'order' => $row['order'],
+              'users' => $row['users'],
+              'groups'=> $row['groups'],
+              'name'  => $registeredBlocks[$row['id']]->get_name(),
+              'owner' => $registeredBlocks[$row['id']]->get_owner()
+            );
+            $order=$row['order'];
+          }
+          unset($registeredBlocks[$row['id']]);
+        }
+      }
+    }
+
+    /*
+     * add new blocks, unknown from plugin
+     * by default, users & groups are visibles
+     */
+    foreach($registeredBlocks as $key=>$val)
+    {
+      $order+=10;
+
+      $returned[$key]=array(
+        'id'    => $key,
+        'order' => $order,
+        'users' => array(),
+        'groups'=> array(),
+        'name'  => $val->get_name(),
+        'owner' => $val->get_owner()
+      );
+    }
+
+    return($returned);
+  }
+
+
+  /**
+   * set order for registered blocks
+   *
+   * note : Piwigo's order is maintened
+   *
+   * @param Array $block : array of block ; each items is an array
+   *                        String  'id'    => ''
+   *                        Integer 'order' => ''
+   *                        Array   'users'   => array()
+   *                        Array   'groups'  => array()
+   * @return Bool : true, false is something is wrong
+   */
+  protected function setRegisteredBlocks($blocks)
+  {
+    $returned=true;
+
+    $sql="DELETE FROM ".$this->tables['blocks'];
+    pwg_query($sql);
+
+    foreach($blocks as $block)
+    {
+      $sql="INSERT INTO ".$this->tables['blocks']." VALUES (
+            '".pwg_db_real_escape_string($block['id'])."',
+            '".$block['order']."',
+            '".pwg_db_real_escape_string(implode(',', $block['users']))."',
+            '".pwg_db_real_escape_string(implode(',', $block['groups']))."'
+            );";
+      $result=pwg_query($sql);
+      if(!$result) $returned=false;
+    }
+
+    return($returned);
+  }
+
+
+
+
+
+
+
+  protected function sortCoreBlocksItemsCompare($a, $b)
   {
     if($a['container']==$b['container'])
@@ -209,7 +659,7 @@
   }
 
-  protected function sortSectionsItems()
-  {
-    uasort($this->config['amm_sections_items'], array($this, "sortSectionsItemsCompare"));
+  protected function sortCoreBlocksItems()
+  {
+    uasort($this->config['amm_blocks_items'], array($this, "sortCoreBlocksItemsCompare"));
   }
 
Index: /extensions/AMenuManager/amm_version.inc.php
===================================================================
--- /extensions/AMenuManager/amm_version.inc.php	(revision 8961)
+++ /extensions/AMenuManager/amm_version.inc.php	(revision 8962)
@@ -15,5 +15,6 @@
   if (!defined('PHPWG_ROOT_PATH')) die('Hacking attempt!');
 
-  define('AMM_VERSION',  '2.2.3');
-  define('AMM_VERSION2', '02.02.03');
+  define('AMM_VERSION',  '3.0.0');
+  define('AMM_VERSION2', '03.00.00');
+  define('AMM_GPC_NEEDED', '3.4.0');
 ?>
Index: /extensions/AMenuManager/js/amm_albumConfig.js
===================================================================
--- /extensions/AMenuManager/js/amm_albumConfig.js	(revision 8962)
+++ /extensions/AMenuManager/js/amm_albumConfig.js	(revision 8962)
@@ -0,0 +1,129 @@
+/**
+ * albumConfig
+ *
+ * release 1.0.0
+ */
+function albumConfig(opt, keys, token, initValues)
+{
+  var options = {
+          ajaxUrl:'plugins/AMenuManager/amm_ajax.php'
+        },
+      translatedKeys= {
+        },
+      properties = {
+          token:token
+        },
+
+
+  /**
+   * submit config
+   */
+  submit = function ()
+    {
+      if(!checkValidity()) return(false);
+
+      displayProcessing(true);
+
+      // build datas
+      var datas = {
+        selectCat:$("#iamm_album_selectedCat").categorySelector('value')
+      };
+
+
+      $.ajax(
+        {
+          type: "POST",
+          url: options.ajaxUrl,
+          async: true,
+          data: { ajaxfct:"admin.album.setConfig", token:properties.token, datas:datas },
+          success:
+            function(msg)
+            {
+              displayProcessing(false);
+
+              returned=msg.split('!');
+
+              if(returned[0]=='OK')
+              {
+                $('#iConfigState')
+                  .html(returned[1])
+                  .removeClass('errors')
+                  .addClass('infos')
+                  .css('display', 'block');
+              }
+              else
+              {
+                $('#iConfigState')
+                  .html(returned[1])
+                  .removeClass('infos')
+                  .addClass('errors')
+                  .css('display', 'block');
+              }
+            }
+        }
+      );
+    },
+
+  /**
+   * check validity of form
+   */
+  checkValidity = function ()
+    {
+      $('.error').removeClass('error');
+      ok=true;
+
+      return(ok);
+    },
+
+  /**
+   * display or hide the processing flower
+   */
+  displayProcessing = function (visible)
+    {
+      if(visible)
+      {
+        $('#iBDProcessing').css("display", "block");
+      }
+      else
+      {
+        $('#iBDProcessing').css("display", "none");
+      }
+    },
+
+  /**
+   * initialize the object and page form
+   */
+  init = function (initValues)
+  {
+    $('#iamm_album_selectedCat').categorySelector(
+      {
+        serverUrl:'plugins/GrumPluginClasses/gpc_ajax.php',
+        listMaxWidth:650,
+        listMaxHeight:550,
+        userMode:'public',
+        galleryRoot:false,
+        displayStatus:false,
+        filter:'all',
+        multiple:true,
+        load:
+          function (event)
+          {
+            $(this)
+              .categorySelector('collapse', ':all')
+              .categorySelector('value', initValues.selectCat);
+          },
+        change: function () { $('#iConfigState').hide(); }
+      }
+    );
+  };
+
+
+  $.extend(options, opt);
+  $.extend(translatedKeys, keys);
+
+  this.submit = function () { submit(); };
+
+  init(initValues);
+}
+
+
Index: /extensions/AMenuManager/js/amm_albumConfig.min.js
===================================================================
--- /extensions/AMenuManager/js/amm_albumConfig.min.js	(revision 8962)
+++ /extensions/AMenuManager/js/amm_albumConfig.min.js	(revision 8962)
@@ -0,0 +1,15 @@
+/* file: amm_albumConfig.js - v1.0.0 | minified on 2011/01/28 with http://jscompress.com/ */
+function albumConfig(opt,keys,token,initValues)
+{var options={ajaxUrl:'plugins/AMenuManager/amm_ajax.php'},translatedKeys={},properties={token:token},submit=function()
+{if(!checkValidity())return(false);displayProcessing(true);var datas={selectCat:$("#iamm_album_selectedCat").categorySelector('value')};$.ajax({type:"POST",url:options.ajaxUrl,async:true,data:{ajaxfct:"admin.album.setConfig",token:properties.token,datas:datas},success:function(msg)
+{displayProcessing(false);returned=msg.split('!');if(returned[0]=='OK')
+{$('#iConfigState').html(returned[1]).removeClass('errors').addClass('infos').css('display','block');}
+else
+{$('#iConfigState').html(returned[1]).removeClass('infos').addClass('errors').css('display','block');}}});},checkValidity=function()
+{$('.error').removeClass('error');ok=true;return(ok);},displayProcessing=function(visible)
+{if(visible)
+{$('#iBDProcessing').css("display","block");}
+else
+{$('#iBDProcessing').css("display","none");}},init=function(initValues)
+{$('#iamm_album_selectedCat').categorySelector({serverUrl:'plugins/GrumPluginClasses/gpc_ajax.php',listMaxWidth:650,listMaxHeight:550,userMode:'public',galleryRoot:false,displayStatus:false,filter:'all',multiple:true,load:function(event)
+{$(this).categorySelector('collapse',':all').categorySelector('value',initValues.selectCat);},change:function(){$('#iConfigState').hide();}});};$.extend(options,opt);$.extend(translatedKeys,keys);this.submit=function(){submit();};init(initValues);}
Index: /extensions/AMenuManager/js/amm_blocks.js
===================================================================
--- /extensions/AMenuManager/js/amm_blocks.js	(revision 8962)
+++ /extensions/AMenuManager/js/amm_blocks.js	(revision 8962)
@@ -0,0 +1,275 @@
+
+function coreBlocks(opt, keys, token, initValues)
+{
+  var options = {
+          ajaxUrl:'plugins/AMenuManager/amm_ajax.php'
+        },
+      translatedKeys= {
+          g002_ok:'g002_ok',
+          g002_cancel:'g002_cancel',
+          g002_loading: 'g002_loading',
+          g002_editoflink : 'g002_editoflink',
+          g002_createoflink : 'g002_createoflink'
+        },
+      properties = {
+          id:'',
+          token:token,
+          resetValues:
+            {
+              'piwigo':[],
+              'cancel':[]
+            }
+        },
+
+  /**
+   * display tab content
+   */
+  displayTabContent = function (tab)
+    {
+      switch(tab)
+      {
+        case 'position':
+          $('#containerPos').css('display', 'block');
+          $('#containerMenu').css('display', 'none');
+          break;
+        case 'blocksContent':
+          $('#containerPos').css('display', 'none');
+          $('#containerMenu').css('display', 'block');
+          break;
+      }
+    }
+
+  /**
+   * reset values
+   * @param String mode : 'piwigo' (piwigo default value) or 'cancel' (restore previous settings)
+   */
+  reset = function(mode)
+    {
+      $('#iConfigState').hide();
+
+      for(var i=0;i<properties.resetValues[mode].length;i++)
+      {
+        var access=resetValues[mode][i].visibility.split('/'),
+            accessUsers=access[0].split(','),
+            accessGroup=access[1].split(',');
+
+        $("#menu_"+resetValues[mode][i].block).get(0).appendChild($("#i"+resetValues[mode][i].id).get(0));
+
+        $("#i"+resetValues[mode][i].id).find('input.visibilityUser').each(
+          function ()
+          {
+            $(this).attr('checked', $.inArray($(this).attr('value'), accessUsers)==-1);
+          }
+        );
+
+        $("#i"+resetValues[mode][i].id).find('input.visibilityGroup').each(
+          function ()
+          {
+            $(this).attr('checked', $.inArray($(this).attr('value'), accessGroup)==-1);
+          }
+        );
+      }
+    },
+
+  /**
+   * submit config
+   */
+  submit = function ()
+    {
+      if(!checkValidity()) return(false);
+
+      displayProcessing(true);
+
+      // build datas
+      var datas = {
+            menuItems: {},
+            blocks: {}
+          },
+          order=0;
+
+      $('#containerMenu ul.categoryUl li.categoryLi').each(
+        function ()
+        {
+          var visibilityUser=[]
+              visibilityGroup=[];
+
+          $(this).find('input.visibilityUser:not(:checked)').each(
+            function ()
+            {
+              visibilityUser.push($(this).attr('value'));
+            }
+          );
+          $(this).find('input.visibilityGroup:not(:checked)').each(
+            function ()
+            {
+              visibilityGroup.push($(this).attr('value'));
+            }
+          );
+
+          datas.menuItems[this.id.substr(1)]={
+            order:order,
+            container:$(this).parent().parent().attr('id').substr(14),
+            visibilityUser:visibilityUser,
+            visibilityGroup:visibilityGroup
+          };
+          order++;
+        }
+      );
+
+      order=0;
+      $('ul.menuUl li.menuListItem').each(
+        function ()
+        {
+          var id=$(this).attr('blockid'),
+              visibilityUser=$(this).find('div.menuListUsers').inputList('value'),
+              visibilityGroup=$(this).find('div.menuListGroups').inputList('value');
+
+          datas.blocks[id]={
+            id:id,
+            order:order,
+            users:visibilityUser,
+            groups:visibilityGroup
+          };
+
+          order++;
+        }
+      );
+
+      $.ajax(
+        {
+          type: "POST",
+          url: options.ajaxUrl,
+          async: true,
+          data: { ajaxfct:"admin.coreBlocks.setConfig", token:properties.token, datas:datas },
+          success:
+            function(msg)
+            {
+              displayProcessing(false);
+
+              returned=msg.split('!');
+
+              if(returned[0]=='OK')
+              {
+                properties.resetValues.cancel=[];
+                for(var id in datas.items)
+                {
+                  properties.resetValues.cancel.push(
+                    {
+                      id:id,
+                      block:datas.items[id].container,
+                      order:datas.items[id].order,
+                      visibility:datas.items[id].visibility
+                    }
+                  );
+                }
+
+                $('#iConfigState')
+                  .html(returned[1])
+                  .removeClass('errors')
+                  .addClass('infos')
+                  .css('display', 'block');
+              }
+              else
+              {
+                $('#iConfigState')
+                  .html(returned[1])
+                  .removeClass('infos')
+                  .addClass('errors')
+                  .css('display', 'block');
+              }
+            }
+        }
+      );
+    },
+
+  /**
+   * check validity of form
+   */
+  checkValidity = function ()
+    {
+      $('.error').removeClass('error');
+      ok=true;
+      return(ok);
+    },
+
+  /**
+   * display or hide the processing flower
+   */
+  displayProcessing = function (visible)
+    {
+      if(visible)
+      {
+        $('#iBDProcessing').css("display", "block");
+      }
+      else
+      {
+        $('#iBDProcessing').css("display", "none");
+      }
+    },
+
+  init = function (initValues)
+    {
+      properties.resetValues=initValues.resetValues;
+
+      $("#containerMenu").sortable(
+        {
+          connectWith: '.connectedSortable',
+          cursor: 'move',
+          opacity:0.6,
+          items: 'li:not(.menuItemDisabled)',
+          tolerance:'pointer',
+          start: function ()
+            {
+              $('#iConfigState').hide();
+            }
+        }
+      );
+
+      $('#containerMenu ul.categoryUl li.categoryLi img.visibilitySwitch').bind('click',
+        function ()
+        {
+          $('#'+$(this).parent().parent().attr('id')+'_visibility').toggle();
+          $('#iConfigState').hide();
+        }
+      );
+
+      $("ul.menuUl").sortable(
+        {
+          connectWith: '.connectedSortable',
+          axis: "y",
+          cursor: 'move',
+          opacity:0.6,
+          items: 'li.connectedSortable',
+          tolerance:'pointer',
+          start: function ()
+            {
+              $('#iConfigState').hide();
+            }
+        }
+      );
+
+      $('ul.menuUl li div.menuListUsers, ul.menuUl li div.menuListGroups').inputList(
+        {
+          listMaxHeight:300,
+          multiple:true,
+          popupMode:'mouseout',
+          returnMode:'notSelected',
+          change: function ()
+            {
+              $('#iConfigState').hide();
+            }
+        }
+      ).inputList('value', ':invert');
+
+
+      displayTabContent(initValues.tab);
+    };
+
+  this.reset = function (mode) { reset(mode); };
+  this.submit = function () { submit(); };
+  this.displayTabContent = function (tab) { displayTabContent(tab); };
+
+  init(initValues);
+}
+
+
Index: /extensions/AMenuManager/js/amm_blocks.min.js
===================================================================
--- /extensions/AMenuManager/js/amm_blocks.min.js	(revision 8962)
+++ /extensions/AMenuManager/js/amm_blocks.min.js	(revision 8962)
@@ -0,0 +1,32 @@
+/* file: amm_blocks.js - v1.0.0 | minified on 2011/01/28 with http://jscompress.com/ */
+function coreBlocks(opt,keys,token,initValues)
+{var options={ajaxUrl:'plugins/AMenuManager/amm_ajax.php'},translatedKeys={g002_ok:'g002_ok',g002_cancel:'g002_cancel',g002_loading:'g002_loading',g002_editoflink:'g002_editoflink',g002_createoflink:'g002_createoflink'},properties={id:'',token:token,resetValues:{'piwigo':[],'cancel':[]}},displayTabContent=function(tab)
+{switch(tab)
+{case'position':$('#containerPos').css('display','block');$('#containerMenu').css('display','none');break;case'blocksContent':$('#containerPos').css('display','none');$('#containerMenu').css('display','block');break;}}
+reset=function(mode)
+{$('#iConfigState').hide();for(var i=0;i<properties.resetValues[mode].length;i++)
+{var access=resetValues[mode][i].visibility.split('/'),accessUsers=access[0].split(','),accessGroup=access[1].split(',');$("#menu_"+resetValues[mode][i].block).get(0).appendChild($("#i"+resetValues[mode][i].id).get(0));$("#i"+resetValues[mode][i].id).find('input.visibilityUser').each(function()
+{$(this).attr('checked',$.inArray($(this).attr('value'),accessUsers)==-1);});$("#i"+resetValues[mode][i].id).find('input.visibilityGroup').each(function()
+{$(this).attr('checked',$.inArray($(this).attr('value'),accessGroup)==-1);});}},submit=function()
+{if(!checkValidity())return(false);displayProcessing(true);var datas={menuItems:{},blocks:{}},order=0;$('#containerMenu ul.categoryUl li.categoryLi').each(function()
+{var visibilityUser=[]
+visibilityGroup=[];$(this).find('input.visibilityUser:not(:checked)').each(function()
+{visibilityUser.push($(this).attr('value'));});$(this).find('input.visibilityGroup:not(:checked)').each(function()
+{visibilityGroup.push($(this).attr('value'));});datas.menuItems[this.id.substr(1)]={order:order,container:$(this).parent().parent().attr('id').substr(14),visibilityUser:visibilityUser,visibilityGroup:visibilityGroup};order++;});order=0;$('ul.menuUl li.menuListItem').each(function()
+{var id=$(this).attr('blockid'),visibilityUser=$(this).find('div.menuListUsers').inputList('value'),visibilityGroup=$(this).find('div.menuListGroups').inputList('value');datas.blocks[id]={id:id,order:order,users:visibilityUser,groups:visibilityGroup};order++;});$.ajax({type:"POST",url:options.ajaxUrl,async:true,data:{ajaxfct:"admin.coreBlocks.setConfig",token:properties.token,datas:datas},success:function(msg)
+{displayProcessing(false);returned=msg.split('!');if(returned[0]=='OK')
+{properties.resetValues.cancel=[];for(var id in datas.items)
+{properties.resetValues.cancel.push({id:id,block:datas.items[id].container,order:datas.items[id].order,visibility:datas.items[id].visibility});}
+$('#iConfigState').html(returned[1]).removeClass('errors').addClass('infos').css('display','block');}
+else
+{$('#iConfigState').html(returned[1]).removeClass('infos').addClass('errors').css('display','block');}}});},checkValidity=function()
+{$('.error').removeClass('error');ok=true;return(ok);},displayProcessing=function(visible)
+{if(visible)
+{$('#iBDProcessing').css("display","block");}
+else
+{$('#iBDProcessing').css("display","none");}},init=function(initValues)
+{properties.resetValues=initValues.resetValues;$("#containerMenu").sortable({connectWith:'.connectedSortable',cursor:'move',opacity:0.6,items:'li:not(.menuItemDisabled)',tolerance:'pointer',start:function()
+{$('#iConfigState').hide();}});$('#containerMenu ul.categoryUl li.categoryLi img.visibilitySwitch').bind('click',function()
+{$('#'+$(this).parent().parent().attr('id')+'_visibility').toggle();$('#iConfigState').hide();});$("ul.menuUl").sortable({connectWith:'.connectedSortable',axis:"y",cursor:'move',opacity:0.6,items:'li.connectedSortable',tolerance:'pointer',start:function()
+{$('#iConfigState').hide();}});$('ul.menuUl li div.menuListUsers, ul.menuUl li div.menuListGroups').inputList({listMaxHeight:300,multiple:true,popupMode:'mouseout',returnMode:'notSelected',change:function()
+{$('#iConfigState').hide();}}).inputList('value',':invert');displayTabContent(initValues.tab);};this.reset=function(mode){reset(mode);};this.submit=function(){submit();};this.displayTabContent=function(tab){displayTabContent(tab);};init(initValues);}
Index: /extensions/AMenuManager/js/amm_links.js
===================================================================
--- /extensions/AMenuManager/js/amm_links.js	(revision 8962)
+++ /extensions/AMenuManager/js/amm_links.js	(revision 8962)
@@ -0,0 +1,366 @@
+/**
+ * userLinksManage
+ *
+ * release 1.0.0
+ */
+function userLinksManage (opt, keys, token)
+{
+  var options = {
+          ajaxUrl:'plugins/AMenuManager/amm_ajax.php'
+        },
+      translatedKeys= {
+          g002_ok:'g002_ok',
+          g002_cancel:'g002_cancel',
+          g002_loading: 'g002_loading',
+          g002_editoflink : 'g002_editoflink',
+          g002_createoflink : 'g002_createoflink'
+        },
+      properties = {
+          id:'',
+          token:token
+        },
+
+  /**
+   * load links list
+   */
+  load = function ()
+    {
+      $("#iList table.littlefont").sortable('destroy');
+      $('#iList').html("<br>"+translatedKeys.g002_loading+"<br><img src='./plugins/GrumPluginClasses/icons/processing.gif'>");
+
+      $.ajax(
+        {
+          type: "POST",
+          url: options.ajaxUrl,
+          async: true,
+          data: { ajaxfct:"admin.links.list" },
+          success:
+            function(msg)
+            {
+              $("#iList").html(msg);
+              $('#iListOrderButtons').css("display", 'none');
+
+              $("#iList").sortable(
+                {
+                  connectWith: '.connectedSortable',
+                  axis: "y",
+                  cursor: 'move',
+                  opacity:0.6,
+                  items: 'li',
+                  tolerance:'pointer',
+                  update: function () {  $('#iListOrderButtons').css("display", 'block'); }
+                }
+              );
+            }
+        }
+      );
+    },
+
+  /**
+   * edit or create a new link
+   *
+   * @param String linkId : if empty, assume to create a new link
+   */
+  edit = function (linkId)
+    {
+      properties.id=linkId;
+
+      $('#iDialogEdit')
+        .dialog('option', 'title', (linkId=='')?translatedKeys.g002_createoflink:translatedKeys.g002_editoflink)
+        .dialog("open");
+    },
+
+  /**
+   * remove a link
+   *
+   * @param String linkId : link to remove
+   */
+  remove = function (linkId)
+    {
+      properties.id=linkId;
+
+      $.ajax(
+        {
+          type: "POST",
+          url: options.ajaxUrl,
+          async: true,
+          data: { ajaxfct:"admin.links.delete", id:properties.id, token:properties.token },
+          success:
+            function(msg)
+            {
+              load();
+            }
+        }
+      );
+    },
+
+  /**
+   * check validity of form
+   */
+  checkValidity = function ()
+    {
+      $('.error').removeClass('error');
+      ok=true;
+
+      if($('#iamm_label').inputText('value')=='')
+      {
+        $('#iamm_label').inputText('isValid', false);
+        ok=false;
+      }
+
+      if($('#iamm_url').inputText('value')=='')
+      {
+        $('#iamm_url').inputText('isValid', false);
+        ok=false;
+      }
+
+      return(ok);
+    },
+
+
+  /**
+   * update values of the dialog box
+   *
+   * @param String items : json string ; if empty assume to reset all fields
+   *                       with default values
+   */
+  updateDialog = function (items)
+    {
+      if(items=='')
+      {
+        $('#iamm_label').inputText('value', '');
+        $('#iamm_url').inputText('value', '');
+        $('#iamm_icon').inputList('value', ':first');
+        $('#iamm_mode').inputList('value', ':first');
+        $('#iamm_visible').inputRadio('value', 'y');
+        $('#iamm_access_users').inputCheckbox('value', ':all');
+        $('#iamm_access_groups').inputCheckbox('value', ':all');
+      }
+      else
+      {
+        tmp=$.parseJSON(items);
+
+        $('#iamm_label').inputText('value', tmp.label);
+        $('#iamm_url').inputText('value', tmp.url);
+        $('#iamm_icon').inputList('value', tmp.icon);
+        $('#iamm_mode').inputList('value', tmp.mode);
+        $('#iamm_visible').inputRadio('value', tmp.visible);
+        $('#iamm_access_users').inputCheckbox('value', '', tmp.accessUsers);
+        $('#iamm_access_users').inputCheckbox('value', ':invert');
+        $('#iamm_access_groups').inputCheckbox('value', '', tmp.accessGroups);
+        $('#iamm_access_groups').inputCheckbox('value', ':invert');
+      }
+    },
+
+  /**
+   * update order on server
+   */
+  doUpdateOrder = function ()
+    {
+      var datas={
+            links:[]
+          },
+          order=0;
+
+      $('#iList li.connectedSortable').each(
+        function ()
+        {
+          datas.links.push(
+            {
+              id:$(this).attr('linkId'),
+              order:order
+            }
+          );
+          order++;
+        }
+      );
+
+      $.ajax(
+        {
+          type: "POST",
+          url: options.ajaxUrl,
+          async: true,
+          data: { ajaxfct:"admin.links.order", token:properties.token, datas:datas },
+          success:
+            function(msg)
+            {
+              displayProcessing(false);
+
+              returned=msg.split('!');
+
+              if(returned[0]=='OK')
+              {
+                $('#iListOrderButtons').css("display", 'none');
+              }
+              else
+              {
+                $('#'+returned[0]).addClass('error');
+                alert(returned[1]);
+              }
+            }
+        }
+      );
+    },
+
+  /**
+   * update values on server
+   */
+  doUpdate = function ()
+    {
+      displayProcessing(true);
+
+      // build datas
+      var datas = {
+        label:$('#iamm_label').inputText('value'),
+        url:$('#iamm_url').inputText('value'),
+        icon:$('#iamm_icon').inputList('value'),
+        mode:$('#iamm_mode').inputList('value'),
+        visible:$('#iamm_visible').inputRadio('value'),
+        accessUsers:$('#iamm_access_users').inputCheckbox('value'),
+        accessGroups:$('#iamm_access_groups').inputCheckbox('value')
+      };
+
+      $.ajax(
+        {
+          type: "POST",
+          url: options.ajaxUrl,
+          async: true,
+          data: { ajaxfct:"admin.links.set", id:properties.id, token:properties.token, datas:datas },
+          success:
+            function(msg)
+            {
+              displayProcessing(false);
+
+              if(msg.match(/^[0-9]+$/i)!=null)
+              {
+                // result Ok ! => close the dialog box and reload the list
+                $('#iDialogEdit').dialog("close");
+                load();
+              }
+              else
+              {
+                returned=msg.split('!');
+                $('#'+returned[0]).addClass('error');
+                alert(returned[1]);
+              }
+            }
+        }
+      );
+    },
+
+  /**
+   * display or hide the processing flower
+   */
+  displayProcessing = function (visible)
+    {
+      if(visible)
+      {
+        $('#iBDProcessing').css("display", "block");
+      }
+      else
+      {
+        $('#iBDProcessing').css("display", "none");
+      }
+    },
+
+  /**
+   * initialize the object
+   */
+  init = function ()
+  {
+    var buttons={};
+
+    buttons[translatedKeys.g002_ok]=function()
+      {
+        if(checkValidity()) doUpdate();
+      };
+    buttons[translatedKeys.g002_cancel]=function()
+      {
+        $('#iDialogEdit').dialog("close");
+      };
+
+    $('#iDialogEdit')
+      .dialog(
+        {
+          autoOpen:false,
+          width:600,
+          height:400,
+          modal: true,
+          dialogClass: 'gcBgTabSheet gcBorder',
+          title: '',
+          buttons:buttons
+        }
+      )
+      .bind('dialogopen', function ()
+        {
+          if(properties.id!='')
+          {
+            displayProcessing(true);
+
+            $.ajax(
+              {
+                type: "POST",
+                url: options.ajaxUrl,
+                async: true,
+                data: { ajaxfct:"admin.links.get", id:properties.id },
+                success:
+                  function(msg)
+                  {
+                    updateDialog(msg);
+                    displayProcessing(false);
+                  }
+              }
+            );
+          }
+          else
+          {
+            updateDialog('');
+          }
+        }
+      );
+
+    $('#iamm_label').inputText(
+      {
+        displayChar:50,
+        maxChar:50
+      }
+    );
+
+    $('#iamm_url').inputText(
+      {
+        displayChar:50,
+        maxChar:255
+      }
+    );
+
+    $('#iamm_icon').inputList(
+      {
+        listMaxWidth:250,
+        colsWidth:[22,200],
+        colsCss:['iconColImg','iconColText'],
+        popupMode:'mouseout'
+      }
+    );
+
+    $('#iamm_mode').inputList({popupMode:'mouseout'});
+
+    $('#iamm_visible').inputRadio();
+
+    $('#iamm_access_users').inputCheckbox({returnMode:'notSelected'});
+    $('#iamm_access_groups').inputCheckbox({returnMode:'notSelected'});
+
+    load();
+  };
+
+  $.extend(options, opt);
+  $.extend(translatedKeys, keys);
+
+  this.load = function () { load(); };
+  this.edit = function (linkId) { edit(linkId); };
+  this.remove = function (linkId) { remove(linkId); };
+  this.doUpdateOrder = function () { doUpdateOrder(); };
+
+  init();
+}
+
+
Index: /extensions/AMenuManager/js/amm_links.min.js
===================================================================
--- /extensions/AMenuManager/js/amm_links.min.js	(revision 8962)
+++ /extensions/AMenuManager/js/amm_links.min.js	(revision 8962)
@@ -0,0 +1,40 @@
+/* file: amm_links.js - v1.0.0 | minified on 2011/01/28 with http://jscompress.com/ */
+function userLinksManage(opt,keys,token)
+{var options={ajaxUrl:'plugins/AMenuManager/amm_ajax.php'},translatedKeys={g002_ok:'g002_ok',g002_cancel:'g002_cancel',g002_loading:'g002_loading',g002_editoflink:'g002_editoflink',g002_createoflink:'g002_createoflink'},properties={id:'',token:token},load=function()
+{$("#iList table.littlefont").sortable('destroy');$('#iList').html("<br>"+translatedKeys.g002_loading+"<br><img src='./plugins/GrumPluginClasses/icons/processing.gif'>");$.ajax({type:"POST",url:options.ajaxUrl,async:true,data:{ajaxfct:"admin.links.list"},success:function(msg)
+{$("#iList").html(msg);$('#iListOrderButtons').css("display",'none');$("#iList").sortable({connectWith:'.connectedSortable',axis:"y",cursor:'move',opacity:0.6,items:'li',tolerance:'pointer',update:function(){$('#iListOrderButtons').css("display",'block');}});}});},edit=function(linkId)
+{properties.id=linkId;$('#iDialogEdit').dialog('option','title',(linkId=='')?translatedKeys.g002_createoflink:translatedKeys.g002_editoflink).dialog("open");},remove=function(linkId)
+{properties.id=linkId;$.ajax({type:"POST",url:options.ajaxUrl,async:true,data:{ajaxfct:"admin.links.delete",id:properties.id,token:properties.token},success:function(msg)
+{load();}});},checkValidity=function()
+{$('.error').removeClass('error');ok=true;if($('#iamm_label').inputText('value')=='')
+{$('#iamm_label').inputText('isValid',false);ok=false;}
+if($('#iamm_url').inputText('value')=='')
+{$('#iamm_url').inputText('isValid',false);ok=false;}
+return(ok);},updateDialog=function(items)
+{if(items=='')
+{$('#iamm_label').inputText('value','');$('#iamm_url').inputText('value','');$('#iamm_icon').inputList('value',':first');$('#iamm_mode').inputList('value',':first');$('#iamm_visible').inputRadio('value','y');$('#iamm_access_users').inputCheckbox('value',':all');$('#iamm_access_groups').inputCheckbox('value',':all');}
+else
+{tmp=$.parseJSON(items);$('#iamm_label').inputText('value',tmp.label);$('#iamm_url').inputText('value',tmp.url);$('#iamm_icon').inputList('value',tmp.icon);$('#iamm_mode').inputList('value',tmp.mode);$('#iamm_visible').inputRadio('value',tmp.visible);$('#iamm_access_users').inputCheckbox('value','',tmp.accessUsers);$('#iamm_access_users').inputCheckbox('value',':invert');$('#iamm_access_groups').inputCheckbox('value','',tmp.accessGroups);$('#iamm_access_groups').inputCheckbox('value',':invert');}},doUpdateOrder=function()
+{var datas={links:[]},order=0;$('#iList li.connectedSortable').each(function()
+{datas.links.push({id:$(this).attr('linkId'),order:order});order++;});$.ajax({type:"POST",url:options.ajaxUrl,async:true,data:{ajaxfct:"admin.links.order",token:properties.token,datas:datas},success:function(msg)
+{displayProcessing(false);returned=msg.split('!');if(returned[0]=='OK')
+{$('#iListOrderButtons').css("display",'none');}
+else
+{$('#'+returned[0]).addClass('error');alert(returned[1]);}}});},doUpdate=function()
+{displayProcessing(true);var datas={label:$('#iamm_label').inputText('value'),url:$('#iamm_url').inputText('value'),icon:$('#iamm_icon').inputList('value'),mode:$('#iamm_mode').inputList('value'),visible:$('#iamm_visible').inputRadio('value'),accessUsers:$('#iamm_access_users').inputCheckbox('value'),accessGroups:$('#iamm_access_groups').inputCheckbox('value')};$.ajax({type:"POST",url:options.ajaxUrl,async:true,data:{ajaxfct:"admin.links.set",id:properties.id,token:properties.token,datas:datas},success:function(msg)
+{displayProcessing(false);if(msg.match(/^[0-9]+$/i)!=null)
+{$('#iDialogEdit').dialog("close");load();}
+else
+{returned=msg.split('!');$('#'+returned[0]).addClass('error');alert(returned[1]);}}});},displayProcessing=function(visible)
+{if(visible)
+{$('#iBDProcessing').css("display","block");}
+else
+{$('#iBDProcessing').css("display","none");}},init=function()
+{var buttons={};buttons[translatedKeys.g002_ok]=function()
+{if(checkValidity())doUpdate();};buttons[translatedKeys.g002_cancel]=function()
+{$('#iDialogEdit').dialog("close");};$('#iDialogEdit').dialog({autoOpen:false,width:600,height:400,modal:true,dialogClass:'gcBgTabSheet gcBorder',title:'',buttons:buttons}).bind('dialogopen',function()
+{if(properties.id!='')
+{displayProcessing(true);$.ajax({type:"POST",url:options.ajaxUrl,async:true,data:{ajaxfct:"admin.links.get",id:properties.id},success:function(msg)
+{updateDialog(msg);displayProcessing(false);}});}
+else
+{updateDialog('');}});$('#iamm_label').inputText({displayChar:50,maxChar:50});$('#iamm_url').inputText({displayChar:50,maxChar:255});$('#iamm_icon').inputList({listMaxWidth:250,colsWidth:[22,200],colsCss:['iconColImg','iconColText'],popupMode:'mouseout'});$('#iamm_mode').inputList({popupMode:'mouseout'});$('#iamm_visible').inputRadio();$('#iamm_access_users').inputCheckbox({returnMode:'notSelected'});$('#iamm_access_groups').inputCheckbox({returnMode:'notSelected'});load();};$.extend(options,opt);$.extend(translatedKeys,keys);this.load=function(){load();};this.edit=function(linkId){edit(linkId);};this.remove=function(linkId){remove(linkId);};this.doUpdateOrder=function(){doUpdateOrder();};init();}
Index: /extensions/AMenuManager/js/amm_linksConfig.js
===================================================================
--- /extensions/AMenuManager/js/amm_linksConfig.js	(revision 8962)
+++ /extensions/AMenuManager/js/amm_linksConfig.js	(revision 8962)
@@ -0,0 +1,129 @@
+/**
+ * userLinksConfig
+ *
+ * release 1.0.0
+ */
+function userLinksConfig(opt, keys, token, initValues)
+{
+  var options = {
+          ajaxUrl:'plugins/AMenuManager/amm_ajax.php'
+        },
+      translatedKeys= {
+        },
+      properties = {
+          token:token
+        },
+
+
+  /**
+   * submit config
+   */
+  submit = function ()
+    {
+      if(!checkValidity()) return(false);
+
+      displayProcessing(true);
+
+      // build datas
+      var datas = {
+        title:[],
+        showIcons:$('#iamm_links_show_icons').inputRadio('value')
+      };
+
+      list=$('#iamm_links_title').inputText('languagesValues');
+      for(var id in list)
+      {
+        datas.title.push({id:id, value:list[id]});
+      }
+
+      $.ajax(
+        {
+          type: "POST",
+          url: options.ajaxUrl,
+          async: true,
+          data: { ajaxfct:"admin.links.setConfig", token:properties.token, datas:datas },
+          success:
+            function(msg)
+            {
+              displayProcessing(false);
+
+              returned=msg.split('!');
+
+              if(returned[0]=='OK')
+              {
+                $('#iConfigState')
+                  .html(returned[1])
+                  .removeClass('errors')
+                  .addClass('infos')
+                  .css('display', 'block');
+              }
+              else
+              {
+                $('#iConfigState')
+                  .html(returned[1])
+                  .removeClass('infos')
+                  .addClass('errors')
+                  .css('display', 'block');
+              }
+            }
+        }
+      );
+    },
+
+  /**
+   * check validity of form
+   */
+  checkValidity = function ()
+    {
+      $('.error').removeClass('error');
+      ok=true;
+      return(ok);
+    },
+
+  /**
+   * display or hide the processing flower
+   */
+  displayProcessing = function (visible)
+    {
+      if(visible)
+      {
+        $('#iBDProcessing').css("display", "block");
+      }
+      else
+      {
+        $('#iBDProcessing').css("display", "none");
+      }
+    },
+
+  /**
+   * initialize the object
+   */
+  init = function (initValues)
+  {
+    $('#iamm_links_show_icons').inputRadio();
+    $('#iamm_links_show_icons').inputRadio('value', initValues.showIcons);
+
+    $('#islang').inputList({popupMode:'mouseout'});
+
+    $('#iamm_links_title').inputText(
+      {
+        languages:initValues.langs,
+        languagesValues:initValues.titles,
+        currentLanguage:initValues.userLang,
+        languageSelector:'islang',
+        displayChar:40
+      }
+    );
+
+    $('#islang').inputList('value', initValues.userLang);
+  };
+
+  $.extend(options, opt);
+  $.extend(translatedKeys, keys);
+
+  this.submit = function () { submit(); };
+
+  init(initValues);
+}
+
+
Index: /extensions/AMenuManager/js/amm_linksConfig.min.js
===================================================================
--- /extensions/AMenuManager/js/amm_linksConfig.min.js	(revision 8962)
+++ /extensions/AMenuManager/js/amm_linksConfig.min.js	(revision 8962)
@@ -0,0 +1,16 @@
+/* file: amm_linksConfig.js - v1.0.0 | minified on 2011/01/28 with http://jscompress.com/ */
+function userLinksConfig(opt,keys,token,initValues)
+{var options={ajaxUrl:'plugins/AMenuManager/amm_ajax.php'},translatedKeys={},properties={token:token},submit=function()
+{if(!checkValidity())return(false);displayProcessing(true);var datas={title:[],showIcons:$('#iamm_links_show_icons').inputRadio('value')};list=$('#iamm_links_title').inputText('languagesValues');for(var id in list)
+{datas.title.push({id:id,value:list[id]});}
+$.ajax({type:"POST",url:options.ajaxUrl,async:true,data:{ajaxfct:"admin.links.setConfig",token:properties.token,datas:datas},success:function(msg)
+{displayProcessing(false);returned=msg.split('!');if(returned[0]=='OK')
+{$('#iConfigState').html(returned[1]).removeClass('errors').addClass('infos').css('display','block');}
+else
+{$('#iConfigState').html(returned[1]).removeClass('infos').addClass('errors').css('display','block');}}});},checkValidity=function()
+{$('.error').removeClass('error');ok=true;return(ok);},displayProcessing=function(visible)
+{if(visible)
+{$('#iBDProcessing').css("display","block");}
+else
+{$('#iBDProcessing').css("display","none");}},init=function(initValues)
+{$('#iamm_links_show_icons').inputRadio();$('#iamm_links_show_icons').inputRadio('value',initValues.showIcons);$('#islang').inputList({popupMode:'mouseout'});$('#iamm_links_title').inputText({languages:initValues.langs,languagesValues:initValues.titles,currentLanguage:initValues.userLang,languageSelector:'islang',displayChar:40});$('#islang').inputList('value',initValues.userLang);};$.extend(options,opt);$.extend(translatedKeys,keys);this.submit=function(){submit();};init(initValues);}
Index: /extensions/AMenuManager/js/amm_personalisedBlocks.js
===================================================================
--- /extensions/AMenuManager/js/amm_personalisedBlocks.js	(revision 8962)
+++ /extensions/AMenuManager/js/amm_personalisedBlocks.js	(revision 8962)
@@ -0,0 +1,324 @@
+/**
+ * userPersonnalisedBlockManage
+ *
+ * release 1.0.0
+ */
+function userPersonnalisedBlockManage(opt, keys, token, initValues)
+{
+  var options = {
+          ajaxUrl:'plugins/AMenuManager/amm_ajax.php'
+        },
+      translatedKeys= {
+          g002_ok:'g002_ok',
+          g002_cancel:'g002_cancel',
+          g002_loading: 'g002_loading',
+          g002_editofpersonalised : 'g002_editofpersonalised',
+          g002_createofpersonalised : 'g002_createofpersonalised'
+        },
+      properties = {
+          id:'',
+          token:token
+        },
+
+  /**
+   * load blocks list
+   */
+  load = function ()
+    {
+      $('#iList').html("<br>"+translatedKeys.g002_loading+"<br><img src='./plugins/GrumPluginClasses/icons/processing.gif'>");
+
+      $.ajax(
+        {
+          type: "POST",
+          url: options.ajaxUrl,
+          async: true,
+          data: { ajaxfct:"admin.blocks.list" },
+          success:
+            function(msg)
+            {
+              $("#iList").html(msg);
+            }
+        }
+      );
+    },
+
+  /**
+   * edit or create a new block
+   *
+   * @param String blockId : if empty, assume to create a new block
+   */
+  edit = function (blockId)
+    {
+      properties.id=blockId;
+
+      $('#iDialogEdit')
+        .dialog('option', 'title', (blockId=='')?translatedKeys.g002_createofpersonalised:translatedKeys.g002_editofpersonalised)
+        .dialog("open");
+    },
+
+  /**
+   * remove a block
+   *
+   * @param String blockId : block to remove
+   */
+  remove = function (blockId)
+    {
+      properties.id=blockId;
+
+      $.ajax(
+        {
+          type: "POST",
+          url: options.ajaxUrl,
+          async: true,
+          data: { ajaxfct:"admin.blocks.delete", id:properties.id, token:properties.token },
+          success:
+            function(msg)
+            {
+              load();
+            }
+        }
+      );
+    },
+
+  /**
+   * check validity of form
+   */
+  checkValidity = function ()
+    {
+      $('.error').removeClass('error');
+      ok=true;
+/*
+      if($('#iamm_label').inputText('value')=='')
+      {
+        $('#iamm_label').inputText('isValid', false);
+        ok=false;
+      }
+
+      if($('#iamm_url').inputText('value')=='')
+      {
+        $('#iamm_url').inputText('isValid', false);
+        ok=false;
+      }
+*/
+      return(ok);
+    },
+
+
+  /**
+   * update values of the dialog box
+   *
+   * @param String items : json string ; if empty assume to reset all fields
+   *                       with default values
+   */
+  updateDialog = function (items)
+    {
+      if(items=='')
+      {
+        $('#iamm_personalised_nfo').inputText('value', '');
+        $('#iamm_personalised_title')
+          .inputText('value', '')
+          .inputText('languagesValues', {});
+        $('#iamm_personalised_content')
+          .inputText('value', '')
+          .inputText('languagesValues', {});
+        $('#iamm_personalised_visible').inputRadio('value', 'y');
+      }
+      else
+      {
+        var tmp=$.parseJSON(items),
+            titles={},
+            contents={};
+
+        for(var lang in tmp.langs)
+        {
+          titles[lang]=tmp.langs[lang].title;
+          contents[lang]=tmp.langs[lang].content;
+        }
+
+        $('#iamm_personalised_nfo').inputText('value', tmp.nfo);
+        $('#iamm_personalised_title').inputText('languagesValues', titles);
+        $('#iamm_personalised_content').inputText('languagesValues', contents);
+        $('#iamm_personalised_visible').inputRadio('value', tmp.visible);
+      }
+    },
+
+  /**
+   * update values on server
+   */
+  doUpdate = function ()
+    {
+      displayProcessing(true);
+
+      // build datas
+      var langs=[],
+          titles=$('#iamm_personalised_content').inputText('languagesValues'),
+          contents=$('#iamm_personalised_title').inputText('languagesValues');
+
+      for(var lang in titles)
+      {
+        langs.push(
+          {
+            lang:lang,
+            title:titles[lang],
+            content:contents[lang]
+          }
+        );
+      }
+
+
+
+
+      var datas = {
+        nfo:$('#iamm_personalised_nfo').inputText('value'),
+        visible:$('#iamm_personalised_visible').inputRadio('value'),
+        langs:langs
+      };
+
+      $.ajax(
+        {
+          type: "POST",
+          url: options.ajaxUrl,
+          async: true,
+          data: { ajaxfct:"admin.blocks.set", id:properties.id, token:properties.token, datas:datas },
+          success:
+            function(msg)
+            {
+              displayProcessing(false);
+
+              if(msg.match(/^[0-9]+$/i)!=null)
+              {
+                // result Ok ! => close the dialog box and reload the list
+                $('#iDialogEdit').dialog("close");
+                load();
+              }
+              else
+              {
+                returned=msg.split('!');
+                $('#'+returned[0]).addClass('error');
+                alert(returned[1]);
+              }
+            }
+        }
+      );
+    },
+
+  /**
+   * display or hide the processing flower
+   */
+  displayProcessing = function (visible)
+    {
+      if(visible)
+      {
+        $('#iBDProcessing').css("display", "block");
+      }
+      else
+      {
+        $('#iBDProcessing').css("display", "none");
+      }
+    },
+
+  /**
+   * initialize the object
+   */
+  init = function (initValues)
+  {
+    var buttons={};
+
+    buttons[translatedKeys.g002_ok]=function()
+      {
+        if(checkValidity()) doUpdate();
+      };
+    buttons[translatedKeys.g002_cancel]=function()
+      {
+        $('#iDialogEdit').dialog("close");
+      };
+
+    $('#iDialogEdit')
+      .dialog(
+        {
+          autoOpen:false,
+          width:800,
+          height:480,
+          modal: true,
+          dialogClass: 'gcBgTabSheet gcBorder',
+          title: '',
+          buttons:buttons
+        }
+      )
+      .bind('dialogopen', function ()
+        {
+          if(properties.id!='')
+          {
+            displayProcessing(true);
+
+            $.ajax(
+              {
+                type: "POST",
+                url: options.ajaxUrl,
+                async: true,
+                data: { ajaxfct:"admin.blocks.get", id:properties.id },
+                success:
+                  function(msg)
+                  {
+                    updateDialog(msg);
+                    displayProcessing(false);
+                  }
+              }
+            );
+          }
+          else
+          {
+            updateDialog('');
+          }
+        }
+      );
+
+    $('#islang').inputList({popupMode:'mouseout'});
+
+
+    $('#iamm_personalised_nfo').inputText(
+      {
+        displayChar:75,
+        maxChar:255
+      }
+    );
+
+    $('#iamm_personalised_title').inputText(
+      {
+        displayChar:75,
+        maxChar:255,
+        languages:initValues.langs,
+        currentLanguage:initValues.userLang,
+        languageSelector:'islang'
+      }
+    );
+
+    $('#iamm_personalised_content').inputText(
+      {
+        multilines:true,
+        displayChar:70,
+        numRows:13,
+        languages:initValues.langs,
+        currentLanguage:initValues.userLang,
+        languageSelector:'islang'
+      }
+    );
+
+    $('#islang').inputList('value', initValues.userLang);
+
+    $('#iamm_personalised_visible').inputRadio();
+
+    load();
+  };
+
+  $.extend(options, opt);
+  $.extend(translatedKeys, keys);
+
+  this.load = function () { load(); };
+  this.edit = function (linkId) { edit(linkId); };
+  this.remove = function (linkId) { remove(linkId); };
+
+  init(initValues);
+}
+
+
Index: /extensions/AMenuManager/js/amm_personalisedBlocks.min.js
===================================================================
--- /extensions/AMenuManager/js/amm_personalisedBlocks.min.js	(revision 8962)
+++ /extensions/AMenuManager/js/amm_personalisedBlocks.min.js	(revision 8962)
@@ -0,0 +1,34 @@
+/* file: amm_personalisedBlocks.js - v1.0.0 | minified on 2011/01/28 with http://jscompress.com/ */
+function userPersonnalisedBlockManage(opt,keys,token,initValues)
+{var options={ajaxUrl:'plugins/AMenuManager/amm_ajax.php'},translatedKeys={g002_ok:'g002_ok',g002_cancel:'g002_cancel',g002_loading:'g002_loading',g002_editofpersonalised:'g002_editofpersonalised',g002_createofpersonalised:'g002_createofpersonalised'},properties={id:'',token:token},load=function()
+{$('#iList').html("<br>"+translatedKeys.g002_loading+"<br><img src='./plugins/GrumPluginClasses/icons/processing.gif'>");$.ajax({type:"POST",url:options.ajaxUrl,async:true,data:{ajaxfct:"admin.blocks.list"},success:function(msg)
+{$("#iList").html(msg);}});},edit=function(blockId)
+{properties.id=blockId;$('#iDialogEdit').dialog('option','title',(blockId=='')?translatedKeys.g002_createofpersonalised:translatedKeys.g002_editofpersonalised).dialog("open");},remove=function(blockId)
+{properties.id=blockId;$.ajax({type:"POST",url:options.ajaxUrl,async:true,data:{ajaxfct:"admin.blocks.delete",id:properties.id,token:properties.token},success:function(msg)
+{load();}});},checkValidity=function()
+{$('.error').removeClass('error');ok=true;return(ok);},updateDialog=function(items)
+{if(items=='')
+{$('#iamm_personalised_nfo').inputText('value','');$('#iamm_personalised_title').inputText('value','').inputText('languagesValues',{});$('#iamm_personalised_content').inputText('value','').inputText('languagesValues',{});$('#iamm_personalised_visible').inputRadio('value','y');}
+else
+{var tmp=$.parseJSON(items),titles={},contents={};for(var lang in tmp.langs)
+{titles[lang]=tmp.langs[lang].title;contents[lang]=tmp.langs[lang].content;}
+$('#iamm_personalised_nfo').inputText('value',tmp.nfo);$('#iamm_personalised_title').inputText('languagesValues',titles);$('#iamm_personalised_content').inputText('languagesValues',contents);$('#iamm_personalised_visible').inputRadio('value',tmp.visible);}},doUpdate=function()
+{displayProcessing(true);var langs=[],titles=$('#iamm_personalised_content').inputText('languagesValues'),contents=$('#iamm_personalised_title').inputText('languagesValues');for(var lang in titles)
+{langs.push({lang:lang,title:titles[lang],content:contents[lang]});}
+var datas={nfo:$('#iamm_personalised_nfo').inputText('value'),visible:$('#iamm_personalised_visible').inputRadio('value'),langs:langs};$.ajax({type:"POST",url:options.ajaxUrl,async:true,data:{ajaxfct:"admin.blocks.set",id:properties.id,token:properties.token,datas:datas},success:function(msg)
+{displayProcessing(false);if(msg.match(/^[0-9]+$/i)!=null)
+{$('#iDialogEdit').dialog("close");load();}
+else
+{returned=msg.split('!');$('#'+returned[0]).addClass('error');alert(returned[1]);}}});},displayProcessing=function(visible)
+{if(visible)
+{$('#iBDProcessing').css("display","block");}
+else
+{$('#iBDProcessing').css("display","none");}},init=function(initValues)
+{var buttons={};buttons[translatedKeys.g002_ok]=function()
+{if(checkValidity())doUpdate();};buttons[translatedKeys.g002_cancel]=function()
+{$('#iDialogEdit').dialog("close");};$('#iDialogEdit').dialog({autoOpen:false,width:800,height:480,modal:true,dialogClass:'gcBgTabSheet gcBorder',title:'',buttons:buttons}).bind('dialogopen',function()
+{if(properties.id!='')
+{displayProcessing(true);$.ajax({type:"POST",url:options.ajaxUrl,async:true,data:{ajaxfct:"admin.blocks.get",id:properties.id},success:function(msg)
+{updateDialog(msg);displayProcessing(false);}});}
+else
+{updateDialog('');}});$('#islang').inputList({popupMode:'mouseout'});$('#iamm_personalised_nfo').inputText({displayChar:75,maxChar:255});$('#iamm_personalised_title').inputText({displayChar:75,maxChar:255,languages:initValues.langs,currentLanguage:initValues.userLang,languageSelector:'islang'});$('#iamm_personalised_content').inputText({multilines:true,displayChar:70,numRows:13,languages:initValues.langs,currentLanguage:initValues.userLang,languageSelector:'islang'});$('#islang').inputList('value',initValues.userLang);$('#iamm_personalised_visible').inputRadio();load();};$.extend(options,opt);$.extend(translatedKeys,keys);this.load=function(){load();};this.edit=function(linkId){edit(linkId);};this.remove=function(linkId){remove(linkId);};init(initValues);}
Index: /extensions/AMenuManager/js/amm_randomPictConfig.js
===================================================================
--- /extensions/AMenuManager/js/amm_randomPictConfig.js	(revision 8962)
+++ /extensions/AMenuManager/js/amm_randomPictConfig.js	(revision 8962)
@@ -0,0 +1,254 @@
+/**
+ * randomPictConfig
+ *
+ * release 1.0.0
+ */
+function randomPictConfig(opt, keys, token, initValues)
+{
+  var options = {
+          ajaxUrl:'plugins/AMenuManager/amm_ajax.php'
+        },
+      translatedKeys= {
+          g002_setting_randompic_periodicchange_deactivated:'g002_setting_randompic_periodicchange_deactivated',
+          g002_setting_randompic_height_auto:'g002_setting_randompic_height_auto'
+        },
+      properties = {
+          token:token
+        },
+
+
+  /**
+   * submit config
+   */
+  submit = function ()
+    {
+      if(!checkValidity()) return(false);
+
+      displayProcessing(true);
+
+      // build datas
+      var datas = {
+        blockTitles:[],
+        blockHeight:$("#iamm_rp_height_slider").slider('option', 'value'),
+        infosName:$("#iamm_randompicture_showname").inputList('value'),
+        infosComment:$("#iamm_randompicture_showcomment").inputList('value'),
+        freqDelay:$("#iamm_rp_pc_slider").slider('option', 'value')==99?0:$("#iamm_rp_pc_slider").slider('option', 'value'),
+        selectMode:$("#iamm_randompicture_selectedMode").inputRadio('value'),
+        selectCat:$("#iamm_randompicture_selectedCat").categorySelector('value')
+      };
+
+
+
+      list=$('#iamm_randompicture_title').inputText('languagesValues');
+      for(var id in list)
+      {
+        datas.blockTitles.push({id:id, value:list[id]});
+      }
+
+      $.ajax(
+        {
+          type: "POST",
+          url: options.ajaxUrl,
+          async: true,
+          data: { ajaxfct:"admin.randomPict.setConfig", token:properties.token, datas:datas },
+          success:
+            function(msg)
+            {
+              displayProcessing(false);
+
+              returned=msg.split('!');
+
+              if(returned[0]=='OK')
+              {
+                $('#iConfigState')
+                  .html(returned[1])
+                  .removeClass('errors')
+                  .addClass('infos')
+                  .css('display', 'block');
+              }
+              else
+              {
+                $('#iConfigState')
+                  .html(returned[1])
+                  .removeClass('infos')
+                  .addClass('errors')
+                  .css('display', 'block');
+              }
+            }
+        }
+      );
+    },
+
+  /**
+   * check validity of form
+   */
+  checkValidity = function ()
+    {
+      $('.error').removeClass('error');
+      ok=true;
+      $("#iamm_randompicture_selectedCat").categorySelector('isValid', true);
+
+      if($("#iamm_randompicture_selectedMode").inputRadio('value')=='c' &&
+         $("#iamm_randompicture_selectedCat").categorySelector('value').length==0
+        )
+      {
+        ok=false;
+        $("#iamm_randompicture_selectedCat").categorySelector('isValid', false);
+      }
+
+      return(ok);
+    },
+
+  /**
+   * display or hide the processing flower
+   */
+  displayProcessing = function (visible)
+    {
+      if(visible)
+      {
+        $('#iBDProcessing').css("display", "block");
+      }
+      else
+      {
+        $('#iBDProcessing').css("display", "none");
+      }
+    },
+
+  /**
+   * initialize the object and page form
+   */
+  init = function (initValues)
+  {
+    $('#iamm_randompicture_selectedMode').inputRadio(
+      {
+        change:function () { $('#iConfigState').hide(); }
+      }
+    );
+    $('#iamm_randompicture_selectedMode').inputRadio('value', initValues.selectMode);
+
+    $('#iamm_randompicture_selectedCat').categorySelector(
+      {
+        serverUrl:'plugins/GrumPluginClasses/gpc_ajax.php',
+        listMaxWidth:650,
+        listMaxHeight:550,
+        userMode:'public',
+        galleryRoot:false,
+        displayStatus:false,
+        filter:'all',
+        multiple:true,
+        load:
+          function (event)
+          {
+            $(this)
+              .categorySelector('collapse', ':all')
+              .categorySelector('value', initValues.selectCat);
+          },
+        change: function () { $('#iConfigState').hide(); }
+      }
+    );
+
+    $('#iamm_randompicture_showname').inputList(
+      {
+        colsWidth:[300],
+        popupMode:'mouseout',
+        change: function () { $('#iConfigState').hide(); }
+      }
+    ).inputList('value', initValues.infosName);
+    $('#iamm_randompicture_showcomment').inputList(
+      {
+        colsWidth:[300],
+        popupMode:'mouseout',
+        change: function () { $('#iConfigState').hide(); }
+      }
+    ).inputList('value', initValues.infosComment);
+
+
+    $('#islang').inputList(
+      {
+        popupMode:'mouseout',
+        change: function () { $('#iConfigState').hide(); }
+      }
+    );
+
+    $('#iamm_randompicture_title').inputText(
+      {
+        languages:initValues.langs,
+        languagesValues:initValues.blockTitles,
+        currentLanguage:initValues.userLang,
+        languageSelector:'islang',
+        displayChar:50,
+        maxChar:255,
+        change: function () { $('#iConfigState').hide(); }
+      }
+    );
+
+    $('#islang').inputList('value', initValues.userLang);
+
+
+
+    formatDelay(initValues.freqDelay);
+    $("#iamm_rp_pc_slider").slider(
+      {
+        min:0,
+        max:60000,
+        step:50,
+        value:initValues.freqDelay,
+        slide: function(event, ui) { formatDelay(ui.value); },
+        change: function () { $('#iConfigState').hide(); }
+      });
+    $("#iamm_rp_pc_slider a").addClass('gcBgInput');
+
+    formatHeight(initValues.blockHeight);
+    $("#iamm_rp_height_slider").slider(
+      {
+        min:99,
+        max:300,
+        steps:1,
+        value:initValues.blockHeight,
+        slide: function(event, ui) { formatHeight(ui.value); },
+        change: function () { $('#iConfigState').hide(); }
+      });
+    $("#iamm_rp_height_slider a").addClass('gcBgInput');
+  },
+
+  /**
+   * format delay value for display
+   */
+  formatDelay = function(delay)
+  {
+    $("#iamm_randompicture_periodicchange").val(delay);
+    if(delay==0)
+    {
+      $("#iamm_rp_pc_display").html(translatedKeys.g002_setting_randompic_periodicchange_deactivated);
+    }
+    else
+    {
+      $("#iamm_rp_pc_display").html((delay/1000).toFixed(2)+"s");
+    }
+  },
+
+  formatHeight = function(height)
+  {
+    var vheight = (height==99)?0:height;
+
+    $("#iamm_randompicture_height").val(vheight);
+    if(vheight==0)
+    {
+      $("#iamm_rp_height_display").html(translatedKeys.g002_setting_randompic_height_auto);
+    }
+    else
+    {
+      $("#iamm_rp_height_display").html(vheight+"px");
+    }
+  };
+
+
+  $.extend(options, opt);
+  $.extend(translatedKeys, keys);
+
+  this.submit = function () { submit(); };
+
+  init(initValues);
+}
+
+
Index: /extensions/AMenuManager/js/amm_randomPictConfig.min.js
===================================================================
--- /extensions/AMenuManager/js/amm_randomPictConfig.min.js	(revision 8962)
+++ /extensions/AMenuManager/js/amm_randomPictConfig.min.js	(revision 8962)
@@ -0,0 +1,27 @@
+/* file: amm_randomPictConfig.js - v1.0.0 | minified on 2011/01/28 with http://jscompress.com/ */
+function randomPictConfig(opt,keys,token,initValues)
+{var options={ajaxUrl:'plugins/AMenuManager/amm_ajax.php'},translatedKeys={g002_setting_randompic_periodicchange_deactivated:'g002_setting_randompic_periodicchange_deactivated',g002_setting_randompic_height_auto:'g002_setting_randompic_height_auto'},properties={token:token},submit=function()
+{if(!checkValidity())return(false);displayProcessing(true);var datas={blockTitles:[],blockHeight:$("#iamm_rp_height_slider").slider('option','value'),infosName:$("#iamm_randompicture_showname").inputList('value'),infosComment:$("#iamm_randompicture_showcomment").inputList('value'),freqDelay:$("#iamm_rp_pc_slider").slider('option','value')==99?0:$("#iamm_rp_pc_slider").slider('option','value'),selectMode:$("#iamm_randompicture_selectedMode").inputRadio('value'),selectCat:$("#iamm_randompicture_selectedCat").categorySelector('value')};list=$('#iamm_randompicture_title').inputText('languagesValues');for(var id in list)
+{datas.blockTitles.push({id:id,value:list[id]});}
+$.ajax({type:"POST",url:options.ajaxUrl,async:true,data:{ajaxfct:"admin.randomPict.setConfig",token:properties.token,datas:datas},success:function(msg)
+{displayProcessing(false);returned=msg.split('!');if(returned[0]=='OK')
+{$('#iConfigState').html(returned[1]).removeClass('errors').addClass('infos').css('display','block');}
+else
+{$('#iConfigState').html(returned[1]).removeClass('infos').addClass('errors').css('display','block');}}});},checkValidity=function()
+{$('.error').removeClass('error');ok=true;$("#iamm_randompicture_selectedCat").categorySelector('isValid',true);if($("#iamm_randompicture_selectedMode").inputRadio('value')=='c'&&$("#iamm_randompicture_selectedCat").categorySelector('value').length==0)
+{ok=false;$("#iamm_randompicture_selectedCat").categorySelector('isValid',false);}
+return(ok);},displayProcessing=function(visible)
+{if(visible)
+{$('#iBDProcessing').css("display","block");}
+else
+{$('#iBDProcessing').css("display","none");}},init=function(initValues)
+{$('#iamm_randompicture_selectedMode').inputRadio({change:function(){$('#iConfigState').hide();}});$('#iamm_randompicture_selectedMode').inputRadio('value',initValues.selectMode);$('#iamm_randompicture_selectedCat').categorySelector({serverUrl:'plugins/GrumPluginClasses/gpc_ajax.php',listMaxWidth:650,listMaxHeight:550,userMode:'public',galleryRoot:false,displayStatus:false,filter:'all',multiple:true,load:function(event)
+{$(this).categorySelector('collapse',':all').categorySelector('value',initValues.selectCat);},change:function(){$('#iConfigState').hide();}});$('#iamm_randompicture_showname').inputList({colsWidth:[300],popupMode:'mouseout',change:function(){$('#iConfigState').hide();}}).inputList('value',initValues.infosName);$('#iamm_randompicture_showcomment').inputList({colsWidth:[300],popupMode:'mouseout',change:function(){$('#iConfigState').hide();}}).inputList('value',initValues.infosComment);$('#islang').inputList({popupMode:'mouseout',change:function(){$('#iConfigState').hide();}});$('#iamm_randompicture_title').inputText({languages:initValues.langs,languagesValues:initValues.blockTitles,currentLanguage:initValues.userLang,languageSelector:'islang',displayChar:50,maxChar:255,change:function(){$('#iConfigState').hide();}});$('#islang').inputList('value',initValues.userLang);formatDelay(initValues.freqDelay);$("#iamm_rp_pc_slider").slider({min:0,max:60000,step:50,value:initValues.freqDelay,slide:function(event,ui){formatDelay(ui.value);},change:function(){$('#iConfigState').hide();}});$("#iamm_rp_pc_slider a").addClass('gcBgInput');formatHeight(initValues.blockHeight);$("#iamm_rp_height_slider").slider({min:99,max:300,steps:1,value:initValues.blockHeight,slide:function(event,ui){formatHeight(ui.value);},change:function(){$('#iConfigState').hide();}});$("#iamm_rp_height_slider a").addClass('gcBgInput');},formatDelay=function(delay)
+{$("#iamm_randompicture_periodicchange").val(delay);if(delay==0)
+{$("#iamm_rp_pc_display").html(translatedKeys.g002_setting_randompic_periodicchange_deactivated);}
+else
+{$("#iamm_rp_pc_display").html((delay/1000).toFixed(2)+"s");}},formatHeight=function(height)
+{var vheight=(height==99)?0:height;$("#iamm_randompicture_height").val(vheight);if(vheight==0)
+{$("#iamm_rp_height_display").html(translatedKeys.g002_setting_randompic_height_auto);}
+else
+{$("#iamm_rp_height_display").html(vheight+"px");}};$.extend(options,opt);$.extend(translatedKeys,keys);this.submit=function(){submit();};init(initValues);}
Index: /extensions/AMenuManager/js/amm_randomPictPublic.js
===================================================================
--- /extensions/AMenuManager/js/amm_randomPictPublic.js	(revision 8962)
+++ /extensions/AMenuManager/js/amm_randomPictPublic.js	(revision 8962)
@@ -0,0 +1,110 @@
+/**
+ * randomPict
+ *
+ * release 1.0.0
+ */
+function randomPict(opt)
+{
+  var options={
+          fixedHeight:0,
+          pictures:[],
+          showName:'n',
+          showComment:'n',
+          delay:0
+        },
+      properties={
+          vIntervalID:0,
+          vCurrentPict:0,
+          nameDOM:'',
+          commentDOM:'',
+          img:new Image()
+        },
+
+  init = function (opt)
+  {
+    $.extend(options, opt);
+
+    switch(options.showName)
+    {
+      case 'o':
+        properties.nameDOM='iammRPicNameO';
+        break;
+      case 'u':
+        properties.nameDOM='iammRPicNameU';
+        break;
+    }
+    switch(options.showComment)
+    {
+      case 'o':
+        properties.commentDOM='iammRPicCommentO';
+        break;
+      case 'u':
+        properties.commentDOM='iammRPicCommentU';
+        break;
+    }
+
+    if(properties.nameDOM!='') $('#'+properties.nameDOM).css('display', 'block');
+    if(properties.commentDOM!='') $('#'+properties.commentDOM).css('display', 'block');
+
+    if(options.delay>0) properties.vIntervalID = window.setInterval(getNextPicture, options.delay);
+
+    if(options.fixedHeight>0) $('#irandompicinner').css('height', options.fixedHeight+'px');
+
+    preloadImages();
+  },
+
+  preloadImages = function ()
+  {
+    $(properties.img).bind('load',
+      function ()
+      {
+        properties.vCurrentPict++;
+        if(properties.vCurrentPict>=options.pictures.length)
+        {
+          properties.vCurrentPict=-1;
+          getNextPicture();
+        }
+        else
+        {
+          properties.img.src=options.pictures[properties.vCurrentPict].thumb;
+        }
+      }
+    );
+    properties.img.src=options.pictures[properties.vCurrentPict].thumb;
+  },
+
+  computePositionTop = function()
+  {
+    $("#iamm_ill0").css({top:(options.fixedHeight-$("#iamm_ill0").innerHeight())/2});
+  },
+
+  getNextPicture = function()
+  {
+    properties.vCurrentPict++;
+    if(properties.vCurrentPict>=options.pictures.length) properties.vCurrentPict=0;
+
+    $('#iamm_ill0').fadeTo(200, 0,
+      function ()
+      {
+        if(properties.nameDOM!='') $('#'+properties.nameDOM).html(options.pictures[properties.vCurrentPict].name);
+        if(properties.commentDOM!='') $('#'+properties.commentDOM).html(options.pictures[properties.vCurrentPict].comment);
+
+        $('#iammRPicLink').attr('href', options.pictures[properties.vCurrentPict].link);
+        $('#iammRPicImg').attr('src', options.pictures[properties.vCurrentPict].thumb);
+        computePositionTop();
+        $('#iamm_ill0').fadeTo(200, 1);
+      }
+    );
+
+  };
+
+  init(opt);
+}
+
+
+$(document).ready(
+  function ()
+  {
+    var rPict=new randomPict(randomPictOpt);
+  }
+);
Index: /extensions/AMenuManager/js/amm_randomPictPublic.min.js
===================================================================
--- /extensions/AMenuManager/js/amm_randomPictPublic.min.js	(revision 8962)
+++ /extensions/AMenuManager/js/amm_randomPictPublic.min.js	(revision 8962)
@@ -0,0 +1,18 @@
+/* file: amm_randomPictPublic.js - v1.0.0 | minified on 2011/01/28 with http://jscompress.com/ */
+function randomPict(opt)
+{var options={fixedHeight:0,pictures:[],showName:'n',showComment:'n',delay:0},properties={vIntervalID:0,vCurrentPict:0,nameDOM:'',commentDOM:'',img:new Image()},init=function(opt)
+{$.extend(options,opt);switch(options.showName)
+{case'o':properties.nameDOM='iammRPicNameO';break;case'u':properties.nameDOM='iammRPicNameU';break;}
+switch(options.showComment)
+{case'o':properties.commentDOM='iammRPicCommentO';break;case'u':properties.commentDOM='iammRPicCommentU';break;}
+if(properties.nameDOM!='')$('#'+properties.nameDOM).css('display','block');if(properties.commentDOM!='')$('#'+properties.commentDOM).css('display','block');if(options.delay>0)properties.vIntervalID=window.setInterval(getNextPicture,options.delay);if(options.fixedHeight>0)$('#irandompicinner').css('height',options.fixedHeight+'px');preloadImages();},preloadImages=function()
+{$(properties.img).bind('load',function()
+{properties.vCurrentPict++;if(properties.vCurrentPict>=options.pictures.length)
+{properties.vCurrentPict=-1;getNextPicture();}
+else
+{properties.img.src=options.pictures[properties.vCurrentPict].thumb;}});properties.img.src=options.pictures[properties.vCurrentPict].thumb;},computePositionTop=function()
+{$("#iamm_ill0").css({top:(options.fixedHeight-$("#iamm_ill0").innerHeight())/2});},getNextPicture=function()
+{properties.vCurrentPict++;if(properties.vCurrentPict>=options.pictures.length)properties.vCurrentPict=0;$('#iamm_ill0').fadeTo(200,0,function()
+{if(properties.nameDOM!='')$('#'+properties.nameDOM).html(options.pictures[properties.vCurrentPict].name);if(properties.commentDOM!='')$('#'+properties.commentDOM).html(options.pictures[properties.vCurrentPict].comment);$('#iammRPicLink').attr('href',options.pictures[properties.vCurrentPict].link);$('#iammRPicImg').attr('src',options.pictures[properties.vCurrentPict].thumb);computePositionTop();$('#iamm_ill0').fadeTo(200,1);});};init(opt);}
+$(document).ready(function()
+{var rPict=new randomPict(randomPictOpt);});
Index: /extensions/AMenuManager/language/en_UK/plugin.lang.php
===================================================================
--- /extensions/AMenuManager/language/en_UK/plugin.lang.php	(revision 8961)
+++ /extensions/AMenuManager/language/en_UK/plugin.lang.php	(revision 8962)
@@ -47,5 +47,5 @@
 $lang['g002_apply'] = 'Apply';
 
-$lang['g002_sectionslist'] = 'Menu blocks';
+$lang['g002_sectionslist'] = 'Menu\'s blocks';
 
 $lang['g002_yesno_y'] = 'Yes';
@@ -60,11 +60,11 @@
 $lang['g002_configrandompic'] = 'Random picture settings';
 $lang['g002_setting_randompic_aboutpicture'] = 'Displayed datas';
-$lang['g002_setting_randompic_showname'] = 'Show picture name';
-$lang['g002_setting_randompic_showcomment'] = 'Show picture comment';
+$lang['g002_setting_randompic_showname'] = 'Show picture\'s name';
+$lang['g002_setting_randompic_showcomment'] = 'Show picure\'s comment';
 $lang['g002_show_n'] = 'No';
-$lang['g002_show_o'] = 'Display above the picture';
-$lang['g002_show_u'] = 'Display under the picture';
+$lang['g002_show_o'] = 'Display over the picture';
+$lang['g002_show_u'] = 'Display under thpicture';
 
-$lang['g002_personalisedlist'] = "List of personalized blocks";
+$lang['g002_personalisedlist'] = "Liste of personalised blocks";
 $lang['g002_notitle'] = '[No title]';
 $lang['g002_title'] = 'Title';
@@ -75,6 +75,6 @@
 $lang['g002_createofpersonalised'] = 'Create a new personalized block';
 $lang['g002_editofpersonalised'] = 'Modify a personalized block';
-$lang['g002_setting_block_langchoice'] = 'Language choice';
-$lang['g002_setting_personalised_content'] = 'Block content';
+$lang['g002_setting_block_langchoice'] = 'Lang choice';
+$lang['g002_setting_personalised_content'] = 'Block\'s content';
 $lang['g002_setting_personalised_properties'] = 'Properties';
 $lang['g002_setting_personalised_nfo'] = 'Description';
@@ -84,5 +84,5 @@
 $lang['g002_modmenu'] = '\'menu\' block';
 $lang['g002_modspecial'] = '\'special\' block';
-$lang['g002_labelmenu'] = 'Menu label';
+$lang['g002_labelmenu'] = 'Menu\'s label';
 
 $lang['g002_setting_randompic_periodicchange'] = "Periodic change of the image";
@@ -100,3 +100,24 @@
 $lang['g002_click_to_manage_rights'] = "Rights management";
 
+
+// v3.0.0
+$lang['g002_ok'] = "OK";
+$lang['g002_config_saved'] = "Config saved";
+$lang['g002_config_not_saved'] = "Config was not saved";
+$lang['g002_selected_all_gallery'] = "All albums";
+$lang['g002_selected_favorites_wm'] = "Webmaster's favorites pictures";
+$lang['g002_selected_categories'] = "All selected albums";
+$lang['g002_loading'] = "Loading...";
+$lang['g002_valid_order'] = "Apply order";
+$lang['g002_reset_order'] = "Reset order";
+$lang['g002_accessibility'] = "Accessibility";
+$lang['g002_setting_core_blocks_content'] = "Content for 'Menu' & 'Specials' menus";
+$lang['g002_setting_blocks_position'] = "Visibility & ordering for menus ";
+$lang['g002_plugin'] = "Plugin";
+$lang['g002_selectedpict'] = "Selected pictures";
+$lang['g002_album_nfo'] = 'Allow to convert one or more album into a menu';
+$lang['g002_album2menu'] = "Converted album to menu";
+$lang['g002_album'] = "Album &rArr; menu";
+$lang['g002_setting_albums_menus'] = "Albums to convert to menu";
+
 ?>
Index: /extensions/AMenuManager/language/fr_FR/plugin.lang.php
===================================================================
--- /extensions/AMenuManager/language/fr_FR/plugin.lang.php	(revision 8961)
+++ /extensions/AMenuManager/language/fr_FR/plugin.lang.php	(revision 8962)
@@ -13,8 +13,8 @@
 $lang['g002_personnalblock'] = 'Menu personnalisé';
 
-$lang['g002_setmenu_nfo'] = 'Gestion de l\'affichage des sections affichées dans le menu';
-$lang['g002_addlinks_nfo'] = 'Section permettant d\'afficher dans le menu une liste d\'hyperliens vers d\'autres sites internet';
-$lang['g002_randompict_nfo'] = 'Section permettant d\'afficher dans le menu une image prise au hasard dans la galerie';
-$lang['g002_personnalblock_nfo'] = 'Afficher dans le menu des sections au contenu personnalisé';
+$lang['g002_setmenu_nfo'] = 'Gestion de l\'affichage des blocs du menu';
+$lang['g002_addlinks_nfo'] = 'Bloc permettant d\'afficher dans le menu une liste d\'hyperliens pointant vers d\'autres sites';
+$lang['g002_randompict_nfo'] = 'Bloc permettant d\'afficher dans le menu une image prise au hasard dans la galerie';
+$lang['g002_personnalblock_nfo'] = 'Afficher dans le menu des blocs au contenu personnalisé';
 
 
@@ -43,9 +43,9 @@
 
 $lang['g002_setting_block_menu'] = 'Intégration dans le menu';
-$lang['g002_setting_block_active'] = 'Afficher la section dans le menu';
-$lang['g002_setting_block_title'] = 'Titre de la section dans le menu';
+$lang['g002_setting_block_active'] = 'Afficher le block dans le menu';
+$lang['g002_setting_block_title'] = 'Titre du block dans le menu';
 $lang['g002_apply'] = 'Appliquer';
 
-$lang['g002_sectionslist'] = 'Sections du menu';
+$lang['g002_sectionslist'] = 'Blocks du menu';
 
 $lang['g002_yesno_y'] = 'Oui';
@@ -58,5 +58,4 @@
 $lang['g002_translate'] = 'Traduire avec Google Translate';
 
-$lang['g002_configrandompic'] = 'Configuration de l\'image aléatoire';
 $lang['g002_setting_randompic_aboutpicture'] = 'Données affichées';
 $lang['g002_setting_randompic_showname'] = 'Afficher le nom de la photo';
@@ -66,15 +65,15 @@
 $lang['g002_show_u'] = 'Afficher en-dessous de la photo';
 
-$lang['g002_personalisedlist'] = "Liste des sections personnalisées";
+$lang['g002_personalisedlist'] = "Liste des blocks personnalisés";
 $lang['g002_notitle'] = '[Pas de titre]';
 $lang['g002_title'] = 'Titre';
-$lang['g002_sections'] = 'sections';
-$lang['g002_section'] = 'section';
-$lang['g002_nosections'] = 'Pas de sections';
-$lang['g002_addsection'] = 'Ajouter une section';
-$lang['g002_createofpersonalised'] = 'Ajout d\'une section personnalisée';
-$lang['g002_editofpersonalised'] = 'Modification d\'une section personnalisée';
+$lang['g002_sections'] = 'blocks';
+$lang['g002_section'] = 'block';
+$lang['g002_nosections'] = 'Pas de blocks';
+$lang['g002_addsection'] = 'Ajouter un block';
+$lang['g002_createofpersonalised'] = 'Ajout d\'un block personnalisé';
+$lang['g002_editofpersonalised'] = 'Modification d\'un block personnalisé';
 $lang['g002_setting_block_langchoice'] = 'Choix de la langue';
-$lang['g002_setting_personalised_content'] = 'Contenu de la section';
+$lang['g002_setting_personalised_content'] = 'Contenu du block';
 $lang['g002_setting_personalised_properties'] = 'Propriétés';
 $lang['g002_setting_personalised_nfo'] = 'Description';
@@ -82,6 +81,6 @@
 $lang['g002_all_languages'] = "Toutes langues";
 
-$lang['g002_modspecial'] = 'Section \'speciale\'';
-$lang['g002_modmenu'] = 'Section \'menu\'';
+$lang['g002_modspecial'] = 'Block \'speciale\'';
+$lang['g002_modmenu'] = 'Block \'menu\'';
 $lang['g002_labelmenu'] = 'Libellé du menu';
 
@@ -101,3 +100,29 @@
 
 
+// v3.0.0
+$lang['g002_ok'] = "OK";
+$lang['g002_config_saved'] = "Configuration enregistrée";
+$lang['g002_config_not_saved'] = "La configuration n'a pu être enregistrée";
+$lang['g002_selected_all_gallery'] = "Dans tous les albums";
+$lang['g002_selected_favorites_wm'] = "Les photos favorites du webmaster";
+$lang['g002_selected_categories'] = "Dans les albums sélectionnés";
+$lang['g002_loading'] = "Chargement en cours...";
+$lang['g002_valid_order'] = "Valider les positions";
+$lang['g002_reset_order'] = "Réinitialiser les positions";
+$lang['g002_accessibility'] = "Accessibilité";
+$lang['g002_setting_core_blocks_content'] = "Contenu des menus 'Menu' & 'Spéciales'";
+$lang['g002_setting_blocks_position'] = "Positionnement & visibilité des menus";
+$lang['g002_plugin'] = "Plugin";
+$lang['g002_selectedpict'] = "Sélection";
+$lang['g002_album_nfo'] = 'Permet de convertir un ou plusieurs albums en blocs de menu';
+$lang['g002_album2menu'] = "Conversion album &rArr; menu";
+$lang['g002_album'] = "Album &rArr; menu";
+$lang['g002_setting_albums_menus'] = "Album à convertir en menu";
+
+/* --- removed keys ---
+$lang['g002_configrandompic'] = 'Configuration de l\'image aléatoire';
+
+*/
+
+
 ?>
Index: /extensions/AMenuManager/main.inc.php
===================================================================
--- /extensions/AMenuManager/main.inc.php	(revision 8961)
+++ /extensions/AMenuManager/main.inc.php	(revision 8962)
@@ -2,5 +2,5 @@
 /*
 Plugin Name: Advanced Menu Manager
-Version: 2.2.3
+Version: 3.0.0
 Description: Gestion avancée du menu / Advanced management of menu
 Plugin URI: http://piwigo.org
@@ -23,7 +23,10 @@
 | release | date       |
 | 2.0.0b  | 2008/07/27 | * initial release with own blocks classes
+|         |            |
 | 2.0.0   | 2008/10/23 | * first release for piwigo's blocks classes
+|         |            |
 | 2.1.0   | 2009/07/26 | * add a functionality : random image can be changed
 |         |            |   every x seconds (from 0.5 to 60)
+|         |            |
 |         |            | * bug resolved : random image block is displayed only
 |         |            |   if user have accessibility to more than 0 images
@@ -32,60 +35,109 @@
 |         |            |   (cf. post:107877 on french forum)
 |         |            |   (cf. topic:14374 on french forum)
+|         |            |
 | 2.1.1   | 2009/07/27 | * random picture is preloaded before the first ajax
 |         |            |   call assuming the display of a thumbnail even if
 |         |            |   javascript is disabled on the browser
 |         |            |   (cf. post:116807 on french forum)
+|         |            |
 |         |            | * give the possibility to choose between an automatic
 |         |            |   and a fixed height for the block menu
 |         |            |   (cf. post:116804 on french forum)
+|         |            |
 |         |            | * compatibility with Sylvia theme
 |         |            |   (cf. post:116800 on french forum)
+|         |            |
 | 2.1.2   | 2009/11/16 | * adding new translations
 |         |            |    - es_ES
 |         |            |    - hu_HU (thx to sámli)
+|         |            |
 | 2.1.3   | 2009/11/24 | * mantis: feature 1285
 |         |            |   move the js for "random image" in the the footer
 |         |            |   (having the js inside the <dl> tag was not w3c
 |         |            |   compliant)
+|         |            |
 |         |            | * mantis: feature 1132
 |         |            |   Allowing order management for items in Piwigo's core
 |         |            |   blocks
+|         |            |
 |         |            | * mantis: feature 1133
 |         |            |   Allowing to group content from Piwigo's core blocks
+|         |            |
 |         |            | * mantis: feature 1278
 |         |            |   Allowing to manage access to menu items with a right
 |         |            |   management system
+|         |            |
 |         |            | * mantis: feature 1100
 |         |            |   Random picture : compatibility with theme 'montblanc'
+|         |            |
 | 2.1.4   | 2009/11/29 | * mantis: feature 1299
 |         |            |   Allows to manage access for the 'Admin' users
+|         |            |
 |         |            | * mantis: feature 1298
 |         |            |   Users 'Webmaster' aren't managed
+|         |            |
 |         |            | * mantis: feature 1297
 |         |            |   AMM don't works properly if a block 'menu' or
 |         |            |   'specials' is hidden
+|         |            |
 | 2.1.5   | 2009/12/15 | * mantis: feature 1331
 |         |            |   JS code used to manage the random picture is always
 |         |            |   loaded even if there is no menubar
+|         |            |
 |         |            | * adding new translations
 |         |            |    - zh_CN (thx mzs777)
+|         |            |
 |         |            | * update translations
 |         |            |    - hu_HU (thx to sámli)
+|         |            |
 | 2.1.6   | 2009/12/19 | * mantis: feature 1336
 |         |            |   Error message about an undefined var 'tabsheet' on
 |         |            |   the admin panel
+|         |            |
 | 2.2.0   | 2010/03/28 | * updated for Piwigo 2.1 compatibility
+|         |            |
 |         |            | * mantis: feature 1384
 |         |            |   Problem of length of title field in the custom menu
 |         |            |   module
+|         |            |
 |         |            | * mantis: bug 1476
 |         |            |   Error message on login screen
+|         |            |
 |         |            | * mantis: bug 1541
 |         |            |   Items order is not respected in admin pages
 |         |            |
-| 2.2.3   | 2011/01/20 | * Add languages
+| 3.0.0   | 2011/01/09 | * mantis: feature 1296
+|         |            |   . add permissions for managing personal menu
 |         |            |
+|         |            | * mantis: feature 1477
+|         |            |   . Possibility to pre-select the "random images"
 |         |            |
+|         |            | * mantis: bug 1680
+|         |            |   . Warning if a new lang is added in Piwigo
 |         |            |
+|         |            | * mantis: feature 1709
+|         |            |   . Change title links by sub tabs
+|         |            |
+|         |            | * mantis: feature 1723
+|         |            |   . Display links using user access right
+|         |            |
+|         |            | * mantis: bug 1776
+|         |            |   . Unable to set access for the administrator
+|         |            |
+|         |            | * mantis: bug 1910
+|         |            |   . Incompatibility with Internet Explorer
+|         |            |     (partially fixed : works, but lloks a little bit
+|         |            |      ugly)
+|         |            |
+|         |            | * mantis: feature 2052
+|         |            |   . Convert album to menu
+|         |            |
+|         |            | * mantis: feature 2128
+|         |            |   . Random picture : preload a set of picture
+|         |            |
+|         |            | * mantis: feature 2129
+|         |            |   . User & group access management is not consistent
+|         |            |
+|         |            | * plugin core rewrited
 |         |            |
 |         |            |
Index: /extensions/AMenuManager/maintain.inc.php
===================================================================
--- /extensions/AMenuManager/maintain.inc.php	(revision 8961)
+++ /extensions/AMenuManager/maintain.inc.php	(revision 8962)
@@ -14,19 +14,18 @@
 
 
-global $gpc_installed, $gpcNeeded, $lang; //needed for plugin manager compatibility
+global $gpcInstalled, $lang; //needed for plugin manager compatibility
 
 /* -----------------------------------------------------------------------------
 AMM needs the Grum Plugin Classe
 ----------------------------------------------------------------------------- */
-$gpc_installed=false;
-$gpcNeeded="3.0.0";
+$gpcInstalled=false;
 if(file_exists(PHPWG_PLUGINS_PATH.'GrumPluginClasses/classes/CommonPlugin.class.inc.php'))
 {
   @include_once(PHPWG_PLUGINS_PATH.'GrumPluginClasses/classes/CommonPlugin.class.inc.php');
-  // need GPC release greater or equal than 3.0.0
-  if(CommonPlugin::checkGPCRelease(3,0,0))
+  // need GPC release greater or equal than 3.3.3
+  if(CommonPlugin::checkGPCRelease(3,3,3))
   {
     @include_once("amm_install.class.inc.php");
-    $gpc_installed=true;
+    $gpcInstalled=true;
   }
 }
@@ -34,6 +33,5 @@
 function gpcMsgError(&$errors)
 {
-  global $gpcNeeded;
-  $msg=sprintf(l10n('To install this plugin, you need to install Grum Plugin Classes %s before'), $gpcNeeded);
+  $msg=sprintf(l10n('To install this plugin, you need to install Grum Plugin Classes %s before'), AMM_GPC_NEEDED);
   if(is_array($errors))
   {
@@ -51,14 +49,13 @@
 load_language('plugin.lang', AMM_PATH);
 
+
+
 function plugin_install($plugin_id, $plugin_version, &$errors)
 {
-  global $prefixeTable, $gpc_installed, $gpcNeeded;
-  if($gpc_installed)
+  global $prefixeTable, $gpcInstalled;
+  if($gpcInstalled)
   {
-    //$menu->register('mbAMM_links', 'Links', 0, 'AMM');
-    //$menu->register('mbAMM_randompict', 'Random pictures', 0, 'AMM');
     $amm=new AMM_install($prefixeTable, __FILE__);
     $result=$amm->install();
-    GPCCore::register($amm->getPluginName(), AMM_VERSION, $gpcNeeded);
   }
   else
@@ -70,22 +67,30 @@
 function plugin_activate($plugin_id, $plugin_version, &$errors)
 {
-  global $prefixeTable;
-
-  $amm=new AMM_install($prefixeTable, __FILE__);
-  $result=$amm->activate();
+  global $prefixeTable, $gpcInstalled;
+  if($gpcInstalled)
+  {
+    $amm=new AMM_install($prefixeTable, __FILE__);
+    $result=$amm->activate();
+  }
 }
 
 function plugin_deactivate($plugin_id)
 {
+  global $prefixeTable, $gpcInstalled;
+
+  if($gpcInstalled)
+  {
+    $amm=new AMM_install($prefixeTable, __FILE__);
+    $amm->deactivate();
+  }
 }
 
 function plugin_uninstall($plugin_id)
 {
-  global $prefixeTable, $gpc_installed;
-  if($gpc_installed)
+  global $prefixeTable, $gpcInstalled;
+  if($gpcInstalled)
   {
     $amm=new AMM_install($prefixeTable, __FILE__);
     $result=$amm->uninstall();
-    GPCCore::unregister($amm->getPluginName());
   }
   else
@@ -96,4 +101,3 @@
 
 
-
 ?>
Index: /extensions/AMenuManager/menu_templates/menubar_album.tpl
===================================================================
--- /extensions/AMenuManager/menu_templates/menubar_album.tpl	(revision 8962)
+++ /extensions/AMenuManager/menu_templates/menubar_album.tpl	(revision 8962)
@@ -0,0 +1,37 @@
+<dt>
+  <a href="{$block->data.link}">{$block->data.name}</a>
+</dt>
+
+<dd>
+  {assign var='ref_level' value=0}
+  {foreach from=$block->data.album item=cat}
+    {if $cat.LEVEL > $ref_level}
+    <ul>
+    {else}
+      </li>
+      {'</ul></li>'|@str_repeat:$ref_level-$cat.LEVEL}
+    {/if}
+      <li {if $cat.SELECTED}class="selected"{/if}>
+        <a href="{$cat.URL}" {if $cat.IS_UPPERCAT}rel="up"{/if} title="{$cat.TITLE}">{$cat.NAME}</a>
+        {if $cat.count_images > 0}
+        <span class="{if $cat.nb_images > 0}menuInfoCat{else}menuInfoCatByChild{/if}" title="{$cat.TITLE}">[{$cat.count_images}]</span>
+        {/if}
+        {if !empty($cat.icon_ts)}
+        <img title="{$cat.icon_ts.TITLE}" src="{$ROOT_URL}{$themeconf.icon_dir}/recent{if $cat.icon_ts.IS_CHILD_DATE}_by_child{/if}.png" class="icon" alt="(!)">
+        {/if}
+    {assign var='ref_level' value=$cat.LEVEL}
+  {/foreach}
+  {'</li></ul>'|@str_repeat:$ref_level}
+
+  {if $data.nbPictures!=''}
+    <p class="totalImages">{$pwg->l10n_dec('%d image', '%d images', $block->data.nbPictures)}</p>
+  {/if}
+</dd>
+
+
+
+
+
+
+
+
Index: /extensions/AMenuManager/menu_templates/menubar_links.tpl
===================================================================
--- /extensions/AMenuManager/menu_templates/menubar_links.tpl	(revision 8961)
+++ /extensions/AMenuManager/menu_templates/menubar_links.tpl	(revision 8962)
@@ -1,3 +1,2 @@
-
 <!-- links menu bar -->
 {if $block->get_title() !="" }
Index: /extensions/AMenuManager/menu_templates/menubar_personalised.tpl
===================================================================
--- /extensions/AMenuManager/menu_templates/menubar_personalised.tpl	(revision 8961)
+++ /extensions/AMenuManager/menu_templates/menubar_personalised.tpl	(revision 8962)
@@ -1,3 +1,2 @@
-
 <!-- personalised menu bar -->
 {if $block->get_title() !="" }
Index: /extensions/AMenuManager/menu_templates/menubar_randompic.js.tpl
===================================================================
--- /extensions/AMenuManager/menu_templates/menubar_randompic.js.tpl	(revision 8961)
+++ /extensions/AMenuManager/menu_templates/menubar_randompic.js.tpl	(revision 8962)
@@ -1,73 +1,23 @@
 {literal}
 <script type="text/javascript">
-var fixedHeight = {/literal}{$data.blockHeight}{literal};
-var vIntervalID;
-
-  $(document).ready(
-    function ()
-    {
-      {/literal}
-      {if $data.blockHeight>0}
-        $("#irandompicinner").height(fixedHeight);
-        {literal}$("#iammrpic").load( function () { computePositionTop(); } );{/literal}
-      {else}
-        {literal}
-        $("#iammrpic").load( function () { $("#irandompicinner").animate({height: ($("#iamm_ill0").innerHeight())+"px"}, "normal"); } );
-        {/literal}
-      {/if}
-      {if $data.delay > 0 }
-        vIntervalID = window.setInterval(getRandomPicture, {$data.delay});
-      {/if}
-      {literal}
-    }
-  );
-
-  function computePositionTop()
-  {
-    $("#iamm_ill0").css({top:(fixedHeight-$("#iamm_ill0").innerHeight())/2});
-  }
-
-  function getRandomPicture()
-  {
-    $.get("./index.php", {ajaxfct:"randompic"},
-      function (data)
-      {
-        $("#iamm_ill0").fadeTo('slow', 0, function ()
-        {
-          $("#iamm_ill0").html(data);
-
-          {/literal}
-          {if $data.blockHeight>0}
-            {literal}
-            $("#iammrpic").load( function () {
-              computePositionTop();
-              $("#iamm_ill0").fadeTo('slow', 1);
-            } );
-            {/literal}
-          {else}
-            {literal}
-            $("#iammrpic").load( function () {
-              $("#irandompicinner").animate({height: ($("#iamm_ill0").innerHeight())+"px"}, "normal", function ()
-              {
-                $("#iamm_ill0").fadeTo('slow', 1, function ()
-                {
-                  $("#irandompicinner").animate({height: this.clientHeight+"px"}, "normal");
-                });
-              });
-            } );
-            {/literal}
-          {/if}
-          {literal}
-
-        } );
-      }
-    );
-  }
-
-  {/literal}
-
-  {literal}
-
-
+var randomPictOpt={
+    {/literal}
+      fixedHeight:{$data.blockHeight},
+      delay:{$data.delay},
+      showName:"{$data.showname}",
+      showComment:"{$data.showcomment}",
+      pictures:[
+        {foreach from=$data.pictures item=picture name=items}
+          {ldelim}
+            'comment':"{$picture.comment}",
+            'link':"{$picture.link}",
+            'name':"{$picture.name}",
+            'thumb':"{$picture.thumb}"
+          {rdelim}
+          {if !$smarty.foreach.items.last},{/if}
+        {/foreach}
+      ]
+    {literal}
+    };
 </script>
 {/literal}
Index: /extensions/AMenuManager/menu_templates/menubar_randompic.tpl
===================================================================
--- /extensions/AMenuManager/menu_templates/menubar_randompic.tpl	(revision 8961)
+++ /extensions/AMenuManager/menu_templates/menubar_randompic.tpl	(revision 8962)
@@ -1,12 +1,15 @@
-{known_script id="jquery" src=$ROOT_URL|cat:"themes/default/js/jquery.packed.js"}
-
 <!-- random picture menu bar -->
 <dt>{$block->get_title()}</dt>
-
 
 <dd id="irandompicdd" class="randompicdd">
   <div id="irandompicinner" class="illustration">
     <div class="ammillustrationc">
-      <div id="iamm_ill0" class="ammillustration">{$block->data.firstPicture}</div>
+      <div id="iamm_ill0" class="ammillustration">
+        <span id='iammRPicNameO' style='display:none;'></span>
+        <span id='iammRPicCommentO' style='display:none;'></span>
+        <a id='iammRPicLink' ><img id="iammRPicImg"/></a>
+        <span id='iammRPicNameU' style='display:none;'></span>
+        <span id='iammRPicCommentU' style='display:none;'></span>
+      </div>
     </div>
   </div>
