Index: /extensions/header_manager/admin.php
===================================================================
--- /extensions/header_manager/admin.php	(revision 26297)
+++ /extensions/header_manager/admin.php	(revision 26298)
@@ -1,4 +1,4 @@
 <?php
-if (!defined('HEADER_MANAGER_PATH')) die('Hacking attempt!');
+defined('HEADER_MANAGER_PATH') or die('Hacking attempt!');
 
 global $template, $page;
@@ -31,4 +31,2 @@
 
 $template->assign_var_from_handle('ADMIN_CONTENT', 'header_manager');
-
-?>
Index: /extensions/header_manager/admin/add.php
===================================================================
--- /extensions/header_manager/admin/add.php	(revision 26297)
+++ /extensions/header_manager/admin/add.php	(revision 26298)
@@ -1,4 +1,4 @@
 <?php
-if (!defined('HEADER_MANAGER_PATH')) die('Hacking attempt!');
+defined('HEADER_MANAGER_PATH') or die('Hacking attempt!');
 
 // cancel crop
@@ -15,19 +15,13 @@
   
   $banner = get_banner($_POST['picture_file']);
+  
   $img = new banner_image($banner['PATH']);
-  $crop = hm_get_crop_display(array('width'=>$img->get_width(), 'height'=>$img->get_height()));
-  
   $img->banner_resize(
     $banner['PATH'],
-    $_POST['x'],
-    $_POST['y'], 
-    $_POST['x2'],
-    $_POST['y2'],
-    $crop['display_width'],
-    $crop['display_height']
+    $_POST
     );
   $img->destroy();
   
-  $img = new banner_image($banner['PATH']);
+  $img = new pwg_image($banner['PATH']);
   $img->pwg_resize(
     $banner['THUMB'],
@@ -67,5 +61,5 @@
   if (!pwg_db_num_rows($result))
   {
-    array_push($page['errors'], l10n('Unknown picture id'));
+    $page['errors'][] = l10n('Unknown picture id');
   }
   else
@@ -86,9 +80,9 @@
   if ($file['error'] > 0) 
   {
-    array_push($page['errors'], l10n('Unknown upload error'));
+    $page['errors'][] = l10n('Unknown upload error');
   }
-  else if ( !in_array($file['type'], array('image/jpeg','image/png','image/gif')) )
+  else if (!in_array($file['type'], array('image/jpeg','image/png','image/gif')))
   {
-    array_push($page['errors'], l10n('Incorrect file type,').' '.sprintf(l10n('Allowed file types: %s.'), 'jpg, png, gif'));
+    $page['errors'][] = l10n('Incorrect file type,').' '.l10n('Allowed file types: %s.', 'jpg, png, gif');
   }
   
@@ -117,5 +111,5 @@
   $conf['header_manager']['height'] = intval($_POST['height']);
   conf_update_param('header_manager', serialize($conf['header_manager']));
-    
+
   $picture['banner_src'] = HEADER_MANAGER_DIR . $picture['filename'];
   
@@ -149,7 +143,6 @@
 }
 
-$template->assign('F_ACTION', HEADER_MANAGER_ADMIN . '-add' .(!empty($_GET['redirect']) ? '&amp;redirect='.urlencode($_GET['redirect']) : ''));
+$template->assign('F_ACTION', HEADER_MANAGER_ADMIN . '-add' .
+  (!empty($_GET['redirect']) ? '&amp;redirect='.urlencode($_GET['redirect']) : ''));
 
-$template->set_filename('header_manager', dirname(__FILE__).'/template/add.tpl');
-
-?>
+$template->set_filename('header_manager', realpath(HEADER_MANAGER_PATH . 'admin/template/add.tpl'));
Index: /extensions/header_manager/admin/album.php
===================================================================
--- /extensions/header_manager/admin/album.php	(revision 26297)
+++ /extensions/header_manager/admin/album.php	(revision 26298)
@@ -1,26 +1,4 @@
 <?php
-// +-----------------------------------------------------------------------+
-// | Piwigo - a PHP based photo gallery                                    |
-// +-----------------------------------------------------------------------+
-// | Copyright(C) 2008-2012 Piwigo Team                  http://piwigo.org |
-// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
-// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
-// +-----------------------------------------------------------------------+
-// | This program is free software; you can redistribute it and/or modify  |
-// | it under the terms of the GNU General Public License as published by  |
-// | the Free Software Foundation                                          |
-// |                                                                       |
-// | This program is distributed in the hope that it will be useful, but   |
-// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
-// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
-// | General Public License for more details.                              |
-// |                                                                       |
-// | You should have received a copy of the GNU General Public License     |
-// | along with this program; if not, write to the Free Software           |
-// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
-// | USA.                                                                  |
-// +-----------------------------------------------------------------------+
-
-if(!defined("PHPWG_ROOT_PATH")) die ("Hacking attempt!");
+defined('HEADER_MANAGER_PATH') or die ("Hacking attempt!");
 
 // +-----------------------------------------------------------------------+
@@ -47,4 +25,7 @@
 }
 
+$cat_id = $_GET['cat_id'];
+
+
 // +-----------------------------------------------------------------------+
 // | Tabs                                                                  |
@@ -60,7 +41,4 @@
 
 
-$cat_id = $_GET['cat_id'];
-
-
 // +-----------------------------------------------------------------------+
 // | Save Form                                                             |
@@ -68,5 +46,5 @@
 if (isset($_POST['save_banner']))
 {
-  if ( !isset($_POST['image']) or $_POST['image'] == 'default')
+  if (!isset($_POST['image']) or $_POST['image'] == 'default')
   {
     $query = '
@@ -136,5 +114,3 @@
 ));
 
-$template->set_filename('header_manager', dirname(__FILE__).'/template/album.tpl');
-
-?>
+$template->set_filename('header_manager', realpath(HEADER_MANAGER_PATH . 'admin/template/album.tpl'));
Index: /extensions/header_manager/admin/config.php
===================================================================
--- /extensions/header_manager/admin/config.php	(revision 26297)
+++ /extensions/header_manager/admin/config.php	(revision 26298)
@@ -1,7 +1,7 @@
 <?php
-if (!defined('HEADER_MANAGER_PATH')) die('Hacking attempt!');
+defined('HEADER_MANAGER_PATH') or die('Hacking attempt!');
 
 // change banner to last uploaded
-if ( pwg_get_session_var('added_banner')!==null and $conf['header_manager']['image']!='random' )
+if (pwg_get_session_var('added_banner')!==null and $conf['header_manager']['image']!='random')
 {
   $conf['header_manager']['image'] = pwg_get_session_var('added_banner');
@@ -29,5 +29,5 @@
   conf_update_param('header_manager', serialize($conf['header_manager']));
   
-  array_push($page['infos'], l10n('Information data registered in database'));
+  $page['infos'][] = l10n('Information data registered in database');
 }
 
@@ -37,5 +37,5 @@
 {
   $banner = get_banner($_GET['delete_banner']);
-  if ( $banner !== false or @unlink($banner['PATH']) )
+  if ($banner !== false or @unlink($banner['PATH']))
   {
     @unlink($banner['THUMB']);
@@ -53,9 +53,9 @@
     pwg_query($query);
     
-    array_push($page['infos'], l10n('Banner deleted'));
+    $page['infos'][] = l10n('Banner deleted');
   }
   else
   {
-    array_push($page['warnings'], l10n('File/directory read error').' : ' . HEADER_MANAGER_DIR . $_GET['delete_banner']);
+    $page['warnings'][] = l10n('File/directory read error').' : ' . HEADER_MANAGER_DIR . $_GET['delete_banner'];
   }
 }
@@ -63,9 +63,9 @@
 if (isset($_GET['delete_cat_banner']))
 {
-    $query = '
+  $query = '
 DELETE FROM '.HEADER_MANAGER_TABLE.'
   WHERE category_id = "'.$_GET['delete_cat_banner'].'"
 ;';
-    pwg_query($query);
+  pwg_query($query);
 }
 
@@ -85,5 +85,5 @@
   ORDER BY global_rank ASC
 ;';
-$categories = hash_from_query($query, 'id');
+$categories = query2array($query, 'id');
 
 foreach ($categories as $category)
@@ -91,9 +91,9 @@
   $tpl_cat =
     array(
-      'NAME'        => get_cat_display_name_from_id($category['id'], HEADER_MANAGER_ADMIN.'-album&amp;cat_id='),
-      'ID'          => $category['id'],
-      'IMAGE'       => get_filename_wo_extension($category['image']),
-      'DEEP'        => $category['deep'],
-      'U_DELETE'    => HEADER_MANAGER_ADMIN.'-config&amp;delete_cat_banner='.$category['id'],
+      'NAME'     => get_cat_display_name_from_id($category['id'], HEADER_MANAGER_ADMIN.'-album&amp;cat_id='),
+      'ID'       => $category['id'],
+      'IMAGE'    => get_filename_wo_extension($category['image']),
+      'DEEP'     => $category['deep'],
+      'U_DELETE' => HEADER_MANAGER_ADMIN.'-config&amp;delete_cat_banner='.$category['id'],
     );
   
@@ -103,5 +103,5 @@
 
 // config template
-if ( empty($conf['header_manager']['image']) or get_banner($conf['header_manager']['image']) === false )
+if (empty($conf['header_manager']['image']) or get_banner($conf['header_manager']['image']) === false)
 {
   $conf['header_manager']['image'] = 'random';
@@ -116,5 +116,3 @@
   ));
 
-$template->set_filename('header_manager', dirname(__FILE__).'/template/config.tpl');
-
-?>
+$template->set_filename('header_manager', realpath(HEADER_MANAGER_PATH . 'admin/template/config.tpl'));
Index: /extensions/header_manager/admin/template/add.tpl
===================================================================
--- /extensions/header_manager/admin/template/add.tpl	(revision 26297)
+++ /extensions/header_manager/admin/template/add.tpl	(revision 26298)
@@ -1,3 +1,3 @@
-{combine_css path=$HEADER_MANAGER_PATH|@cat:"admin/template/style.css"}
+{combine_css path=$HEADER_MANAGER_PATH|cat:'admin/template/style.css'}
 
 <div class="titrePage">
@@ -10,42 +10,55 @@
 
 {footer_script require="jquery"}
-var jcrop_api;
+(function(){
+  var jcrop_api;
 
-jQuery("#jcrop").Jcrop({ldelim}
-    boxWidth: {$crop.display_width}, 
-    boxHeight: {$crop.display_height},
+  jQuery("#jcrop").Jcrop({
+    boxWidth: {$crop.box_width}, 
+    boxHeight: {$crop.box_height},
+    trueSize: [{$picture.width}, {$picture.height}],
+    aspectRatio: {$crop.real_width}/{$crop.real_height},
     setSelect: [{$crop.l}, {$crop.t}, {$crop.r}, {$crop.b}],
-    onChange: jOnChange,
-    onRelease: jOnRelease
-	},
-  function(){ldelim}
+    onChange: function(sel) {
+      jQuery("input[name='x']").val(Math.round(sel.x));
+      jQuery("input[name='y']").val(Math.round(sel.y));
+      jQuery("input[name='x2']").val(Math.round(sel.x2));
+      jQuery("input[name='y2']").val(Math.round(sel.y2));
+      
+      var final_width = Math.min(Math.round(sel.x2-sel.x), {$crop.desired_width}),
+          final_height = Math.round((sel.y2-sel.y)*final_width/(sel.x2-sel.x));
+      
+      jQuery("#width").html(final_width);
+      jQuery("#height").html(final_height);
+    },
+    onRelease: function() {
+      jcrop_api.setSelect([{$crop.l}, {$crop.t}, {$crop.r}, {$crop.b}]);
+    }
+  },
+  function() {
     jcrop_api = this;
   });
   
-function jOnChange(sel) {ldelim}
-	jQuery("input[name='x']").val(sel.x);
-	jQuery("input[name='y']").val(sel.y);
-	jQuery("input[name='x2']").val(sel.x2);
-	jQuery("input[name='y2']").val(sel.y2);
-  
-  jQuery("#width").html(sel.x2-sel.x);
-  jQuery("#height").html(sel.y2-sel.y);
-}
-  
-function jOnRelease() {ldelim}
-	jcrop_api.setSelect([{$crop.l}, {$crop.t}, {$crop.r}, {$crop.b}]);
-}
+  jQuery('input[name="keep_ratio"]').on('change', function() {
+    jcrop_api.setOptions({
+      aspectRatio: jQuery(this).prop('checked') ? {$crop.real_width}/{$crop.real_height} : 0
+    });
+    if (!jQuery(this).prop('checked')) {
+      jcrop_api.release();
+    }
+  });
+}());
 {/footer_script}
 
 <form method="post" action="{$F_ACTION}">
 <fieldset>
-  <legend>{'Crop banner image'|@translate}</legend>
-  {'Choose the part of the image you want to use as your header.'|@translate}<br>
+  <legend>{'Crop banner image'|translate}</legend>
+  {'Choose the part of the image you want to use as your header.'|translate}<br>
   
-  <img id="jcrop" src="{$picture.banner_src}" width="{$crop.display_width}" height="{$crop.display_height}">
+  <img id="jcrop" src="{$picture.banner_src}">
   
   <ul>
-    <li><b>{'Width'|@translate}:</b> <span id="width"></span>px</li>
-    <li><b>{'Height'|@translate}:</b> <span id="height"></span>px</li>
+    <li><b>{'Width'|translate}:</b> <span id="width"></span>px</li>
+    <li><b>{'Height'|translate}:</b> <span id="height"></span>px</li>
+    <li><label><input type="checkbox" name="keep_ratio" checked> {'Respect %s aspect ratio'|translate:($crop.desired_width|cat:'/'|cat:$crop.desired_height)}</label></li>
   </ul>
   
@@ -56,11 +69,11 @@
   <input type="hidden" name="picture_file" value="{$picture.filename}">
   
-  <input type="submit" name="submit_crop" value="{'Submit'|@translate}">
-  <input type="submit" name="cancel_crop" value="{'Cancel'|@translate}">
+  <input type="submit" name="submit_crop" value="{'Submit'|translate}">
+  <input type="submit" name="cancel_crop" value="{'Cancel'|translate}">
 </fieldset>
 </form>
 
 {else}
-{footer_script require="jquery"}{literal}
+{footer_script require="jquery"}
 jQuery(".showInfo").tipTip({
   delay: 0,
@@ -75,16 +88,17 @@
     $("input[name='upload_gallery_image']").click();
     return false;
-  } else {
+  }
+  else {
     return true;
   }
 });
-{/literal}{/footer_script}
+{/footer_script}
 
 <form method="post" action="{$F_ACTION}" ENCTYPE="multipart/form-data">
   <fieldset>
-    <legend>{'Default banner size'|@translate}</legend>
+    <legend>{'Default banner size'|translate}</legend>
     
     <label>
-      {'Width'|@translate}:
+      {'Width'|translate}:
       <input type="text" name="width" size="4" value="{$BANNER_WIDTH}"> px
     </label>
@@ -92,30 +106,30 @@
     <br>
     <label>
-      {'Height'|@translate}:
+      {'Height'|translate}:
       <input type="text" name="height" size="4" value="{$BANNER_HEIGHT}"> px
     </label>
     <br>
     <br>
-    <i>{'For MontBlancXL and BlancMontXL, advised size is 900&times;190.'|@translate}</i>
+    <i>{'For MontBlancXL and BlancMontXL, advised size is 900&times;190.'|translate}</i>
   </fieldset>
   
   <fieldset>
-    <legend>{'Select an image'|@translate}</legend>
-    {'You can upload a custom header image or select one from your gallery. On the next screen you will be able to crop the image.'|@translate}
+    <legend>{'Select an image'|translate}</legend>
+    {'You can upload a custom header image or select one from your gallery. On the next screen you will be able to crop the image.'|translate}
     <br><br>
     
-    <b>{'Choose an image from your computer'|@translate}</b>
+    <b>{'Choose an image from your computer'|translate}</b>
     <blockquote>
-      {'Maximum file size: %sB.'|@translate|@sprintf:$upload_max_filesize_shorthand} {'Allowed file types: %s.'|@translate|@sprintf:'jpg, png, gif'}<br>
+      {'Maximum file size: %sB.'|translate:$upload_max_filesize_shorthand} {'Allowed file types: %s.'|translate:'jpg, png, gif'}<br>
       <input type="file" name="new_image">
       <input type="hidden" name="MAX_FILE_SIZE" value="{$upload_max_filesize}">
-      <input type="submit" name="upload_new_image" value="{'Upload'|@translate}" class="submit">
+      <input type="submit" name="upload_new_image" value="{'Upload'|translate}" class="submit">
     </blockquote>
     
-    <b>{'or choose a picture from the gallery'|@translate}</b>
+    <b>{'or choose a picture from the gallery'|translate}</b>
     <blockquote>
-      {'Picture id.'|@translate} <a class="icon-info-circled-1 showInfo" title="{'The numeric identifier can be found on the picture edition page, near the thumbnail.'|@translate}"></a>
+      {'Picture id.'|translate} <a class="icon-info-circled-1 showInfo" title="{'The numeric identifier can be found on the picture edition page, near the thumbnail.'|translate}"></a>
       <input type="text" name="picture_id" size="5">
-      <input type="submit" name="upload_gallery_image" value="{'Use'|@translate}" class="submit">
+      <input type="submit" name="upload_gallery_image" value="{'Use'|translate}" class="submit">
     </blockquote>
   </fieldset>
Index: /extensions/header_manager/admin/template/album.tpl
===================================================================
--- /extensions/header_manager/admin/template/album.tpl	(revision 26297)
+++ /extensions/header_manager/admin/template/album.tpl	(revision 26298)
@@ -1,6 +1,6 @@
-{combine_css path=$HEADER_MANAGER_PATH|@cat:"admin/template/style.css"}
+{combine_css path=$HEADER_MANAGER_PATH|cat:'admin/template/style.css'}
 
 <div class="titrePage">
-  <h2><span style="letter-spacing:0">{$CATEGORIES_NAV}</span> &#8250; {'Edit album'|@translate} [{'Banner'|@translate}]</h2>
+  <h2><span style="letter-spacing:0">{$CATEGORIES_NAV}</span> &#8250; {'Edit album'|translate} [{'Banner'|translate}]</h2>
 </div>
 
@@ -9,5 +9,5 @@
     <div class="banner-radio" style="display:block;">
       <input type="radio" name="image" value="default" id="banner-default"{if $BANNER_IMAGE=='default'}checked="checked"{/if}>
-      <label for="banner-default"><b>{'Default banner'|@translate}</b></label>
+      <label for="banner-default"><b>{'Default banner'|translate}</b></label>
     </div>
     {foreach from=$banners item=image}
@@ -23,16 +23,16 @@
     {/foreach}
   {else}
-    <p style="text-align:left;">{'No banner added yet'|@translate}</p>
+    <p style="text-align:left;">{'No banner added yet'|translate}</p>
   {/if}
   
   <p style="text-align:left;">
-    <a href="{$ADD_IMAGE_URL}&redirect={$F_ACTION|urlencode}">{'Add a banner'|@translate}</a>
+    <a href="{$ADD_IMAGE_URL}&redirect={$F_ACTION|urlencode}">{'Add a banner'|translate}</a>
   </p>
     
   {if $banners}
   <p class="actionButtons">
-    <label><input type="checkbox" name="deep" value="1" {if $BANNER_DEEP}checked="checked"{/if}> {'Apply to sub-albums'|@translate}</label>
+    <label><input type="checkbox" name="deep" value="1" {if $BANNER_DEEP}checked="checked"{/if}> {'Apply to sub-albums'|translate}</label>
     <br><br>
-    <input type="submit" name="save_banner" value="{'Submit'|@translate}" class="submit">
+    <input type="submit" name="save_banner" value="{'Submit'|translate}" class="submit">
   </p>
   {/if}
Index: /extensions/header_manager/admin/template/config.tpl
===================================================================
--- /extensions/header_manager/admin/template/config.tpl	(revision 26297)
+++ /extensions/header_manager/admin/template/config.tpl	(revision 26298)
@@ -1,5 +1,5 @@
-{combine_css path=$HEADER_MANAGER_PATH|@cat:"admin/template/style.css"}
+{combine_css path=$HEADER_MANAGER_PATH|cat:'admin/template/style.css'}
 
-{footer_script require="jquery"}{literal}
+{footer_script require="jquery"}
 jQuery("input[name='display']").change(function() {
   jQuery(".display-help:not(#"+ jQuery(this).val() +")").slideUp();
@@ -13,5 +13,5 @@
   defaultPosition: 'top'
 });
-{/literal}{/footer_script}
+{/footer_script}
 
 <div class="titrePage">
@@ -21,30 +21,30 @@
 <form method="post" action="{$CONFIG_URL}" class="properties">
   <fieldset>
-    <legend>{'Display'|@translate}</legend>
+    <legend>{'Display'|translate}</legend>
     
-    <label><input type="radio" name="display" value="image_only" {if $BANNER_DISPLAY=='image_only'}checked="checked"{/if}> {'Image only'|@translate}</label><br>
+    <label><input type="radio" name="display" value="image_only" {if $BANNER_DISPLAY=='image_only'}checked="checked"{/if}> {'Image only'|translate}</label><br>
     
-    <label><input type="radio" name="display" value="with_title" {if $BANNER_DISPLAY=='with_title'}checked="checked"{/if}> {'Gallery title above image'|@translate}</label><br>
+    <label><input type="radio" name="display" value="with_title" {if $BANNER_DISPLAY=='with_title'}checked="checked"{/if}> {'Gallery title above image'|translate}</label><br>
     <div class="display-help" id="with_title" {if $BANNER_DISPLAY!='with_title'}style="display:none;"{/if}>
-      <i>{'You can customize the display by adding CSS rules to'|@translate}</i>
+      <i>{'You can customize the display by adding CSS rules to'|translate}</i>
       <span style="font-family:monospace;font-size:14px;color:#000;background:#eee;padding:0 2px;">#<span style="color:#09f;font-weight:bold;">theHeader</span> <span style="color:#00f;">div</span>.<span style="color:#f00;">banner</span></span>
     </div>
     
-    <label><input type="radio" name="display" value="with_text" {if $BANNER_DISPLAY=='with_text'}checked="checked"{/if}> {'With text'|@translate}</label><br>
+    <label><input type="radio" name="display" value="with_text" {if $BANNER_DISPLAY=='with_text'}checked="checked"{/if}> {'With text'|translate}</label><br>
     <div class="display-help" id="with_text" {if $BANNER_DISPLAY!='with_text'}style="display:none;"{/if}>
       <textarea rows="5" cols="50" class="description" name="conf_page_banner">{$CONF_PAGE_BANNER}</textarea><br>
-      <i>{'Put <b>%header_manager%</b> where you want to display the image.'|@translate}</i>
+      <i>{'Put <b>%header_manager%</b> where you want to display the image.'|translate}</i>
     </div>
     
-    <label><input style="margin-top:20px;" type="checkbox" name="banner_on_picture" value="true" {if $BANNER_ON_PICTURE}checked="checked"{/if}> <b>{'Display banner on photo page'|@translate}</b></label>
+    <label><input style="margin-top:20px;" type="checkbox" name="banner_on_picture" value="true" {if $BANNER_ON_PICTURE}checked="checked"{/if}> <b>{'Display banner on photo page'|translate}</b></label>
   </fieldset>
   
   <fieldset id="batchManagerGlobal">
-    <legend>{'Banner'|@translate}</legend>
+    <legend>{'Banner'|translate}</legend>
     
   {if $banners}
     <div class="banner-radio" style="display:block;">
       <input type="radio" name="image" value="random" id="banner-random" {if $BANNER_IMAGE=='random'}checked="checked"{/if}>
-      <label for="banner-random"><b>{'Random'|@translate}</b></label>
+      <label for="banner-random"><b>{'Random'|translate}</b></label>
     </div>
     {foreach from=$banners item=image key=name}
@@ -54,5 +54,5 @@
       </span>
       <span class="banner-wrapper">
-        <a href="{$CONFIG_URL}&amp;delete_banner={$image.NAME}" title="{'Delete'|@translate}" onclick="return confirm('{'Are you sure?'|@translate|@escape:javascript}');" class="delete-banner">&times;</a>
+        <a href="{$CONFIG_URL}&amp;delete_banner={$image.NAME}" title="{'Delete'|translate}" onclick="return confirm('{'Are you sure?'|translate|@escape:javascript}');" class="delete-banner">&times;</a>
         <span class="banner-size">{$image.SIZE[0]} &times; {$image.SIZE[1]} px</span>
         <label for="banner-{$image.NAME}" title="{$name}"><img src="{$image.THUMB}" alt="{$image.NAME}"></label>
@@ -61,16 +61,16 @@
     {/foreach}
   {else}
-    {'No banner added yet'|@translate}
+    {'No banner added yet'|translate}
   {/if}
     
     <br><br>
-    <a href="{$ADD_IMAGE_URL}">{'Add a banner'|@translate}</a>
+    <a href="{$ADD_IMAGE_URL}">{'Add a banner'|translate}</a>
   </fieldset>
 
-  <p class="formButtons"><input type="submit" name="save_config" value="{'Submit'|@translate}" class="submit"></p>
+  <p class="formButtons"><input type="submit" name="save_config" value="{'Submit'|translate}" class="submit"></p>
   
   <fieldset>
-    <legend>{'Album specific banners'|@translate}</legend>
-    <i>{'In order to add a specific banner, go to the admin page of the desired album.'|@translate}</i>
+    <legend>{'Album specific banners'|translate}</legend>
+    <i>{'In order to add a specific banner, go to the admin page of the desired album.'|translate}</i>
     
   {if $categories}
@@ -80,5 +80,5 @@
         {$cat.NAME}
         <a class="showImage" title="<img src='{$banners[$cat.IMAGE].THUMB}'>"><img src="{$HEADER_MANAGER_PATH}admin/template/image_{$cat.DEEP}.png"></a>
-        <a href="{$cat.U_DELETE}" title="{'Restore default banner'|@translate}" onclick="return confirm('{'Are you sure?'|@translate|@escape:javascript}');"><img src="{$themeconf.admin_icon_dir}/delete.png"></a>
+        <a href="{$cat.U_DELETE}" title="{'Restore default banner'|translate}" onclick="return confirm('{'Are you sure?'|translate|@escape:javascript}');"><img src="{$themeconf.admin_icon_dir}/delete.png"></a>
       </li>
     {/foreach}
@@ -86,6 +86,6 @@
     
     <p>
-      <img src="{$HEADER_MANAGER_PATH}admin/template/image_0.png"> : {'Non recursive'|@translate} &bull; 
-      <img src="{$HEADER_MANAGER_PATH}admin/template/image_1.png"> : {'Recursive'|@translate}
+      <img src="{$HEADER_MANAGER_PATH}admin/template/image_0.png"> : {'Non recursive'|translate} &bull; 
+      <img src="{$HEADER_MANAGER_PATH}admin/template/image_1.png"> : {'Recursive'|translate}
     </p>
   {/if}
Index: /extensions/header_manager/include/banner.class.php
===================================================================
--- /extensions/header_manager/include/banner.class.php	(revision 26297)
+++ /extensions/header_manager/include/banner.class.php	(revision 26298)
@@ -1,4 +1,4 @@
 <?php
-if (!defined('HEADER_MANAGER_PATH')) die('Hacking attempt!');
+defined('HEADER_MANAGER_PATH') or die('Hacking attempt!');
 
 include_once(PHPWG_ROOT_PATH . 'admin/include/image.class.php');
@@ -9,5 +9,5 @@
 class banner_image extends pwg_image
 {
-  function banner_resize($destination_filepath, $x, $y, $x2, $y2, $width, $height)
+  function banner_resize($destination_filepath, $selection)
   {
     global $conf;
@@ -18,21 +18,17 @@
     $source_height = $this->image->get_height();
 
-    $resize_dimensions = array(
-      'width' => $width,
-      'height'=> $height,
-      'crop' => array(
-        'width' => $x2-$x,
-        'height' => $y2-$y,
-        'x' => $x,
-        'y' => $y,
-        ),
+    $crop = array(
+      'width' => $selection['x2']-$selection['x'],
+      'height' => $selection['y2']-$selection['y'],
+      'x' => $selection['x'],
+      'y' => $selection['y'],
       );
     
-    // maybe resizing/croping is useless ?
-    if ( $resize_dimensions['crop']['width'] == $source_width and $resize_dimensions['crop']['height'] == $source_height )
+    // maybe resizing/cropping is useless ?
+    if ($conf['header_manager']['width'] == $source_width and $conf['header_manager']['height'] == $source_height)
     {
       // the image doesn't need any resize! We just copy it to the destination
       copy($this->source_filepath, $destination_filepath);
-      return $this->get_resize_result($destination_filepath, $resize_dimensions['width'], $resize_dimensions['height'], $starttime);
+      return $this->get_resize_result($destination_filepath, $source_width, $source_height, $starttime);
     }
     
@@ -40,12 +36,12 @@
     $this->image->strip();
     
+    // crop
+    $this->image->crop($crop['width'], $crop['height'], $crop['x'], $crop['y']);
+    
     // resize to what is displayed on crop screen
-    if ($source_width > $conf['header_manager']['width'])
+    if ($crop['width'] > $conf['header_manager']['width'])
     {
-      $this->image->resize($resize_dimensions['width'], $source_height*$resize_dimensions['width']/$source_width);
+      $this->image->resize($conf['header_manager']['width'], $crop['height']*$conf['header_manager']['width']/$crop['width']);
     }
-    
-    // crop
-    $this->image->crop($resize_dimensions['crop']['width'], $resize_dimensions['crop']['height'], $resize_dimensions['crop']['x'], $resize_dimensions['crop']['y']);
     
     // save
@@ -53,5 +49,5 @@
 
     // everything should be OK if we are here!
-    return $this->get_resize_result($destination_filepath, $resize_dimensions['crop']['width'], $resize_dimensions['crop']['height'], $starttime);
+    return $this->get_resize_result($destination_filepath, $crop['width'], $crop['height'], $starttime);
   }
   
@@ -69,4 +65,2 @@
   }
 }
-
-?>
Index: /extensions/header_manager/include/functions.inc.php
===================================================================
--- /extensions/header_manager/include/functions.inc.php	(revision 26297)
+++ /extensions/header_manager/include/functions.inc.php	(revision 26298)
@@ -8,5 +8,9 @@
 function list_banners($delete_orphans=false)
 { 
-  if (!file_exists(HEADER_MANAGER_DIR)) return array();
+  if (!file_exists(HEADER_MANAGER_DIR))
+  {
+    return array();
+  }
+  
   $dir = scandir(HEADER_MANAGER_DIR);
   $banners = array();
@@ -14,11 +18,11 @@
   foreach ($dir as $file)
   {
-    if ( in_array($file, array('.','..','index.php','.svn')) ) continue;
-    if ( !in_array(strtolower(get_extension($file)), array('jpg','jpeg','png','gif')) ) continue;
-    if ( strpos($file, '-thumbnail')!==false ) continue;
+    if (in_array($file, array('.','..','index.php','.svn'))) continue;
+    if (!in_array(strtolower(get_extension($file)), array('jpg','jpeg','png','gif'))) continue;
+    if (strpos($file, '-thumbnail')!==false) continue;
     
     $banner = get_banner($file);
 
-    if ( $delete_orphans and !file_exists($banner['THUMB']) )
+    if ($delete_orphans and !file_exists($banner['THUMB']))
     {
       @unlink($banner['PATH']);
@@ -43,6 +47,6 @@
     return array(
       'NAME' => $file,
-      'PATH' => get_root_url().HEADER_MANAGER_DIR . $file,
-      'THUMB' => get_root_url().HEADER_MANAGER_DIR . get_filename_wo_extension($file) . '-thumbnail.'. get_extension($file),
+      'PATH' => get_root_url() . HEADER_MANAGER_DIR . $file,
+      'THUMB' => get_root_url() . HEADER_MANAGER_DIR . get_filename_wo_extension($file) . '-thumbnail.' . get_extension($file),
       'SIZE' => getimagesize(HEADER_MANAGER_DIR . $file),
       );
@@ -85,45 +89,26 @@
   $crop['coi']['y'] = ($picture['coi']['b']+$picture['coi']['t'])/2;
   
-  // define default crop frame
-  if ($picture['width'] > $conf['header_manager']['width'])
+  $crop['desired_width'] = $conf['header_manager']['width'];
+  $crop['desired_height'] = $conf['header_manager']['height'];
+  
+  if ($picture['width'] > $crop['desired_width'])
   {
-    $crop['display_width'] = $conf['header_manager']['width'];
-    $crop['display_height'] = round($picture['height']*$crop['display_width']/$picture['width']);
-    
-    $crop['coi']['x'] = round($crop['coi']['x']*$crop['display_width']/$picture['width']);
-    $crop['coi']['y'] = round($crop['coi']['y']*$crop['display_height']/$picture['height']);
-    
-    $crop['l'] = 0;
-    $crop['r'] = $conf['header_manager']['width'];
-    $crop['t'] = max(0, $crop['coi']['y']-$conf['header_manager']['height']/2);
-    $crop['b'] = min($crop['display_height'], $crop['t']+$conf['header_manager']['height']);
+    $crop['box_width'] = $crop['desired_width'];
+    $crop['box_height'] = round($picture['height']*$crop['box_width']/$picture['width']);
   }
   else
   {
-    $crop['display_width'] = $picture['width'];
-    $crop['display_height'] = $picture['height'];
-    
-    $adapted_crop_height = round($conf['header_manager']['height']*$picture['width']/$conf['header_manager']['width']);
-    
-    $crop['l'] = 0;
-    $crop['r'] = $picture['width'];
-    $crop['t'] = max(0, $crop['coi']['y']-$adapted_crop_height/2);
-    $crop['b'] = min($crop['display_height'], $crop['t']+$adapted_crop_height);
+    $crop['box_width'] = $picture['width'];
+    $crop['box_height'] = $picture['height'];
   }
+  
+  $crop['real_width'] = $picture['width'];
+  $crop['real_height'] = round($crop['desired_height']*$crop['real_width']/$crop['desired_width']);
+  
+  $crop['l'] = 0;
+  $crop['r'] = $crop['real_width'];
+  $crop['t'] = max(0, $crop['coi']['y']-$crop['real_height']/2);
+  $crop['b'] = min($picture['height'], $crop['t']+$crop['real_height']);
   
   return $crop;
 }
-
-/**
- * clean table when categroies are delete
- */
-function header_manager_delete_categories($ids)
-{
-  $query = '
-DELETE FROM '.HEADER_MANAGER_TABLE.'
-  WHERE category_id IN('.implode(',', $ids).')
-;';
-  pwg_query($query);
-}
-
-?>
Index: /extensions/header_manager/include/header_manager.inc.php
===================================================================
--- /extensions/header_manager/include/header_manager.inc.php	(revision 26297)
+++ /extensions/header_manager/include/header_manager.inc.php	(revision 26298)
@@ -1,4 +1,4 @@
 <?php
-if (!defined('HEADER_MANAGER_PATH')) die('Hacking attempt!');
+defined('HEADER_MANAGER_PATH') or die('Hacking attempt!');
 
 /**
@@ -9,7 +9,13 @@
   global $conf, $user, $template, $page;
   
-  if ( script_basename() == 'picture' and !$conf['header_manager']['banner_on_picture'] )
+  if (script_basename() == 'picture' and !$conf['header_manager']['banner_on_picture'])
   {
-    return null;
+    return '';
+  }
+  
+  // no support for Kardon (not enough space)
+  if ($user['theme'] == 'kardon')
+  {
+    return $page_banner;
   }
   
@@ -48,8 +54,11 @@
   if (!isset($banner))
   {
-    if ( empty($conf['header_manager']['image']) or $conf['header_manager']['image'] == 'random')
+    if (empty($conf['header_manager']['image']) or $conf['header_manager']['image'] == 'random')
     {
       $banners = array_values(list_banners());
-      if (!count($banners)) return $page_banner;
+      if (!count($banners))
+      {
+        return $page_banner;
+      }
       $banner = $banners[ mt_rand(0, count($banners)-1) ];
     }
@@ -57,36 +66,34 @@
     {
       $banner = get_banner($conf['header_manager']['image']);
-      if ($banner === false) return $page_banner;
+      if ($banner === false)
+      {
+        return $page_banner;
+      }
     }
   }
   
   // for MontBlancXL and BlancMontXL the banner is displayed as background of the header
-  if ( in_array($user['theme'], array('blancmontxl','montblancxl')) )
+  if (in_array($user['theme'], array('blancmontxl','montblancxl')))
   {
-    $template->append('head_elements',
-'<style type="text/css">
-#theHeader { background: transparent url('.$banner['PATH'].') center bottom no-repeat; }
-</style>'
+    $template->block_html_style(null,
+      '#theHeader { background: transparent url('.$banner['PATH'].') center bottom no-repeat; }'
       );
 
     if ($conf['header_manager']['display'] == 'image_only')
     {
-      $page_banner = null;
+      $page_banner = '';
     }
     else
     {
-      $page_banner = str_replace('%header_manager%', null, $page_banner);
+      $page_banner = str_replace('%header_manager%', '', $page_banner);
     }
   }
-  // no support for Kardon (not enough space)
-  else if ($user['theme'] != 'kardon')
+  else
   {
-    $template->append('head_elements',
-'<style type="text/css">
-#theHeader div.banner { background:transparent url(\''.$banner['PATH'].'\') center center no-repeat;height:'.$banner['SIZE'][1].'px;line-height:'.($banner['SIZE'][1]-12).'px;font-size:2.5em;color:#fff;text-shadow:0 0 5px #000;text-align:center; }
-</style>'
+    $template->block_html_style(null,
+      '#theHeader div.banner { background:transparent url(\''.$banner['PATH'].'\') center center no-repeat; height:'. ($banner['SIZE'][1]) .'px; line-height:'. ($banner['SIZE'][1]-12) .'px; font-size:2.5em; color:#fff; text-shadow:0 0 5px #000; text-align:center; }'
       );
     
-    $banner_img = '<div class="banner">'.($conf['header_manager']['display']=='with_title' ? $conf['gallery_title'] : '&nbsp;').'</div>';
+    $banner_img = '<div class="banner">'. ($conf['header_manager']['display']=='with_title' ? $conf['gallery_title'] : '&nbsp;') .'</div>';
     
     if ($conf['header_manager']['display'] == 'with_text')
@@ -96,5 +103,5 @@
     else
     {
-      $page_banner = '<a href="'.get_gallery_home_url().'">'.$banner_img.'</a>';
+      $page_banner = '<a href="'. get_gallery_home_url() .'">'. $banner_img .'</a>';
     }
   }
@@ -109,4 +116,2 @@
   return array_search($a['category_id'], $ids) < array_search($b['category_id'], $ids);
 }
-
-?>
Index: tensions/header_manager/include/install.inc.php
===================================================================
--- /extensions/header_manager/include/install.inc.php	(revision 26297)
+++ 	(revision )
@@ -1,51 +1,0 @@
-<?php
-if (!defined('PHPWG_ROOT_PATH')) die('Hacking attempt!');
-  
-function header_manager_install() 
-{
-  global $conf, $prefixeTable;
-
-  // configuration
-  if (empty($conf['header_manager']))
-  {
-    $header_manager_default_config = serialize(array(
-      'width' => 1000,
-      'height' => 150,
-      'image' => 'random',
-      'display' => 'image_only',
-      'banner_on_picture' => true,
-      ));
-    
-    conf_update_param('header_manager', $header_manager_default_config);
-    $conf['header_manager'] = $header_manager_default_config;
-  }
-  else
-  {
-    $new_conf = is_string($conf['header_manager']) ? unserialize($conf['header_manager']) : $conf['header_manager'];
-    if (!isset($new_conf['banner_on_picture']))
-    {
-      $new_conf['banner_on_picture'] = true;
-      $conf['header_manager'] = serialize($new_conf);
-      conf_update_param('header_manager', $conf['header_manager']);
-    }
-  }
-
-  // banners directory
-  if (!file_exists(PHPWG_ROOT_PATH . PWG_LOCAL_DIR . 'banners/')) 
-  {
-    mkdir(PHPWG_ROOT_PATH . PWG_LOCAL_DIR . 'banners/', 0755);
-  }
-
-  // banners table
-  $query = '
-CREATE TABLE IF NOT EXISTS `' .$prefixeTable . 'category_banner` (
-  `category_id` smallint(5) unsigned NOT NULL,
-  `image` varchar(255) NOT NULL,
-  `deep` tinyint(1) DEFAULT 1,
-  PRIMARY KEY (`category_id`)
-) ENGINE=MyISAM DEFAULT CHARSET=utf8
-;';
-  pwg_query($query);
-}
-
-?>
Index: /extensions/header_manager/main.inc.php
===================================================================
--- /extensions/header_manager/main.inc.php	(revision 26297)
+++ /extensions/header_manager/main.inc.php	(revision 26298)
@@ -9,5 +9,5 @@
 */
 
-if (!defined('PHPWG_ROOT_PATH')) die('Hacking attempt!');
+defined('PHPWG_ROOT_PATH') or die('Hacking attempt!');
 
 global $prefixeTable;
@@ -37,5 +37,5 @@
 
 /**
- * update plugin & unserialize conf
+ * initialization
  */
 function header_manager_init()
@@ -43,29 +43,7 @@
   global $conf, $pwg_loaded_plugins, $page;
   
-  if (
-    HEADER_MANAGER_VERSION == 'auto' or
-    $pwg_loaded_plugins['header_manager']['version'] == 'auto' or
-    version_compare($pwg_loaded_plugins['header_manager']['version'], HEADER_MANAGER_VERSION, '<')
-  )
-  {
-    include_once(HEADER_MANAGER_PATH . 'include/install.inc.php');
-    header_manager_install();
-    
-    if ( $pwg_loaded_plugins['header_manager']['version'] != 'auto' and HEADER_MANAGER_VERSION != 'auto' )
-    {
-      $query = '
-UPDATE '. PLUGINS_TABLE .'
-SET version = "'. HEADER_MANAGER_VERSION .'"
-WHERE id = "header_manager"';
-      pwg_query($query);
-      
-      $pwg_loaded_plugins['header_manager']['version'] = HEADER_MANAGER_VERSION;
-      
-      if (defined('IN_ADMIN'))
-      {
-        $_SESSION['page_infos'][] = 'Header Manager updated to version '. HEADER_MANAGER_VERSION;
-      }
-    }
-  }
+  include_once(HEADER_MANAGER_PATH . 'maintain.inc.php');
+  $maintain = new header_manager_maintain('header_manager');
+  $maintain->autoUpdate(HEADER_MANAGER_VERSION, 'install');
   
   $conf['header_manager'] = unserialize($conf['header_manager']);
@@ -77,8 +55,8 @@
 function header_manager_admin_menu($menu) 
 {
-  array_push($menu, array(
+  $menu[] = array(
     'NAME' => 'Header Manager',
     'URL' => HEADER_MANAGER_ADMIN,
-  ));
+    );
   return $menu;
 }
@@ -102,3 +80,13 @@
 }
 
-?>
+/**
+ * clean table when categories are deleted
+ */
+function header_manager_delete_categories($ids)
+{
+  $query = '
+DELETE FROM '.HEADER_MANAGER_TABLE.'
+  WHERE category_id IN('.implode(',', $ids).')
+;';
+  pwg_query($query);
+}
Index: /extensions/header_manager/maintain.inc.php
===================================================================
--- /extensions/header_manager/maintain.inc.php	(revision 26297)
+++ /extensions/header_manager/maintain.inc.php	(revision 26298)
@@ -1,29 +1,77 @@
 <?php
-if (!defined('PHPWG_ROOT_PATH')) die('Hacking attempt!');
+defined('PHPWG_ROOT_PATH') or die('Hacking attempt!');
 
-include_once(PHPWG_PLUGINS_PATH . 'header_manager/include/install.inc.php');
+class header_manager_maintain extends PluginMaintain
+{
+  private $installed = false;
   
-function plugin_install() 
-{
-  header_manager_install();
-  
-  define('header_manager_installed', true);
-}
+  private $default_conf = array(
+      'width' => 1000,
+      'height' => 150,
+      'image' => 'random',
+      'display' => 'image_only',
+      'banner_on_picture' => true,
+    );
 
-function plugin_activate()
-{
-  if (!defined('header_manager_installed'))
+  function install($plugin_version, &$errors=array())
   {
-    header_manager_install();
+    global $conf, $prefixeTable;
+
+    // configuration
+    if (empty($conf['header_manager']))
+    {
+      $conf['header_manager'] = serialize($this->default_conf);
+      conf_update_param('header_manager', $conf['header_manager']);
+    }
+    else
+    {
+      $new_conf = is_string($conf['header_manager']) ? unserialize($conf['header_manager']) : $conf['header_manager'];
+      if (!isset($new_conf['banner_on_picture']))
+      {
+        $new_conf['banner_on_picture'] = true;
+        $conf['header_manager'] = serialize($new_conf);
+        conf_update_param('header_manager', $conf['header_manager']);
+      }
+    }
+
+    // banners directory
+    if (!file_exists(PHPWG_ROOT_PATH . PWG_LOCAL_DIR . 'banners')) 
+    {
+      mkdir(PHPWG_ROOT_PATH . PWG_LOCAL_DIR . 'banners', 0755);
+    }
+
+    // banners table
+    $query = '
+CREATE TABLE IF NOT EXISTS `' .$prefixeTable . 'category_banner` (
+  `category_id` smallint(5) unsigned NOT NULL,
+  `image` varchar(255) NOT NULL,
+  `deep` tinyint(1) DEFAULT 1,
+  PRIMARY KEY (`category_id`)
+) ENGINE=MyISAM DEFAULT CHARSET=utf8
+;';
+    pwg_query($query);
+
+    $this->installed = true;
+  }
+
+  function activate($plugin_version, &$errors=array())
+  {
+    if (!$this->installed)
+    {
+      $this->install($plugin_version, $errors);
+    }
+  }
+
+  function deactivate()
+  {
+  }
+
+  function uninstall()
+  {
+    global $prefixeTable;
+
+    conf_delete_param('header_manager');
+
+    pwg_query('DROP TABLE `' .$prefixeTable . 'category_banner`;');
   }
 }
-
-function plugin_uninstall() 
-{
-  global $prefixeTable;
-  
-  pwg_query('DROP TABLE `' .$prefixeTable . 'category_banner`;');
-  pwg_query('DELETE FROM `'. CONFIG_TABLE .'` WHERE param = "header_manager" LIMIT 1;');
-}
-
-?>
