Index: extensions/ASearchEngine/admin/ase_admin.tpl
===================================================================
--- extensions/ASearchEngine/admin/ase_admin.tpl	(revision 7196)
+++ extensions/ASearchEngine/admin/ase_admin.tpl	(revision 7196)
@@ -0,0 +1,3 @@
+<h2 style="float:right;top:-24px;position:relative;height:auto;font-size:12px;font-weight:normal;">{$plugin.ASE_VERSION}</h2>
+
+{$ASE_BODY_PAGE}
Index: extensions/ASearchEngine/admin/ase_search.tpl
===================================================================
--- extensions/ASearchEngine/admin/ase_search.tpl	(revision 7196)
+++ extensions/ASearchEngine/admin/ase_search.tpl	(revision 7196)
@@ -0,0 +1,4 @@
+
+<h2>{'ase_search_with_multiple_criteria'|@translate}</h2>
+
+{$ase_search_page}
Index: extensions/ASearchEngine/admin/index.php
===================================================================
--- extensions/ASearchEngine/admin/index.php	(revision 7196)
+++ extensions/ASearchEngine/admin/index.php	(revision 7196)
@@ -0,0 +1,33 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | PhpWebGallery - a PHP based picture gallery                           |
+// | Copyright (C) 2002-2003 Pierrick LE GALL - pierrick@phpwebgallery.net |
+// | Copyright (C) 2003-2007 PhpWebGallery Team - http://phpwebgallery.net |
+// +-----------------------------------------------------------------------+
+// | file          : $Id: index.php 1912 2007-03-16 06:30:07Z rub $
+// | last update   : $Date: 2007-03-16 07:30:07 +0100 (ven, 16 mar 2007) $
+// | last modifier : $Author: rub $
+// | revision      : $Revision: 1912 $
+// +-----------------------------------------------------------------------+
+// | 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.                                                                  |
+// +-----------------------------------------------------------------------+
+
+// Recursive call
+$url = '../';
+header( 'Request-URI: '.$url );
+header( 'Content-Location: '.$url );
+header( 'Location: '.$url );
+exit();
+?>
Index: extensions/ASearchEngine/admin/plugin_admin.php
===================================================================
--- extensions/ASearchEngine/admin/plugin_admin.php	(revision 7196)
+++ extensions/ASearchEngine/admin/plugin_admin.php	(revision 7196)
@@ -0,0 +1,28 @@
+<?php
+/* -----------------------------------------------------------------------------
+  Plugin     : Advanced Search Engine
+  Author     : Grum
+    email    : grum@piwigo.org
+    website  : http://photos.grum.fr
+
+    << May the Little SpaceFrog be with you ! >>
+  ------------------------------------------------------------------------------
+  See main.inc.php for release information
+
+  --------------------------------------------------------------------------- */
+
+if (!defined('PHPWG_ROOT_PATH')) { die('Hacking attempt!'); }
+
+include(ASE_PATH."ase_aip.class.inc.php");
+
+global $prefixeTable, $template;
+
+load_language('plugin.lang', ASE_PATH);
+
+$main_plugin_object = get_plugin_data($plugin_id);
+
+
+$plugin_aip = new ASE_AIP($prefixeTable, $main_plugin_object->getFileLocation());
+$plugin_aip->manage();
+
+?>
Index: extensions/ASearchEngine/ase.css
===================================================================
--- extensions/ASearchEngine/ase.css	(revision 7196)
+++ extensions/ASearchEngine/ase.css	(revision 7196)
@@ -0,0 +1,83 @@
+#iHeaderListMaps { width:100%; border:1px solid; border-collapse: collapse; margin-top:3px; }
+#iListMaps, #iListAssoc, #iListKml { width:100%; border:1px solid; height:280px; border-top:0px; overflow:auto; position:relative; left:-1px;}
+#iListMapsNb, #iListAssocNb, #iListKmlNb { width:99%; text-align:right; margin-bottom:8px; padding:2px; font-size:80%; }
+
+#iListMaps table, table.listMaps,
+#iListAssoc table,
+#iListKml table  { width:100%; text-align:left; border-collapse: collapse; }
+
+#iListMaps.roma table tr:hover,
+#iListAssoc.roma table tr:hover,
+#iListKml.roma table tr:hover  { cursor:pointer; background:#303030; }
+
+#iListMaps.clear table tr:hover,
+#iListAssoc.clear table tr:hover,
+#iListKml.clear table tr:hover { cursor:pointer; color: #D54E21; background:#dbe8f3; }
+
+#iBDAssocCatId {
+  width:560px;
+}
+
+div.addMap { text-align:left; }
+
+img.pointer, span.pointer, div.pointer { cursor:pointer; }
+
+.error, input.error {
+  background:#FFAAAA;
+  border:1px solid #800000;
+  color:#800000;
+}
+ul.error {
+  min-height:30px;
+  -moz-border-radius:8px;
+  -webkit-border-radius:8px;
+  -khtml-border-radius:8px;
+  border-radius:8px;
+}
+
+.ui-slider {
+  width:708px;
+  height:10px;
+  border-width:1px;
+  border-style:solid;
+  margin-right:5px;
+  padding-right:14px;
+}
+.ui-slider-handle {
+  width:12px;
+  height:12px;
+  position:relative;
+  top:-2px;
+  border-width:1px;
+  border-style:solid;
+  display:block;
+}
+
+#itab2 {
+  border-top:1px solid;
+  margin:25px -6px 0 -10px;
+  padding-top:3px;
+}
+
+#iDialogGMapNfo {
+  height:18px;
+  margin:5px 5px 0 60px;
+  text-align:left;
+}
+#iDialogGMapNfo span {
+  position:relative;
+  top:-3px;
+  margin-left:3px;
+}
+#iDialogGMapWaiting {
+  position:absolute;
+  z-index:1500;
+  background:#000000;
+  opacity:0.55;
+  filter:alpha(opacity:55);
+}
+
+
+// fix IE8 compatibility bugs from GPC 3.2.0 (fixed in next release)
+.formtable, .formtable P { margin-left:0px;  }
+.tabsheet2 { list-style:none; }
Index: extensions/ASearchEngine/ase2.css
===================================================================
--- extensions/ASearchEngine/ase2.css	(revision 7196)
+++ extensions/ASearchEngine/ase2.css	(revision 7196)
@@ -0,0 +1,1 @@
+
Index: extensions/ASearchEngine/ase_aim.class.inc.php
===================================================================
--- extensions/ASearchEngine/ase_aim.class.inc.php	(revision 7196)
+++ extensions/ASearchEngine/ase_aim.class.inc.php	(revision 7196)
@@ -0,0 +1,43 @@
+<?php
+/* -----------------------------------------------------------------------------
+  Plugin     : Advanced Search Engine
+  Author     : Grum
+    email    : grum@piwigo.org
+    website  : http://photos.grum.dnsalias.com
+
+    << May the Little SpaceFrog be with you ! >>
+  ------------------------------------------------------------------------------
+  See main.inc.php for release information
+
+  ASE_AIM : classe to manage plugin integration into plugin menu
+
+  --------------------------------------------------------------------------- */
+
+if (!defined('PHPWG_ROOT_PATH')) { die('Hacking attempt!'); }
+
+include_once('ase_root.class.inc.php');
+
+class ASE_AIM extends ASE_root
+{
+  public function __construct($prefixeTable, $filelocation)
+  {
+    parent::__construct($prefixeTable, $filelocation);
+  }
+
+  /*
+    initialize events call for the plugin
+  */
+  public function initEvents()
+  {
+    parent::initEvents();
+    add_event_handler('get_admin_plugin_menu_links', array(&$this, 'pluginAdminMenu') );
+  }
+
+  /* ---------------------------------------------------------------------------
+  Function needed for plugin activation
+  --------------------------------------------------------------------------- */
+
+} // ASE_AIM class
+
+
+?>
Index: extensions/ASearchEngine/ase_aip.class.inc.php
===================================================================
--- extensions/ASearchEngine/ase_aip.class.inc.php	(revision 7196)
+++ extensions/ASearchEngine/ase_aip.class.inc.php	(revision 7196)
@@ -0,0 +1,170 @@
+<?php
+/* -----------------------------------------------------------------------------
+  Plugin     : Advanced Search Engine
+  Author     : Grum
+    email    : grum@piwigo.org
+    website  : http://photos.grum.fr
+
+    << May the Little SpaceFrog be with you ! >>
+  ------------------------------------------------------------------------------
+  See main.inc.php for release information
+
+  ASE_AIP : classe to manage plugin admin pages
+
+  --------------------------------------------------------------------------- */
+
+include_once('ase_root.class.inc.php');
+include_once(PHPWG_PLUGINS_PATH.'GrumPluginClasses/classes/GPCTables.class.inc.php');
+include_once(PHPWG_PLUGINS_PATH.'GrumPluginClasses/classes/GPCTabSheet.class.inc.php');
+include_once(PHPWG_PLUGINS_PATH.'GrumPluginClasses/classes/GPCRequestBuilder.class.inc.php');
+include_once(PHPWG_ROOT_PATH.'admin/include/tabsheet.class.php');
+
+class ASE_AIP extends ASE_root
+{
+  protected $tabsheet;
+
+  public function __construct($prefixeTable, $filelocation)
+  {
+    parent::__construct($prefixeTable, $filelocation);
+
+    $this->loadConfig();
+    $this->configForTemplate();
+
+    $this->initRequest();
+    $this->initEvents();
+
+    $this->tabsheet = new tabsheet();
+
+    $this->tabsheet->add('search',
+                          l10n('ase_search'),
+                          $this->getAdminLink()."&amp;fASE_tabsheet=search");
+    $this->tabsheet->add('config',
+                          l10n('ase_config'),
+                          $this->getAdminLink()."&amp;fASE_tabsheet=config");
+  }
+
+  public function __destruct()
+  {
+    unset($this->tabsheet);
+    parent::__destruct();
+  }
+
+  /**
+   * initialize events call for the plugin
+   */
+  public function initEvents()
+  {
+    parent::initEvents();
+
+    if($_REQUEST['fASE_tabsheet']=='search')
+    {
+      // load request builder JS only on the search page
+      GPCRequestBuilder::loadJSandCSS();
+    }
+    add_event_handler('loc_end_page_header', array(&$this->css, 'applyCSS'));
+    GPCCss::applyGpcCss();
+  }
+
+  /**
+   * display the administration page
+   */
+  public function manage()
+  {
+    global $template;
+
+    $this->initRequest();
+
+    $template->set_filename('plugin_admin_content', dirname(__FILE__)."/admin/ase_admin.tpl");
+
+    switch($_REQUEST['fASE_tabsheet'])
+    {
+      case 'search':
+        $this->displaySearch();
+        break;
+      case 'config':
+        $this->displayConfig();
+        break;
+    }
+
+    $this->tabsheet->select($_REQUEST['fASE_tabsheet']);
+    $this->tabsheet->assign();
+    $selected_tab=$this->tabsheet->get_selected();
+    $template->assign($this->tabsheet->get_titlename(), "[".$selected_tab['caption']."]");
+
+    $template_plugin["ASE_VERSION"] = "<i>".$this->getPluginName()."</i> ".l10n('ase_release').ASE_VERSION;
+    $template_plugin["ASE_PAGE"] = $_REQUEST['fASE_tabsheet'];
+    $template_plugin["ASE_TITLE"] = "";
+
+    $template->assign('plugin', $template_plugin);
+
+    $template->assign_var_from_handle('ADMIN_CONTENT', 'plugin_admin_content');
+
+  }
+
+
+
+
+  /**
+   * 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(!isset($_REQUEST['errcode'])) $_REQUEST['errcode']='';
+
+    if(!isset($_REQUEST['fASE_tabsheet']))
+    {
+      $_REQUEST['fASE_tabsheet']="search";
+    }
+
+    if(!($_REQUEST['fASE_tabsheet']!="search" or
+         $_REQUEST['fASE_tabsheet']!="config"
+         )) $_REQUEST['fASE_tabsheet']="search";
+  }
+
+
+
+  /**
+   * display the search page
+   *
+   */
+  protected function displaySearch()
+  {
+    global $template;
+
+    GPCCore::addHeaderCSS('categorySelector', 'plugins/GrumPluginClasses/css/categorySelector_'.$template->get_themeconf('name').'.css');
+
+
+    $template->set_filename('body_page',
+                dirname($this->getFileLocation()).'/admin/ase_search.tpl');
+
+    $template->assign('ase_search_page', GPCRequestBuilder::displaySearchPage());
+
+    $template->assign_var_from_handle('ASE_BODY_PAGE', 'body_page');
+  }
+
+
+  /**
+   * display the config page
+   *
+   */
+  protected function displayConfig()
+  {
+    global $template;
+
+    /*$template->set_filename('body_page',
+                dirname($this->getFileLocation()).'/admin/ase_config.tpl');
+
+
+    $template->assign_var_from_handle('ASE_BODY_PAGE', 'body_page');*/
+  }
+
+
+} //class
+
+
+?>
Index: extensions/ASearchEngine/ase_ajax.php
===================================================================
--- extensions/ASearchEngine/ase_ajax.php	(revision 7196)
+++ extensions/ASearchEngine/ase_ajax.php	(revision 7196)
@@ -0,0 +1,112 @@
+<?php
+/*
+ * -----------------------------------------------------------------------------
+ * Plugin Name: Advanced Search Engine
+ * -----------------------------------------------------------------------------
+ * 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('ase_root.class.inc.php');
+
+  load_language('plugin.lang', ASE_PATH);
+
+
+  class ASE_Ajax extends ASE_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']='';
+
+      // check if asked function is valid
+      if(!($_REQUEST['ajaxfct']=='admin.maps.getList'
+           //$_REQUEST['ajaxfct']=='public.maps.getMarkerInfos'
+           )) $_REQUEST['ajaxfct']='';
+
+      if(preg_match('/^admin\./i', $_REQUEST['ajaxfct']) and !is_admin()) $_REQUEST['ajaxfct']='';
+
+
+      if($_REQUEST['ajaxfct']!='')
+      {
+        /*
+         * no check for admin.maps.getList & admin.assoc.getList requests
+         */
+
+
+      }
+    } //checkRequest
+
+
+    /**
+     * return ajax content
+     */
+    protected function returnAjaxContent()
+    {
+      $result="<p class='errors'>An error has occured</p>";
+      /*
+      switch($_REQUEST['ajaxfct'])
+      {
+        case 'admin.maps.getList':
+          $result=$this->ajax_gmaps_admin_mapsGetList();
+          break;
+      }
+      */
+      GPCAjax::returnResult($result);
+    }
+
+
+    /*------------------------------------------------------------------------*
+     *
+     * ADMIN FUNCTIONS
+     *
+     *----------------------------------------------------------------------- */
+
+
+
+  } //class
+
+
+  $returned=new ASE_Ajax($prefixeTable, __FILE__);
+?>
Index: extensions/ASearchEngine/ase_install.class.inc.php
===================================================================
--- extensions/ASearchEngine/ase_install.class.inc.php	(revision 7196)
+++ extensions/ASearchEngine/ase_install.class.inc.php	(revision 7196)
@@ -0,0 +1,102 @@
+<?php
+/* -----------------------------------------------------------------------------
+  Plugin     : Advanced Search Engine
+  Author     : Grum
+    email    : grum@piwigo.org
+    website  : http://photos.grum.fr
+
+    << May the Little SpaceFrog be with you ! >>
+  ------------------------------------------------------------------------------
+  See main.inc.php for release information
+
+  ASE_Install : classe to manage plugin install
+
+  --------------------------------------------------------------------------- */
+
+   include_once('ase_version.inc.php'); // => Don't forget to update this file !!
+   include_once('ase_root.class.inc.php');
+   include_once(PHPWG_PLUGINS_PATH.'GrumPluginClasses/classes/GPCTables.class.inc.php');
+
+  /* ASE class for install process */
+  class ASE_Install extends ASE_root
+  {
+
+    public function __construct($prefixeTable, $filelocation)
+    {
+      parent::__construct($prefixeTable, $filelocation);
+    }
+
+    public function __destruct()
+    {
+      parent::__destruct();
+    }
+
+    /*
+        function for installation process
+        return true if install process is ok, otherwise false
+    */
+    public function install()
+    {
+      $this->initConfig();
+      $this->loadConfig();
+      $this->config['installed']=ASE_VERSION2;
+      $this->config['newInstall']='y';
+      $this->saveConfig();
+
+      GPCCore::register($this->getPluginName(), ASE_VERSION, ASE_GPC_NEEDED);
+      return(true);
+    }
+
+
+    /*
+        function for uninstall process
+    */
+    public function uninstall()
+    {
+      $this->deleteConfig();
+      GPCCore::unregister($this->getPluginName());
+      return('');
+    }
+
+    public function activate()
+    {
+      $this->initConfig();
+      $this->loadConfig();
+
+      /*
+       * migration code
+       */
+      switch($this->config['installed'])
+      {
+        // actually, there no migration possible from previous release
+        default:
+          // nothing to do...
+          break;
+      }
+
+      $this->config['installed']=ASE_VERSION2;
+      $this->saveConfig();
+
+      GPCCore::register($this->getPluginName(), ASE_VERSION, ASE_GPC_NEEDED);
+      GPCRequestBuilder::register('ASETag', dirname($this->getFileLocation()).'/ase_rb_callback_tag.class.inc.php');
+      GPCRequestBuilder::register('ASEDate', dirname($this->getFileLocation()).'/ase_rb_callback_date.class.inc.php');
+      GPCRequestBuilder::register('ASECategory', dirname($this->getFileLocation()).'/ase_rb_callback_category.class.inc.php');
+      GPCRequestBuilder::register('ASEKeyword', dirname($this->getFileLocation()).'/ase_rb_callback_keyword.class.inc.php');
+      GPCRequestBuilder::register('ASEHD', dirname($this->getFileLocation()).'/ase_rb_callback_hd.class.inc.php');
+      GPCRequestBuilder::register('ASERate', dirname($this->getFileLocation()).'/ase_rb_callback_rate.class.inc.php');
+      return('');
+    }
+
+    public function deactivate()
+    {
+      GPCRequestBuilder::unregister('ASETag');
+      GPCRequestBuilder::unregister('ASEDate');
+      GPCRequestBuilder::unregister('ASECategory');
+      GPCRequestBuilder::unregister('ASEKeyword');
+      GPCRequestBuilder::unregister('ASEHD');
+      GPCRequestBuilder::unregister('ASERate');
+    }
+
+  } //class
+
+?>
Index: extensions/ASearchEngine/ase_pip.class.inc.php
===================================================================
--- extensions/ASearchEngine/ase_pip.class.inc.php	(revision 7196)
+++ extensions/ASearchEngine/ase_pip.class.inc.php	(revision 7196)
@@ -0,0 +1,69 @@
+<?php
+/* -----------------------------------------------------------------------------
+  Plugin     : Advanced Search Engine
+  Author     : Grum
+    email    : grum@piwigo.org
+    website  : http://photos.grum.fr
+
+    << May the Little SpaceFrog be with you ! >>
+  ------------------------------------------------------------------------------
+  See main.inc.php for release information
+
+  ASE_PIP : classe to manage plugin public pages
+
+  --------------------------------------------------------------------------- */
+
+include_once('ase_root.class.inc.php');
+
+class ASE_PIP extends ASE_root
+{
+
+  protected $css2;
+
+  public function __construct($prefixeTable, $filelocation)
+  {
+    parent::__construct($prefixeTable, $filelocation);
+    $this->css2 = new GPCCss(dirname($this->getFileLocation()).'/'.$this->getPluginNameFiles()."2.css");
+    $this->loadConfig();
+    $this->initEvents();
+    $this->load_lang();
+  }
+
+  public function __destruct()
+  {
+    parent::__destruct();
+  }
+
+  /*
+    load language file
+  */
+  public function load_lang()
+  {
+    global $lang;
+
+    load_language('plugin.lang', ASE_PATH);
+  }
+
+  /*
+    initialize events call for the plugin
+  */
+  public function initEvents()
+  {
+    parent::initEvents();
+
+    add_event_handler('loc_end_page_header', array(&$this->css2, 'applyCSS'));
+  }
+
+
+
+  /* -------------------------------------------------------------------------
+    FUNCTIONS TO MANAGE ASE
+  ------------------------------------------------------------------------- */
+
+
+
+
+
+} //class
+
+?>
Index: extensions/ASearchEngine/ase_rb_callback.class.inc.php
===================================================================
--- extensions/ASearchEngine/ase_rb_callback.class.inc.php	(revision 7196)
+++ extensions/ASearchEngine/ase_rb_callback.class.inc.php	(revision 7196)
@@ -0,0 +1,198 @@
+<?php
+/* -----------------------------------------------------------------------------
+  Plugin     : Advanced Search Engine
+  Author     : Grum
+    email    : grum@piwigo.org
+    website  : http://photos.grum.fr
+
+    << May the Little SpaceFrog be with you ! >>
+  ------------------------------------------------------------------------------
+  See main.inc.php for release information
+
+
+  --------------------------------------------------------------------------- */
+
+  if(!defined('PHPWG_ROOT_PATH')) die('Hacking attempt!');
+
+  include_once(PHPWG_PLUGINS_PATH.'GrumPluginClasses/classes/GPCRequestBuilder.class.inc.php');
+
+load_language('plugin.lang', ASE_PATH);
+
+class RBCallBackGMaps extends GPCSearchCallback {
+
+  /**
+   * the getImageId returns the name of the image id attribute
+   * return String
+   */
+  static public function getImageId()
+  {
+    return("pgc.imageId");
+  }
+
+  /**
+   * the getSelect function must return an attribute list separated with a comma
+   *
+   * "att1, att2, att3, att4"
+   */
+  static public function getSelect($param="")
+  {
+    return("pgc.latitude, pgc.longitude");
+  }
+
+  /**
+   * the getFrom function must return a tables list separated with a comma
+   *
+   * "table1, (table2 left join table3 on table2.key = table3.key), table4"
+   */
+  static public function getFrom($param="")
+  {
+    global $prefixeTable;
+
+    return($prefixeTable."gmaps_cache pgc");
+  }
+
+  /**
+   * the getWhere function must return a ready to use where clause
+   *
+   * "(att1 = value0 OR att2 = value1) AND att4 LIKE value2 "
+   */
+  static public function getWhere($param="")
+  {
+    global $user;
+
+    $returned='';
+
+    if($param['bounds']['east']<$param['bounds']['west'])
+    {
+      $returned=" (pgc.longitude <= ".$param['bounds']['east']." OR pgc.longitude >= ".$param['bounds']['west'].") ";
+    }
+    else
+    {
+      $returned=" (pgc.longitude >= ".$param['bounds']['west']." AND pgc.longitude <= ".$param['bounds']['east'].") ";
+    }
+
+    $returned.=" AND pgc.latitude >= ".$param['bounds']['south']."
+                 AND pgc.latitude <= ".$param['bounds']['north']."
+                 AND pgc.userId='".$user['id']."'
+                 AND pgc.requestId='".$param['requestId']."' ";
+
+    return($returned);
+  }
+
+  /**
+   * the getJoin function must return a ready to use where allowing to join the
+   * IMAGES table (key : id) with given conditions
+   *
+   * "att3 = pit.id "
+   */
+  static public function getJoin($param="")
+  {
+    return("pgc.imageId = pit.id");
+  }
+
+
+  /**
+   * the getFilter function must return a ready to use where clause
+   * this where clause is used to filter the cache when the used tables can
+   * return more than one result
+   *
+   * the filter can be empty, can be equal to the where clause, or can be equal
+   * to a sub part of the where clause
+   *
+   */
+  static public function getFilter($param="")
+  {
+    return(self::getWhere($param));
+  }
+
+  /**
+   * this function is called by the request builder, allowing to display plugin
+   * data with a specific format
+   *
+   * @param Array $attributes : array of ('attribute_name' => 'attribute_value')
+   * @return String : HTML formatted value
+   */
+  static public function formatData($attributes)
+  {
+    /* attributes is an array :
+     *    Array(
+     *      'csColors' => 'color1,color2,color3,...,colorN',
+     *      'csColorsPct' => 'pct1,pct2,pct3,...,pctN'
+     *    );
+     */
+    $returned=l10n('gmaps_geolocation')."&nbsp;:&nbsp;";
+
+    if($attributes['latitude']<0)
+    {
+      $returned.=GMaps_functions::DDtoDMS(abs($attributes['latitude'])).'&nbsp;'.l10n('gmaps_south');
+    }
+    else
+    {
+      $returned.=GMaps_functions::DDtoDMS($attributes['latitude']).'&nbsp;'.l10n('gmaps_north');
+    }
+
+    $returned.=', ';
+
+    if($attributes['longitude']<0)
+    {
+      $returned.=GMaps_functions::DDtoDMS(abs($attributes['longitude'])).'&nbsp;'.l10n('gmaps_west');
+    }
+    else
+    {
+      $returned.=GMaps_functions::DDtoDMS($attributes['longitude']).'&nbsp;'.l10n('gmaps_east');
+    }
+
+    return($returned);
+  }
+
+
+
+  /**
+   * this function is called by the request builder to make the search page, and
+   * must return the HTML & JS code of the dialogbox used to select criterion
+   *
+   * Notes :
+   *  - the dialogbox is a JS object with a public method 'show'
+   *  - when the method show is called, one parameter is given by the request
+   *    builder ; the parameter is an object defined as this :
+   *      {
+   *        cBuilder: an instance of the criteriaBuilder object used in the page,
+   *        eventOK : a callback function, called when the OK button is pushed
+   *        id:
+   *      }
+   *
+   *
+   *
+   *
+   * @param String $mode : can take 'admin' or 'public' values, allowing to
+   *                       return different interface if needed
+   * @return String : HTML formatted value
+   */
+  static public function getInterfaceContent($mode='admin')
+  {
+    return(GMaps_functions::dialogBoxGMaps());
+  }
+
+  /**
+   * this function returns the label displayed in the criterion menu
+   *
+   * @return String : label displayed in the criterions menu
+   */
+  static public function getInterfaceLabel()
+  {
+    return(l10n('gmaps_add_geographic_area'));
+  }
+
+  /**
+   * this function returns the name of the dialog box class
+   *
+   * @return String : name of the dialogbox class
+   */
+  static public function getInterfaceDBClass()
+  {
+    return('dialogChooseGMapsBox');
+  }
+
+}
+
+?>
Index: extensions/ASearchEngine/ase_rb_callback_category.class.inc.php
===================================================================
--- extensions/ASearchEngine/ase_rb_callback_category.class.inc.php	(revision 7196)
+++ extensions/ASearchEngine/ase_rb_callback_category.class.inc.php	(revision 7196)
@@ -0,0 +1,171 @@
+<?php
+/* -----------------------------------------------------------------------------
+  Plugin     : Advanced Search Engine
+  Author     : Grum
+    email    : grum@piwigo.org
+    website  : http://photos.grum.fr
+
+    << May the Little SpaceFrog be with you ! >>
+  ------------------------------------------------------------------------------
+  See main.inc.php for release information
+
+
+  --------------------------------------------------------------------------- */
+
+  if(!defined('PHPWG_ROOT_PATH')) die('Hacking attempt!');
+
+  include_once(PHPWG_PLUGINS_PATH.'GrumPluginClasses/classes/GPCRequestBuilder.class.inc.php');
+
+load_language('plugin.lang', ASE_PATH);
+
+class RBCallBackASECategory extends GPCSearchCallback {
+
+  /**
+   * the getImageId returns the name of the image id attribute
+   * return String
+   */
+  static public function getImageId()
+  {
+    return("ase_pict.image_id");
+  }
+
+  /**
+   * the getSelect function must return an attribute list separated with a comma
+   *
+   * "att1, att2, att3, att4"
+   */
+  static public function getSelect($param="")
+  {
+    return(" ase_pct.id AS categoryId, ase_pct.name AS categoryName");
+  }
+
+  /**
+   * the getFrom function must return a tables list separated with a comma
+   *
+   * "table1, (table2 left join table3 on table2.key = table3.key), table4"
+   */
+  static public function getFrom($param="")
+  {
+    global $prefixeTable;
+
+    return("(".IMAGE_CATEGORY_TABLE." ase_pict JOIN ".CATEGORIES_TABLE." ase_pct
+      ON ase_pict.category_id = ase_pct.id) ");
+  }
+
+  /**
+   * the getWhere function must return a ready to use where clause
+   *
+   * "(att1 = value0 OR att2 = value1) AND att4 LIKE value2 "
+   */
+  static public function getWhere($param="")
+  {
+    global $user;
+
+    if($param['subCat']=='y')
+    {
+      foreach($param['catIdList'] as $catId)
+      {
+        $returned.=" OR FIND_IN_SET($catId, ase_pct.uppercats) ";
+      }
+    }
+
+    return($returned);
+  }
+
+  /**
+   * the getJoin function must return a ready to use where allowing to join the
+   * IMAGES table (key : id) with given conditions
+   *
+   * "att3 = pit.id "
+   */
+  static public function getJoin($param="")
+  {
+    return("ase_pict.image_id = pit.id");
+  }
+
+
+  /**
+   * the getFilter function must return a ready to use where clause
+   * this where clause is used to filter the cache when the used tables can
+   * return more than one result
+   *
+   * the filter can be empty, can be equal to the where clause, or can be equal
+   * to a sub part of the where clause
+   *
+   */
+  static public function getFilter($param="")
+  {
+    return(self::getWhere($param));
+  }
+
+  /**
+   * this function is called by the request builder, allowing to display plugin
+   * data with a specific format
+   *
+   * @param Array $attributes : array of ('attribute_name' => 'attribute_value')
+   * @return String : HTML formatted value
+   */
+  static public function formatData($attributes)
+  {
+    /* attributes is an array :
+     *    Array(
+     *      'csColors' => 'color1,color2,color3,...,colorN',
+     *      'csColorsPct' => 'pct1,pct2,pct3,...,pctN'
+     *    );
+     */
+    $returned="<span style='font-weight:bold;'>".l10n('Category')."</span>&nbsp;:&nbsp;".$attributes['categoryName'];
+
+    return($returned);
+  }
+
+
+
+  /**
+   * this function is called by the request builder to make the search page, and
+   * must return the HTML & JS code of the dialogbox used to select criterion
+   *
+   * Notes :
+   *  - the dialogbox is a JS object with a public method 'show'
+   *  - when the method show is called, one parameter is given by the request
+   *    builder ; the parameter is an object defined as this :
+   *      {
+   *        cBuilder: an instance of the criteriaBuilder object used in the page,
+   *        eventOK : a callback function, called when the OK button is pushed
+   *        id:
+   *      }
+   *
+   *
+   *
+   *
+   * @param String $mode : can take 'admin' or 'public' values, allowing to
+   *                       return different interface if needed
+   * @return String : HTML formatted value
+   */
+  static public function getInterfaceContent($mode='admin')
+  {
+    return(ASE_functions::dialogBoxASECategory());
+  }
+
+  /**
+   * this function returns the label displayed in the criterion menu
+   *
+   * @return String : label displayed in the criterions menu
+   */
+  static public function getInterfaceLabel()
+  {
+    return(l10n('ase_add_category'));
+  }
+
+  /**
+   * this function returns the name of the dialog box class
+   *
+   * @return String : name of the dialogbox class
+   */
+  static public function getInterfaceDBClass()
+  {
+    return('dialogChooseASECategoryBox');
+  }
+
+}
+
+?>
Index: extensions/ASearchEngine/ase_rb_callback_date.class.inc.php
===================================================================
--- extensions/ASearchEngine/ase_rb_callback_date.class.inc.php	(revision 7196)
+++ extensions/ASearchEngine/ase_rb_callback_date.class.inc.php	(revision 7196)
@@ -0,0 +1,201 @@
+<?php
+/* -----------------------------------------------------------------------------
+  Plugin     : Advanced Search Engine
+  Author     : Grum
+    email    : grum@piwigo.org
+    website  : http://photos.grum.fr
+
+    << May the Little SpaceFrog be with you ! >>
+  ------------------------------------------------------------------------------
+  See main.inc.php for release information
+
+
+  --------------------------------------------------------------------------- */
+
+  if(!defined('PHPWG_ROOT_PATH')) die('Hacking attempt!');
+
+  include_once(PHPWG_PLUGINS_PATH.'GrumPluginClasses/classes/GPCRequestBuilder.class.inc.php');
+
+load_language('plugin.lang', ASE_PATH);
+
+class RBCallBackASEDate extends GPCSearchCallback {
+
+  /**
+   * the getImageId returns the name of the image id attribute
+   * return String
+   */
+  static public function getImageId()
+  {
+    return("ase_pitd.id");
+  }
+
+  /**
+   * the getSelect function must return an attribute list separated with a comma
+   *
+   * "att1, att2, att3, att4"
+   */
+  static public function getSelect($param="")
+  {
+    if($param['dateType']=='c')
+    {
+      return(" ase_pitd.date_creation AS dateCreation");
+    }
+    else
+    {
+      return(" ase_pitd.date_available AS dateAvailable");
+    }
+  }
+
+  /**
+   * the getFrom function must return a tables list separated with a comma
+   *
+   * "table1, (table2 left join table3 on table2.key = table3.key), table4"
+   */
+  static public function getFrom($param="")
+  {
+    global $prefixeTable;
+
+    return(IMAGES_TABLE." ase_pitd ");
+  }
+
+  /**
+   * the getWhere function must return a ready to use where clause
+   *
+   * "(att1 = value0 OR att2 = value1) AND att4 LIKE value2 "
+   */
+  static public function getWhere($param="")
+  {
+    global $user;
+
+    if($param['dateType']=='c')
+    {
+      $returned=" ase_pitd.date_creation ";
+    }
+    else
+    {
+      $returned=" ase_pitd.date_available ";
+    }
+
+    switch($param['searchType'])
+    {
+      case 'eq':
+        $returned.=" = '".$param['from']."' ";
+        break;
+      case 'bt':
+        $returned.=" BETWEEN '".$param['from']."' AND '".$param['to']."' ";
+        break;
+      case 'gt':
+        $returned.=" >= '".$param['from']."' ";
+        break;
+      case 'lt':
+        $returned.=" <= '".$param['to']."' ";
+        break;
+    }
+
+    return($returned);
+  }
+
+  /**
+   * the getJoin function must return a ready to use where allowing to join the
+   * IMAGES table (key : id) with given conditions
+   *
+   * "att3 = pit.id "
+   */
+  static public function getJoin($param="")
+  {
+    return("ase_pitd.id = pit.id");
+  }
+
+
+  /**
+   * the getFilter function must return a ready to use where clause
+   * this where clause is used to filter the cache when the used tables can
+   * return more than one result
+   *
+   * the filter can be empty, can be equal to the where clause, or can be equal
+   * to a sub part of the where clause
+   *
+   */
+  static public function getFilter($param="")
+  {
+    return(self::getWhere($param));
+  }
+
+  /**
+   * this function is called by the request builder, allowing to display plugin
+   * data with a specific format
+   *
+   * @param Array $attributes : array of ('attribute_name' => 'attribute_value')
+   * @return String : HTML formatted value
+   */
+  static public function formatData($attributes)
+  {
+    /* attributes is an array :
+     *    Array(
+     *      'csColors' => 'color1,color2,color3,...,colorN',
+     *      'csColorsPct' => 'pct1,pct2,pct3,...,pctN'
+     *    );
+     */
+    $returned="<span style='font-weight:bold;'>";
+    if(array_key_exists('dateCreation', $attributes))
+    {
+      $returned.=l10n('ase_dateCreation')."</span>&nbsp;:&nbsp;".$attributes['dateCreation'];
+    }
+    else
+    {
+      $returned.=l10n('ase_Available')."</span>&nbsp;:&nbsp;".$attributes['dateAvailable'];
+    }
+    return($returned);
+  }
+
+
+
+  /**
+   * this function is called by the request builder to make the search page, and
+   * must return the HTML & JS code of the dialogbox used to select criterion
+   *
+   * Notes :
+   *  - the dialogbox is a JS object with a public method 'show'
+   *  - when the method show is called, one parameter is given by the request
+   *    builder ; the parameter is an object defined as this :
+   *      {
+   *        cBuilder: an instance of the criteriaBuilder object used in the page,
+   *        eventOK : a callback function, called when the OK button is pushed
+   *        id:
+   *      }
+   *
+   *
+   *
+   *
+   * @param String $mode : can take 'admin' or 'public' values, allowing to
+   *                       return different interface if needed
+   * @return String : HTML formatted value
+   */
+  static public function getInterfaceContent($mode='admin')
+  {
+    return(ASE_functions::dialogBoxASEDate());
+  }
+
+  /**
+   * this function returns the label displayed in the criterion menu
+   *
+   * @return String : label displayed in the criterions menu
+   */
+  static public function getInterfaceLabel()
+  {
+    return(l10n('ase_add_date'));
+  }
+
+  /**
+   * this function returns the name of the dialog box class
+   *
+   * @return String : name of the dialogbox class
+   */
+  static public function getInterfaceDBClass()
+  {
+    return('dialogChooseASEDateBox');
+  }
+
+}
+
+?>
Index: extensions/ASearchEngine/ase_rb_callback_hd.class.inc.php
===================================================================
--- extensions/ASearchEngine/ase_rb_callback_hd.class.inc.php	(revision 7196)
+++ extensions/ASearchEngine/ase_rb_callback_hd.class.inc.php	(revision 7196)
@@ -0,0 +1,183 @@
+<?php
+/* -----------------------------------------------------------------------------
+  Plugin     : Advanced Search Engine
+  Author     : Grum
+    email    : grum@piwigo.org
+    website  : http://photos.grum.fr
+
+    << May the Little SpaceFrog be with you ! >>
+  ------------------------------------------------------------------------------
+  See main.inc.php for release information
+
+
+  --------------------------------------------------------------------------- */
+
+  if(!defined('PHPWG_ROOT_PATH')) die('Hacking attempt!');
+
+  include_once(PHPWG_PLUGINS_PATH.'GrumPluginClasses/classes/GPCRequestBuilder.class.inc.php');
+
+load_language('plugin.lang', ASE_PATH);
+
+class RBCallBackASEHD extends GPCSearchCallback {
+
+  /**
+   * the getImageId returns the name of the image id attribute
+   * return String
+   */
+  static public function getImageId()
+  {
+    return("ase_pith.id");
+  }
+
+  /**
+   * the getSelect function must return an attribute list separated with a comma
+   *
+   * "att1, att2, att3, att4"
+   */
+  static public function getSelect($param="")
+  {
+    $returned=" ase_pith.has_high AS hasHigh";
+    return($returned);
+  }
+
+  /**
+   * the getFrom function must return a tables list separated with a comma
+   *
+   * "table1, (table2 left join table3 on table2.key = table3.key), table4"
+   */
+  static public function getFrom($param="")
+  {
+    global $prefixeTable;
+
+    return(IMAGES_TABLE." ase_pith ");
+  }
+
+  /**
+   * the getWhere function must return a ready to use where clause
+   *
+   * "(att1 = value0 OR att2 = value1) AND att4 LIKE value2 "
+   */
+  static public function getWhere($param="")
+  {
+    global $user;
+
+
+    if($param['withHD']=='y')
+    {
+      $returned=" ase_pith.has_high=true ";
+    }
+    else
+    {
+      $returned=" ase_pith.has_high=false OR ase_pith.has_high IS NULL ";
+    }
+
+    return($returned);
+  }
+
+
+  /**
+   * the getJoin function must return a ready to use where allowing to join the
+   * IMAGES table (key : id) with given conditions
+   *
+   * "att3 = pit.id "
+   */
+  static public function getJoin($param="")
+  {
+    return("ase_pith.id = pit.id");
+  }
+
+
+  /**
+   * the getFilter function must return a ready to use where clause
+   * this where clause is used to filter the cache when the used tables can
+   * return more than one result
+   *
+   * the filter can be empty, can be equal to the where clause, or can be equal
+   * to a sub part of the where clause
+   *
+   */
+  static public function getFilter($param="")
+  {
+    return(self::getWhere($param));
+  }
+
+  /**
+   * this function is called by the request builder, allowing to display plugin
+   * data with a specific format
+   *
+   * @param Array $attributes : array of ('attribute_name' => 'attribute_value')
+   * @return String : HTML formatted value
+   */
+  static public function formatData($attributes)
+  {
+    /* attributes is an array :
+     *    Array(
+     *      'csColors' => 'color1,color2,color3,...,colorN',
+     *      'csColorsPct' => 'pct1,pct2,pct3,...,pctN'
+     *    );
+     */
+    $returned="<span style='font-weight:bold;'>".l10n('ase_the_picture_has_HD')."</span>&nbsp;:&nbsp;";
+
+    if($returned['hasHigh']==true)
+    {
+      $returned.=l10n('ase_y');
+    }
+    else
+    {
+      $returned.=l10n('ase_n');
+    }
+
+    return($returned);
+  }
+
+
+
+  /**
+   * this function is called by the request builder to make the search page, and
+   * must return the HTML & JS code of the dialogbox used to select criterion
+   *
+   * Notes :
+   *  - the dialogbox is a JS object with a public method 'show'
+   *  - when the method show is called, one parameter is given by the request
+   *    builder ; the parameter is an object defined as this :
+   *      {
+   *        cBuilder: an instance of the criteriaBuilder object used in the page,
+   *        eventOK : a callback function, called when the OK button is pushed
+   *        id:
+   *      }
+   *
+   *
+   *
+   *
+   * @param String $mode : can take 'admin' or 'public' values, allowing to
+   *                       return different interface if needed
+   * @return String : HTML formatted value
+   */
+  static public function getInterfaceContent($mode='admin')
+  {
+    return(ASE_functions::dialogBoxASEHD());
+  }
+
+  /**
+   * this function returns the label displayed in the criterion menu
+   *
+   * @return String : label displayed in the criterions menu
+   */
+  static public function getInterfaceLabel()
+  {
+    return(l10n('ase_add_HD'));
+  }
+
+  /**
+   * this function returns the name of the dialog box class
+   *
+   * @return String : name of the dialogbox class
+   */
+  static public function getInterfaceDBClass()
+  {
+    return('dialogChooseASEHDBox');
+  }
+
+}
+
+?>
Index: extensions/ASearchEngine/ase_rb_callback_keyword.class.inc.php
===================================================================
--- extensions/ASearchEngine/ase_rb_callback_keyword.class.inc.php	(revision 7196)
+++ extensions/ASearchEngine/ase_rb_callback_keyword.class.inc.php	(revision 7196)
@@ -0,0 +1,235 @@
+<?php
+/* -----------------------------------------------------------------------------
+  Plugin     : Advanced Search Engine
+  Author     : Grum
+    email    : grum@piwigo.org
+    website  : http://photos.grum.fr
+
+    << May the Little SpaceFrog be with you ! >>
+  ------------------------------------------------------------------------------
+  See main.inc.php for release information
+
+
+  --------------------------------------------------------------------------- */
+
+  if(!defined('PHPWG_ROOT_PATH')) die('Hacking attempt!');
+
+  include_once(PHPWG_PLUGINS_PATH.'GrumPluginClasses/classes/GPCRequestBuilder.class.inc.php');
+
+load_language('plugin.lang', ASE_PATH);
+
+class RBCallBackASEKeyword extends GPCSearchCallback {
+
+  /**
+   * the getImageId returns the name of the image id attribute
+   * return String
+   */
+  static public function getImageId()
+  {
+    return("ase_pitk.id");
+  }
+
+  /**
+   * the getSelect function must return an attribute list separated with a comma
+   *
+   * "att1, att2, att3, att4"
+   */
+  static public function getSelect($param="")
+  {
+    $returned="";
+
+    if($param['searchName']=='y')
+    {
+      $returned=" ase_pitk.name AS optName";
+    };
+
+    if($param['searchDesc']=='y')
+    {
+      $returned.=($returned==''?'':',')." ase_pitk.comment AS optDesc";
+    };
+
+    if($param['searchFileName']=='y')
+    {
+      $returned.=($returned==''?'':',')." ase_pitk.file AS optFileName";
+    };
+
+    return($returned);
+  }
+
+  /**
+   * the getFrom function must return a tables list separated with a comma
+   *
+   * "table1, (table2 left join table3 on table2.key = table3.key), table4"
+   */
+  static public function getFrom($param="")
+  {
+    global $prefixeTable;
+
+    return(IMAGES_TABLE." ase_pitk ");
+  }
+
+  /**
+   * the getWhere function must return a ready to use where clause
+   *
+   * "(att1 = value0 OR att2 = value1) AND att4 LIKE value2 "
+   */
+  static public function getWhere($param="")
+  {
+    global $user;
+
+    $clauses=array();
+
+    if($param['searchName']=='y')
+    {
+      $clauses[]=self::getWhereClause('name', $param['keyword'], $param['optIgnoreCase'], $param['optWholeWords']);
+    }
+
+    if($param['searchDesc']=='y')
+    {
+      $clauses[]=self::getWhereClause('comment', $param['keyword'], $param['optIgnoreCase'], $param['optWholeWords']);
+    }
+
+    if($param['searchFileName']=='y')
+    {
+      $clauses[]=self::getWhereClause('file', $param['keyword'], $param['optIgnoreCase'], $param['optWholeWords']);
+    }
+
+    $returned=implode(' OR ', $clauses);
+
+    return($returned);
+  }
+
+  static private function getWhereClause($target, $keyword, $case, $wwords)
+  {
+    if($target=='file' and $case=='y')
+    {
+      $returned="LOWER(ase_pitk.$target) REGEXP ";
+      $keyword=strtolower($keyword);
+    }
+    else
+    {
+      $returned="ase_pitk.$target REGEXP ";
+    }
+
+    if($case=='n') $returned.=" BINARY ";
+
+    if($wwords=='n')
+    {
+      $returned.=" '$keyword'";
+    }
+    else
+    {
+      $returned.=" '[[:<:]]".$keyword."[[:>:]]'";
+    }
+    return($returned);
+  }
+
+  /**
+   * the getJoin function must return a ready to use where allowing to join the
+   * IMAGES table (key : id) with given conditions
+   *
+   * "att3 = pit.id "
+   */
+  static public function getJoin($param="")
+  {
+    return("ase_pitk.id = pit.id");
+  }
+
+
+  /**
+   * the getFilter function must return a ready to use where clause
+   * this where clause is used to filter the cache when the used tables can
+   * return more than one result
+   *
+   * the filter can be empty, can be equal to the where clause, or can be equal
+   * to a sub part of the where clause
+   *
+   */
+  static public function getFilter($param="")
+  {
+    return(self::getWhere($param));
+  }
+
+  /**
+   * this function is called by the request builder, allowing to display plugin
+   * data with a specific format
+   *
+   * @param Array $attributes : array of ('attribute_name' => 'attribute_value')
+   * @return String : HTML formatted value
+   */
+  static public function formatData($attributes)
+  {
+    /* attributes is an array :
+     *    Array(
+     *      'csColors' => 'color1,color2,color3,...,colorN',
+     *      'csColorsPct' => 'pct1,pct2,pct3,...,pctN'
+     *    );
+     */
+    $returned="";
+    if(array_key_exists('optName', $attributes))
+    {
+      $returned.="<span style='font-weight:bold;'>".l10n('ase_optName')."</span>&nbsp;:&nbsp;".$attributes['optName'];
+    }
+    if(array_key_exists('optDesc', $attributes))
+    {
+      $returned.=($returned==''?'':'<br>')."<span style='font-weight:bold;'>".l10n('ase_optDesc')."</span>&nbsp;:&nbsp;".$attributes['optDesc'];
+    }
+    if(array_key_exists('optFileName', $attributes))
+    {
+      $returned.=($returned==''?'':'<br>')."<span style='font-weight:bold;'>".l10n('ase_optFileName')."</span>&nbsp;:&nbsp;".$attributes['optFileName'];
+    }
+
+    return($returned);
+  }
+
+
+
+  /**
+   * this function is called by the request builder to make the search page, and
+   * must return the HTML & JS code of the dialogbox used to select criterion
+   *
+   * Notes :
+   *  - the dialogbox is a JS object with a public method 'show'
+   *  - when the method show is called, one parameter is given by the request
+   *    builder ; the parameter is an object defined as this :
+   *      {
+   *        cBuilder: an instance of the criteriaBuilder object used in the page,
+   *        eventOK : a callback function, called when the OK button is pushed
+   *        id:
+   *      }
+   *
+   *
+   *
+   *
+   * @param String $mode : can take 'admin' or 'public' values, allowing to
+   *                       return different interface if needed
+   * @return String : HTML formatted value
+   */
+  static public function getInterfaceContent($mode='admin')
+  {
+    return(ASE_functions::dialogBoxASEKeyword());
+  }
+
+  /**
+   * this function returns the label displayed in the criterion menu
+   *
+   * @return String : label displayed in the criterions menu
+   */
+  static public function getInterfaceLabel()
+  {
+    return(l10n('ase_add_keyword'));
+  }
+
+  /**
+   * this function returns the name of the dialog box class
+   *
+   * @return String : name of the dialogbox class
+   */
+  static public function getInterfaceDBClass()
+  {
+    return('dialogChooseASEKeywordBox');
+  }
+
+}
+
+?>
Index: extensions/ASearchEngine/ase_rb_callback_rate.class.inc.php
===================================================================
--- extensions/ASearchEngine/ase_rb_callback_rate.class.inc.php	(revision 7196)
+++ extensions/ASearchEngine/ase_rb_callback_rate.class.inc.php	(revision 7196)
@@ -0,0 +1,182 @@
+<?php
+/* -----------------------------------------------------------------------------
+  Plugin     : Advanced Search Engine
+  Author     : Grum
+    email    : grum@piwigo.org
+    website  : http://photos.grum.fr
+
+    << May the Little SpaceFrog be with you ! >>
+  ------------------------------------------------------------------------------
+  See main.inc.php for release information
+
+
+  --------------------------------------------------------------------------- */
+
+  if(!defined('PHPWG_ROOT_PATH')) die('Hacking attempt!');
+
+  include_once(PHPWG_PLUGINS_PATH.'GrumPluginClasses/classes/GPCRequestBuilder.class.inc.php');
+
+load_language('plugin.lang', ASE_PATH);
+
+class RBCallBackASERate extends GPCSearchCallback {
+
+  /**
+   * the getImageId returns the name of the image id attribute
+   * return String
+   */
+  static public function getImageId()
+  {
+    return("ase_pitn.id");
+  }
+
+  /**
+   * the getSelect function must return an attribute list separated with a comma
+   *
+   * "att1, att2, att3, att4"
+   */
+  static public function getSelect($param="")
+  {
+    return(" ase_pitn.average_rate AS averageRate");
+  }
+
+  /**
+   * the getFrom function must return a tables list separated with a comma
+   *
+   * "table1, (table2 left join table3 on table2.key = table3.key), table4"
+   */
+  static public function getFrom($param="")
+  {
+    global $prefixeTable;
+
+    return(IMAGES_TABLE." ase_pitn ");
+  }
+
+  /**
+   * the getWhere function must return a ready to use where clause
+   *
+   * "(att1 = value0 OR att2 = value1) AND att4 LIKE value2 "
+   */
+  static public function getWhere($param="")
+  {
+    global $user;
+
+    $returned=" ase_pitn.average_rate ";
+
+    switch($param['searchType'])
+    {
+      case 'no':
+        $returned.=" IS NULL ";
+        break;
+      case 'eq':
+        $returned.=" = '".$param['minValue']."' ";
+        break;
+      case 'bt':
+        $returned.=" BETWEEN '".$param['minValue']."' AND '".$param['maxValue']."' ";
+        break;
+      case 'gt':
+        $returned.=" >= '".$param['minValue']."' ";
+        break;
+      case 'lt':
+        $returned.=" <= '".$param['maxValue']."' ";
+        break;
+    }
+
+    return($returned);
+  }
+
+  /**
+   * the getJoin function must return a ready to use where allowing to join the
+   * IMAGES table (key : id) with given conditions
+   *
+   * "att3 = pit.id "
+   */
+  static public function getJoin($param="")
+  {
+    return("ase_pitn.id = pit.id");
+  }
+
+
+  /**
+   * the getFilter function must return a ready to use where clause
+   * this where clause is used to filter the cache when the used tables can
+   * return more than one result
+   *
+   * the filter can be empty, can be equal to the where clause, or can be equal
+   * to a sub part of the where clause
+   *
+   */
+  static public function getFilter($param="")
+  {
+    return(self::getWhere($param));
+  }
+
+  /**
+   * this function is called by the request builder, allowing to display plugin
+   * data with a specific format
+   *
+   * @param Array $attributes : array of ('attribute_name' => 'attribute_value')
+   * @return String : HTML formatted value
+   */
+  static public function formatData($attributes)
+  {
+    /* attributes is an array :
+     *    Array(
+     *      'csColors' => 'color1,color2,color3,...,colorN',
+     *      'csColorsPct' => 'pct1,pct2,pct3,...,pctN'
+     *    );
+     */
+    $returned="<span style='font-weight:bold;'>".l10n('ase_average_rate')."</span>&nbsp;:&nbsp;".$attributes['averageRate'];
+    return($returned);
+  }
+
+
+
+  /**
+   * this function is called by the request builder to make the search page, and
+   * must return the HTML & JS code of the dialogbox used to select criterion
+   *
+   * Notes :
+   *  - the dialogbox is a JS object with a public method 'show'
+   *  - when the method show is called, one parameter is given by the request
+   *    builder ; the parameter is an object defined as this :
+   *      {
+   *        cBuilder: an instance of the criteriaBuilder object used in the page,
+   *        eventOK : a callback function, called when the OK button is pushed
+   *        id:
+   *      }
+   *
+   *
+   *
+   *
+   * @param String $mode : can take 'admin' or 'public' values, allowing to
+   *                       return different interface if needed
+   * @return String : HTML formatted value
+   */
+  static public function getInterfaceContent($mode='admin')
+  {
+    return(ASE_functions::dialogBoxASERate());
+  }
+
+  /**
+   * this function returns the label displayed in the criterion menu
+   *
+   * @return String : label displayed in the criterions menu
+   */
+  static public function getInterfaceLabel()
+  {
+    return(l10n('ase_add_rate'));
+  }
+
+  /**
+   * this function returns the name of the dialog box class
+   *
+   * @return String : name of the dialogbox class
+   */
+  static public function getInterfaceDBClass()
+  {
+    return('dialogChooseASERateBox');
+  }
+
+}
+
+?>
Index: extensions/ASearchEngine/ase_root.class.inc.php
===================================================================
--- extensions/ASearchEngine/ase_root.class.inc.php	(revision 7196)
+++ extensions/ASearchEngine/ase_root.class.inc.php	(revision 7196)
@@ -0,0 +1,251 @@
+<?php
+/* -----------------------------------------------------------------------------
+  Plugin     : Advanced Search Engine
+  Author     : Grum
+    email    : grum@piwigo.org
+    website  : http://photos.grum.fr
+
+    << May the Little SpaceFrog be with you ! >>
+  ------------------------------------------------------------------------------
+  See main.inc.php for release information
+
+  ASE_root : common classe for admin and public classes
+
+  --------------------------------------------------------------------------- */
+  include_once(PHPWG_PLUGINS_PATH.'GrumPluginClasses/classes/CommonPlugin.class.inc.php');
+  include_once(PHPWG_PLUGINS_PATH.'GrumPluginClasses/classes/GPCCss.class.inc.php');
+
+  class ASE_root extends CommonPlugin
+  {
+    protected $css;
+
+    public function __construct($prefixeTable, $filelocation)
+    {
+      $this->setPluginName('Advanced Search Engine');
+      $this->setPluginNameFiles("ase");
+      parent::__construct($prefixeTable, $filelocation);
+      $this->section_name=$this->getPluginNameFiles();
+
+      $this->css = new GPCCss(dirname($this->getFileLocation()).'/'.$this->getPluginNameFiles().".css");
+    }
+
+    public function __destruct()
+    {
+      parent::__destruct();
+    }
+
+    public function initEvents()
+    {
+    }
+
+
+    /*
+      surchage of CommonPlugin->saveConfig function
+    */
+    public function saveConfig()
+    {
+      if(parent::saveConfig())
+      {
+        return(true);
+      }
+      return(false);
+    }
+
+    /*
+      surchage of CommonPlugin->saveConfig function
+    */
+    public function loadConfig()
+    {
+      parent::loadConfig();
+    }
+
+    /*
+      intialize default values
+    */
+    public function initConfig()
+    {
+      //global $user;
+      $this->config=array(
+      );
+    }
+
+
+    /**
+     *
+     */
+    protected function configForTemplate()
+    {
+      global $template;
+
+      $template->assign('aseConfig', $this->config);
+    }
+
+
+    public function getAdminLink($mode='')
+    {
+      if($mode=='ajax')
+      {
+        return('plugins/'.basename(dirname($this->getFileLocation())).'/ase_ajax.php');
+      }
+      else
+      {
+        return(parent::getAdminLink());
+      }
+    }
+
+    protected function displayResult($action_msg, $result)
+    {
+      global $page;
+
+      if($result)
+      {
+        array_push($page['infos'], $action_msg);
+      }
+      else
+      {
+        array_push($page['errors'], $action_msg);
+      }
+    }
+
+
+    /* ---------------------------------------------------------------------------
+
+    --------------------------------------------------------------------------- */
+
+
+
+  } //class
+
+
+
+class ASE_functions
+  {
+    static private $tables = Array();
+    static private $config = Array();
+
+    /**
+     * initialise the class
+     *
+     * @param String $prefixeTable : the piwigo prefixe used on tables name
+     * @param String $pluginNameFile : the plugin name used for tables name
+     */
+    static public function init($prefixeTable)
+    {
+      // no tables for this plugin
+    }
+
+
+    /**
+     *  return all HTML&JS code necessary to display a dialogbox to choose
+     *  tags
+     */
+    static public function dialogBoxASETags()
+    {
+      global $template;
+
+      $template->set_filename('ase_tag_choose',
+                    dirname(__FILE__).'/templates/ase_dialog_tag_choose.tpl');
+
+      $datas=Array();
+
+      $template->assign('datas', $datas);
+
+      return($template->parse('ase_tag_choose', true));
+    }
+
+
+    /**
+     *  return all HTML&JS code necessary to display a dialogbox to choose
+     *  categories
+     */
+    static public function dialogBoxASECategory()
+    {
+      global $template;
+
+      $template->set_filename('ase_category_choose',
+                    dirname(__FILE__).'/templates/ase_dialog_category_choose.tpl');
+
+      $datas=Array();
+
+      $template->assign('datas', $datas);
+
+      return($template->parse('ase_category_choose', true));
+    }
+
+    /**
+     *  return all HTML&JS code necessary to display a dialogbox to choose
+     *  dates
+     */
+    static public function dialogBoxASEDate()
+    {
+      global $template;
+
+      $template->set_filename('ase_date_choose',
+                    dirname(__FILE__).'/templates/ase_dialog_date_choose.tpl');
+
+      $datas=Array();
+
+      $template->assign('datas', $datas);
+
+      return($template->parse('ase_date_choose', true));
+    }
+
+    /**
+     *  return all HTML&JS code necessary to display a dialogbox to choose
+     *  keywords
+     */
+    static public function dialogBoxASEKeyword()
+    {
+      global $template;
+
+      $template->set_filename('ase_keyword_choose',
+                    dirname(__FILE__).'/templates/ase_dialog_keyword_choose.tpl');
+
+      $datas=Array();
+
+      $template->assign('datas', $datas);
+
+      return($template->parse('ase_keyword_choose', true));
+    }
+
+    /**
+     *  return all HTML&JS code necessary to display a dialogbox to choose
+     *  HD picture
+     */
+    static public function dialogBoxASEHD()
+    {
+      global $template;
+
+      $template->set_filename('ase_hd_choose',
+                    dirname(__FILE__).'/templates/ase_dialog_hd_choose.tpl');
+
+      $datas=Array();
+
+      $template->assign('datas', $datas);
+
+      return($template->parse('ase_hd_choose', true));
+    }
+
+    /**
+     *  return all HTML&JS code necessary to display a dialogbox to choose
+     *  rate on picture
+     */
+    static public function dialogBoxASERate()
+    {
+      global $template;
+
+      $template->set_filename('ase_rate_choose',
+                    dirname(__FILE__).'/templates/ase_dialog_rate_choose.tpl');
+
+      $datas=Array();
+
+      $template->assign('datas', $datas);
+
+      return($template->parse('ase_rate_choose', true));
+    }
+
+  } //ASE_functions
+
+
+
+?>
Index: extensions/ASearchEngine/ase_version.inc.php
===================================================================
--- extensions/ASearchEngine/ase_version.inc.php	(revision 7196)
+++ extensions/ASearchEngine/ase_version.inc.php	(revision 7196)
@@ -0,0 +1,20 @@
+<?php
+/* -----------------------------------------------------------------------------
+  Plugin     : Advanced Search Engine
+  Author     : Grum
+    email    : grum@grum.fr
+    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
+
+  --------------------------------------------------------------------------- */
+
+  if (!defined('PHPWG_ROOT_PATH')) die('Hacking attempt!');
+
+  define('ASE_VERSION',  '0.1.0');
+  define('ASE_VERSION2', '00.01.00');
+  define('ASE_GPC_NEEDED', '3.3.1');
+?>
Index: extensions/ASearchEngine/index.php
===================================================================
--- extensions/ASearchEngine/index.php	(revision 7196)
+++ extensions/ASearchEngine/index.php	(revision 7196)
@@ -0,0 +1,33 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | PhpWebGallery - a PHP based picture gallery                           |
+// | Copyright (C) 2002-2003 Pierrick LE GALL - pierrick@phpwebgallery.net |
+// | Copyright (C) 2003-2007 PhpWebGallery Team - http://phpwebgallery.net |
+// +-----------------------------------------------------------------------+
+// | file          : $Id: index.php 1912 2007-03-16 06:30:07Z rub $
+// | last update   : $Date: 2007-03-16 07:30:07 +0100 (ven, 16 mar 2007) $
+// | last modifier : $Author: rub $
+// | revision      : $Revision: 1912 $
+// +-----------------------------------------------------------------------+
+// | 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.                                                                  |
+// +-----------------------------------------------------------------------+
+
+// Recursive call
+$url = '../';
+header( 'Request-URI: '.$url );
+header( 'Content-Location: '.$url );
+header( 'Location: '.$url );
+exit();
+?>
Index: extensions/ASearchEngine/language/en_UK/description.txt
===================================================================
--- extensions/ASearchEngine/language/en_UK/description.txt	(revision 7196)
+++ extensions/ASearchEngine/language/en_UK/description.txt	(revision 7196)
@@ -0,0 +1,1 @@
+An advanced search engine
Index: extensions/ASearchEngine/language/en_UK/index.php
===================================================================
--- extensions/ASearchEngine/language/en_UK/index.php	(revision 7196)
+++ extensions/ASearchEngine/language/en_UK/index.php	(revision 7196)
@@ -0,0 +1,33 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | PhpWebGallery - a PHP based picture gallery                           |
+// | Copyright (C) 2002-2003 Pierrick LE GALL - pierrick@phpwebgallery.net |
+// | Copyright (C) 2003-2007 PhpWebGallery Team - http://phpwebgallery.net |
+// +-----------------------------------------------------------------------+
+// | file          : $Id: index.php 1912 2007-03-16 06:30:07Z rub $
+// | last update   : $Date: 2007-03-16 07:30:07 +0100 (ven, 16 mar 2007) $
+// | last modifier : $Author: rub $
+// | revision      : $Revision: 1912 $
+// +-----------------------------------------------------------------------+
+// | 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.                                                                  |
+// +-----------------------------------------------------------------------+
+
+// Recursive call
+$url = '../';
+header( 'Request-URI: '.$url );
+header( 'Content-Location: '.$url );
+header( 'Location: '.$url );
+exit();
+?>
Index: extensions/ASearchEngine/language/fr_FR/description.txt
===================================================================
--- extensions/ASearchEngine/language/fr_FR/description.txt	(revision 7196)
+++ extensions/ASearchEngine/language/fr_FR/description.txt	(revision 7196)
@@ -0,0 +1,1 @@
+Moteur pour effectuer des recherches avancées
Index: extensions/ASearchEngine/language/fr_FR/index.php
===================================================================
--- extensions/ASearchEngine/language/fr_FR/index.php	(revision 7196)
+++ extensions/ASearchEngine/language/fr_FR/index.php	(revision 7196)
@@ -0,0 +1,33 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | PhpWebGallery - a PHP based picture gallery                           |
+// | Copyright (C) 2002-2003 Pierrick LE GALL - pierrick@phpwebgallery.net |
+// | Copyright (C) 2003-2007 PhpWebGallery Team - http://phpwebgallery.net |
+// +-----------------------------------------------------------------------+
+// | file          : $Id: index.php 1912 2007-03-16 06:30:07Z rub $
+// | last update   : $Date: 2007-03-16 07:30:07 +0100 (ven, 16 mar 2007) $
+// | last modifier : $Author: rub $
+// | revision      : $Revision: 1912 $
+// +-----------------------------------------------------------------------+
+// | 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.                                                                  |
+// +-----------------------------------------------------------------------+
+
+// Recursive call
+$url = '../';
+header( 'Request-URI: '.$url );
+header( 'Content-Location: '.$url );
+header( 'Location: '.$url );
+exit();
+?>
Index: extensions/ASearchEngine/language/fr_FR/plugin.lang.php
===================================================================
--- extensions/ASearchEngine/language/fr_FR/plugin.lang.php	(revision 7196)
+++ extensions/ASearchEngine/language/fr_FR/plugin.lang.php	(revision 7196)
@@ -0,0 +1,96 @@
+<?php
+
+$lang['To install this plugin, you need to install Grum Plugin Classes %s before']="Pour installer ce plugin, vous devez au préalable installer le plugin Grum Plugin Classes %s";
+
+$lang['ase_release']='v';
+
+$lang['ase_search']='Rechercher';
+$lang['ase_config']='Configurer';
+
+$lang['ase_search_with_multiple_criteria']="Recherche multi-critères";
+
+$lang['ase_ok']="Ok";
+$lang['ase_cancel']="Annuler";
+
+$lang['ase_add_category']="Ajouter une ou plusieurs catégories";
+$lang['ase_add_date']="Ajouter une période";
+$lang['ase_add_keyword']="Ajouter un mot-clef";
+$lang['ase_add_HD']="Ajouter la présence d'une photo HD";
+$lang['ase_add_rate']="Ajouter une note";
+
+
+$lang['ase_choose_categories']="Recherche sur une ou plusieurs catégories";
+$lang['ase_choose_date']="Recherche sur une période";
+$lang['ase_search_keyword']="Recherche sur un mot-clef";
+$lang['ase_search_HD']="Recherche sur la présence d'une photo HD";
+$lang['ase_choose_rate']="Recherche par note";
+
+$lang['ase_categories']="Catégories";
+$lang['ase_category']="Catégorie";
+$lang['ase_y']='Oui';
+$lang['ase_n']='Non';
+$lang['ase_one_category_must_be_selected']="Une catégorie doit être sélectionnée";
+$lang['ase_searching_in_subcat']="Recherche dans les sous-catégories";
+$lang['ase_with_search_in_subcat']="avec recherche dans les sous-catégories";
+
+$lang['ase_search_on_date']="Effectuer la recherche sur la date";
+$lang['ase_date_between']="Comprise entre le";
+$lang['ase_date_to']="et le";
+$lang['ase_image_availability']="d'ajout";
+$lang['ase_image_shot']="de prise de vue";
+$lang['ase_the_date']="La date";
+$lang['ase_is_between']="est comprise entre le"; // the date is between ... and ...
+$lang['ase_is_between_and']="et le"; // the date is between ... and ...
+$lang['ase_is_greater_or_equal']="est postérieure ou égale au"; //the date is greater or equal than ...
+$lang['ase_is_less_or_equal']="est antérieure ou égale au"; // the date is less or equal ...
+$lang['ase_is_equal_to']="est égale au"; // the date is ...
+
+$lang['ase_dateCreation']="Date de prise de vue";
+$lang['ase_dateAvailable']="Date d'ajout";
+
+$lang['ase_error_date_from']="La date de début de période est invalide";
+$lang['ase_error_date_to']="La date de fin de période est invalide";
+$lang['ase_error_date']="La date est invalide";
+$lang['ase_error_period']="La période est invalide : la date de début de période doit être antérieure ou égale à la date de fin de période";
+
+$lang['ase_keyword']="Mot clef à trouver";
+$lang['ase_ignore_case']="Ignorer la casse";
+$lang['ase_whole_words_only']="Mots entiers uniquement";
+$lang['ase_search_into']="Chercher dans";
+$lang['ase_picture_name']="le nom de la photo";
+$lang['ase_picture_desc']="la description de la photo";
+$lang['ase_picture_filename']="le nom du fichier de la photo";
+
+$lang['ase_error_keyword_length']="Le mot clef à rechercher est trop court !";
+$lang['ase_error_no_target']="La recherche doit être effectuée dans au moins une des propriétés de la photo";
+$lang['ase_optName']="Nom";
+$lang['ase_optDesc']="Description";
+$lang['ase_optFileName']="Fichier";
+$lang['ase_search_the_keyword']="Rechercher le mot-clef";
+$lang['ase_search_into_name']="Dans le nom de la photo";
+$lang['ase_search_into_desc']="Dans la description de la photo";
+$lang['ase_search_into_filename']="Dans le nom du fichier de la photo";
+$lang['ase_search_with_case_ignored']="En ignorant la casse";
+$lang['ase_search_with_whole_words']="Sur les mots entiers uniquement";
+
+$lang['ase_search_hd']="Recherche de photos HD";
+
+$lang['ase_the_picture']="La photo";
+$lang['ase_the_picture_has_HD']="Présence d'une photo HD";
+$lang['ase_picture_with_hd']="dispose d'une photo HD";
+$lang['ase_picture_without_hd']="ne dispose pas d'une photo HD";
+
+$lang['ase_the_rate']="La note";
+$lang['ase_dont_have_rate']="la photo n'est pas notée";
+$lang['ase_Dont_have_rate']="La photo n'est pas notée"; // with first letter in uppercase
+$lang['ase_average_rate']="Note moyenne";
+
+$lang['ase_error_rate_range']="L'intervalle est invalide : la note minimum doit être inférieure ou égal à la note maximum";
+$lang['ase_is_between2']="est comprise entre"; // the rate is between ... and ...
+$lang['ase_is_between_and2']="et"; // the rate is between ... and ...
+$lang['ase_is_greater_or_equal2']="est supérieure ou égale à"; // the rate is greater or equal than ...
+$lang['ase_is_less_or_equal2']="est inférieure ou égale à"; // the rate is less or equal ...
+$lang['ase_is_equal2']="est égale à"; // the rate is equal to ...
+
+
+?>
Index: extensions/ASearchEngine/language/index.php
===================================================================
--- extensions/ASearchEngine/language/index.php	(revision 7196)
+++ extensions/ASearchEngine/language/index.php	(revision 7196)
@@ -0,0 +1,33 @@
+<?php
+// +-----------------------------------------------------------------------+
+// | PhpWebGallery - a PHP based picture gallery                           |
+// | Copyright (C) 2002-2003 Pierrick LE GALL - pierrick@phpwebgallery.net |
+// | Copyright (C) 2003-2007 PhpWebGallery Team - http://phpwebgallery.net |
+// +-----------------------------------------------------------------------+
+// | file          : $Id: index.php 1912 2007-03-16 06:30:07Z rub $
+// | last update   : $Date: 2007-03-16 07:30:07 +0100 (ven, 16 mar 2007) $
+// | last modifier : $Author: rub $
+// | revision      : $Revision: 1912 $
+// +-----------------------------------------------------------------------+
+// | 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.                                                                  |
+// +-----------------------------------------------------------------------+
+
+// Recursive call
+$url = '../';
+header( 'Request-URI: '.$url );
+header( 'Content-Location: '.$url );
+header( 'Location: '.$url );
+exit();
+?>
Index: extensions/ASearchEngine/main.inc.php
===================================================================
--- extensions/ASearchEngine/main.inc.php	(revision 7196)
+++ extensions/ASearchEngine/main.inc.php	(revision 7196)
@@ -0,0 +1,92 @@
+<?php
+/*
+Plugin Name: Advanced Search Engine
+Version: 0.1.0
+Description: An advanced search engine
+Plugin URI: http://phpwebgallery.net/ext/extension_view.php?eid=
+Author: grum@piwigo.org
+Author URI: http://photos.grum.fr
+*/
+
+/*
+--------------------------------------------------------------------------------
+  Author     : Grum
+    email    : grum@piwigo.com
+    website  : http://photos.grum.fr
+    PWG user : http://forum.phpwebgallery.net/profile.php?id=3706
+
+    << May the Little SpaceFrog be with you ! >>
+--------------------------------------------------------------------------------
+
+:: HISTORY
+
+| release | date       |
+| 0.1.0   | 2010-10-14 | * first lines of code
+|         |            |   . release not published
+|         |            |
+|         |            |
+|         |            |
+|         |            |
+|         |            |
+|         |            |
+|         |            |
+|         |            |
+|         |            |
+|         |            |
+|         |            |
+|         |            |
+|         |            |
+|         |            |
+|         |            |
+|         |            |
+|         |            |
+
+
+:: TO DO
+
+--------------------------------------------------------------------------------
+
+:: NFO
+  ASE_root : common classe for admin and public classes
+  ASE_AIM  : classe to manage plugin integration into plugin menu
+  ASE_AIP  : classe to manage plugin admin pages
+  ASE_PIP  : classe to manage plugin public pages
+
+--------------------------------------------------------------------------------
+*/
+
+// pour faciliter le debug :o)
+ //ini_set('error_reporting', E_ALL);
+ //ini_set('display_errors', true);
+
+if(!defined('PHPWG_ROOT_PATH')) die('Hacking attempt!');
+
+
+define('ASE_DIR' , basename(dirname(__FILE__)));
+define('ASE_PATH' , PHPWG_PLUGINS_PATH . ASE_DIR . '/');
+
+include_once(PHPWG_PLUGINS_PATH.'GrumPluginClasses/classes/CommonPlugin.class.inc.php');
+include_once('ase_version.inc.php'); // => Don't forget to update this file !!
+
+global $prefixeTable;
+
+if(defined('IN_ADMIN'))
+{
+  //ASE admin interface loaded and active only if in admin page
+  include_once("ase_aim.class.inc.php");
+  $obj=new ASE_AIM($prefixeTable, __FILE__);
+  $obj->initEvents();
+}
+else
+{
+  if(CommonPlugin::checkGPCRelease(ASE_GPC_NEEDED))
+  {
+    //ASE public interface loaded and active only if in public page
+    include_once("ase_pip.class.inc.php");
+    $obj=new ASE_PIP($prefixeTable, __FILE__);
+  }
+}
+
+set_plugin_data($plugin['id'], $obj);
+
+?>
Index: extensions/ASearchEngine/maintain.inc.php
===================================================================
--- extensions/ASearchEngine/maintain.inc.php	(revision 7196)
+++ extensions/ASearchEngine/maintain.inc.php	(revision 7196)
@@ -0,0 +1,111 @@
+<?php
+/* -----------------------------------------------------------------------------
+  Plugin     : Advanced Search Engine
+  Author     : Grum
+    email    : grum@piwigo.org
+    website  : http://photos.grum.fr
+
+    << May the Little SpaceFrog be with you ! >>
+  ------------------------------------------------------------------------------
+  See main.inc.php for release information
+
+  --------------------------------------------------------------------------- */
+
+if (!defined('PHPWG_ROOT_PATH')) { die('Hacking attempt!'); }
+
+include_once('ase_version.inc.php'); // => Don't forget to update this file !!
+
+
+if(!defined('ASE_DIR')) define('ASE_DIR' , basename(dirname(__FILE__)));
+if(!defined('ASE_PATH')) define('ASE_PATH' , PHPWG_PLUGINS_PATH . ASE_DIR . '/');
+
+//ini_set('error_reporting', E_ALL);
+//ini_set('display_errors', true);
+
+global $gpcInstalled, $lang; //needed for plugin manager compatibility
+
+/* -----------------------------------------------------------------------------
+ASE needs the Grum Plugin Classes
+----------------------------------------------------------------------------- */
+$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');
+  if(CommonPlugin::checkGPCRelease(ASE_GPC_NEEDED))
+  {
+    @include_once('ase_install.class.inc.php');
+    $gpcInstalled=true;
+  }
+}
+
+function gpcMsgError(&$errors)
+{
+  $msg=sprintf(l10n('To install this plugin, you need to install Grum Plugin Classes %s before'), ASE_GPC_NEEDED);
+  if(is_array($errors))
+  {
+    array_push($errors, $msg);
+  }
+  else
+  {
+    $errors=Array($msg);
+  }
+}
+// -----------------------------------------------------------------------------
+
+
+
+
+load_language('plugin.lang', ASE_PATH);
+
+
+function plugin_install($plugin_id, $plugin_version, &$errors)
+{
+  global $prefixeTable, $gpcInstalled;
+  if(!$gpcInstalled)
+  {
+    gpcMsgError($errors, 'gpc');
+    return(false);
+  }
+
+  $ase=new ASE_Install($prefixeTable, __FILE__);
+  $result=$ase->install();
+}
+
+function plugin_activate($plugin_id, $plugin_version, &$errors)
+{
+  global $prefixeTable, $gpcInstalled;
+  if($gpcInstalled)
+  {
+    $ase = new ASE_Install($prefixeTable, __FILE__);
+    $result=$ase->activate();
+  }
+}
+
+function plugin_deactivate($plugin_id)
+{
+  global $prefixeTable, $gpcInstalled;
+
+  if($gpcInstalled)
+  {
+    $ase=new ASE_Install($prefixeTable, __FILE__);
+    $ase->deactivate();
+  }
+
+}
+
+function plugin_uninstall($plugin_id)
+{
+  global $prefixeTable, $gpcInstalled;
+  if($gpcInstalled)
+  {
+    $ase=new ASE_Install($prefixeTable, __FILE__);
+    $result=$ase->uninstall();
+  }
+  else
+  {
+    gpcMsgError($errors, 'gpc');
+  }
+}
+
+
+?>
Index: extensions/ASearchEngine/templates/ase_dialog_category_choose.tpl
===================================================================
--- extensions/ASearchEngine/templates/ase_dialog_category_choose.tpl	(revision 7196)
+++ extensions/ASearchEngine/templates/ase_dialog_category_choose.tpl	(revision 7196)
@@ -0,0 +1,317 @@
+{known_script id="jquery.ui" src=$ROOT_URL|@cat:"themes/default/js/ui/packed/ui.core.packed.js"}
+{known_script id="jquery.ui.dialog" src=$ROOT_URL|@cat:"themes/default/js/ui/packed/ui.dialog.packed.js"}
+{known_script id="gpc.categorySelector" src=$ROOT_URL|@cat:"plugins/GrumPluginClasses/js/ui.categorySelector.packed.js"}
+
+
+{literal}
+<style type='text/css'>
+#iASECategoryCategory {
+  width:500px;
+}
+</style>
+
+<script type="text/javascript">
+/**
+ * include this template in a page and use dialogChooseASECategoryBox.show({options}) to display
+ * the dialog box
+ *
+ */
+dialogChooseASECategoryBox = function()
+{
+  var dialogOptions = {
+      id:'',
+      eventOk:null,
+      cBuilder:null,
+
+      values: {
+        subCat:'=',
+        catIdList:new Array()
+      },
+    };
+
+  /**
+   * initialize the dialog box
+   */
+  var initDialogBox = function()
+  {
+    $("#iDialogASECategoryChoose")
+    .dialog(
+      {
+        autoOpen: false,
+        resizable: false,
+        width:765,
+        height:130,
+        modal: true,
+        draggable:true,
+        dialogClass: 'gcBgTabSheet gcBorder',
+        title: '{/literal}{"ase_choose_categories"|@translate}{literal}',
+        open: function(event, ui)
+        {
+        },
+        buttons:
+        {
+          '{/literal}{"ase_ok"|@translate}{literal}':
+            function()
+            {
+              if(checkValidity())
+              {
+                dialogOptions.values.catIdList=$('#iASECategoryCategory').categorySelector('value');
+                dialogOptions.values.subCat=$('#iASECategorySubCat').val();
+
+
+                if(dialogOptions.cBuilder!=null)
+                {
+                  setCBuilderItem(dialogOptions.id, dialogOptions.values);
+                }
+
+                if(dialogOptions.eventOk!=null)
+                {
+                  dialogOptions.eventOk(dialogOptions.id, dialogOptions.values);
+                }
+                $(this).dialog('close');
+              }
+            },
+          '{/literal}{"ase_cancel"|@translate}{literal}':
+            function()
+            {
+              $(this).dialog('close');
+            }
+        }
+      }
+    )
+    .parent().css('overflow', 'visible');
+
+
+
+
+    $('#iASECategoryCategory').categorySelector(
+      {
+        multiple:true,
+        listMaxWidth:1,
+        listMaxHeight:350,
+        displayStatus:true,
+        levelIndent:20,
+        userMode:'admin',
+        galleryRoot:false,
+        load: function (event) { $(this).categorySelector('collapse', ':all'); }
+      }
+    );
+
+  }
+
+
+  /**
+   * check the validity of the condition
+   * return Boolean : true if OK, otherwise false
+   */
+  var checkValidity = function ()
+  {
+
+    if($('#iASECategoryCategory').categorySelector('value') .length==0)
+    {
+      alert('ase_one_category_must_be_selected');
+      return(false);
+    }
+    return(true);
+  }
+
+
+  /**
+   * the show() function display and manage a dialog box to choose categories
+   * and the kind of test to apply
+   *
+   * @param options : properties to manage the dialog box
+   *                  - id : a string to identify a DOM object ; this parameter
+   *                         is given to the callback when the OK button is pushed
+   *                  - values : an object with 2 properties
+   *                               - subCat : true or false, search in subcategories
+   *                               - catIdList : an array of categories Id
+   *                  - eventOK : a callback function, with 2 parameters : id of
+   *                              the given DOM object and values parameted
+   *                  - cBuilder : a criteriaBuilder object
+   *                               if set, the dialog box manage automaticaly
+   *                               the criteria builder interface
+   */
+  this.show = function (options)
+  {
+    showDialog(options);
+  }
+
+  /**
+   * private function used to show the dialog box
+   */
+  var showDialog = function(options)
+  {
+    if(options.id!=null)
+    {
+      dialogOptions.id=options.id;
+    }
+    else
+    {
+      dialogOptions.id='';
+    }
+
+    if(options.eventOk!=null)
+    {
+      dialogOptions.eventOk=options.eventOk;
+    }
+
+    if(options.cBuilder!=null)
+    {
+      dialogOptions.cBuilder=options.cBuilder;
+      dialogOptions.cBuilder.doAction('setOptions',
+        {
+          onEdit:function (e) { editCB(e.data); },
+          onDelete:function (e) { deleteCB(e.data); },
+        }
+      );
+    }
+
+    if(options.values!=null)
+    {
+      dialogOptions.values=jQuery.extend(dialogOptions.values, options.values);
+    }
+    else
+    {
+      dialogOptions.values.subCat='y';
+      dialogOptions.values.catIdList=0;
+    }
+    $('#iASECategorySubCat').val(dialogOptions.values.subCat);
+    $('#iASECategoryCategory').categorySelector('value', ':none');
+    $('#iASECategoryCategory').categorySelector('value', dialogOptions.values.catIdList);
+    $('#iASECategoryCategory').categorySelector('collapse', ':all');
+    for(var i=0;i<dialogOptions.values.catIdList.length;i++)
+    {
+      $('#iASECategoryCategory').categorySelector('expand', dialogOptions.values.catIdList[i]+'<');
+    }
+
+
+    $("#iDialogASECategoryChoose").dialog('open');
+  }
+
+
+
+  /**
+   * manage the 'edit' button from criteria builder interface
+   * @param String itemId : the itemId
+   */
+  var editCB = function (itemId)
+  {
+    extraData=dialogOptions.cBuilder.doAction('getExtraData', itemId);
+    showDialog(
+      {
+        id:itemId,
+        values:
+          {
+            subCat:extraData.param.subCat,
+            catIdList:extraData.param.catIdList,
+          },
+      }
+    );
+  }
+
+  /**
+   * manage the 'delete' button from criteria builder interface
+   * @param String itemId : the itemId
+   */
+  var deleteCB = function (itemId)
+  {
+    dialogOptions.cBuilder.doAction('delete', itemId);
+  }
+
+  /**
+   * set the content for the cBuilder item
+   */
+  var setCBuilderItem = function(id)
+  {
+    var content="<div>",
+        list=$('#iASECategoryCategory').categorySelector('name');
+
+    if(dialogOptions.values.catIdList.length==1)
+    {
+      content+="{/literal}{'ase_category'|@translate}{literal}";
+    }
+    else
+    {
+      content+="{/literal}{'ase_categories'|@translate}{literal}";
+    }
+
+    if(dialogOptions.values.subCat=='y')
+    {
+      content+="&nbsp;({/literal}{'ase_with_search_in_subcat'|@translate}{literal})";
+    }
+    content+="&nbsp:";
+
+
+    for(i=0;i<list.length;i++)
+    {
+      content+="<br>&nbsp;-&nbsp;"+list[i];
+    }
+
+    content+="</div>";
+
+
+    if(id=='')
+    {
+      //no id:add a new item in the list
+      dialogOptions.cBuilder.doAction(
+        'add',
+        content,
+        criteriaBuilder.makeExtendedData(
+          'ASECategory',
+          {
+            subCat:dialogOptions.values.subCat,
+            catIdList:dialogOptions.values.catIdList
+          }
+        )
+      );
+    }
+    else
+    {
+      // update item
+      dialogOptions.cBuilder.doAction(
+        'edit',
+        id,
+        content,
+        criteriaBuilder.makeExtendedData(
+          'ASECategory',
+          {
+            subCat:dialogOptions.values.subCat,
+            catIdList:dialogOptions.values.catIdList
+          }
+        )
+      );
+    }
+  }
+
+  initDialogBox();
+}
+
+
+</script>
+{/literal}
+
+<div id="iDialogASECategoryChoose" style='display:none;'>
+
+  <table class="formtable">
+    <tr>
+      <td>{'ase_categories'|@translate}</td>
+      <td>
+        <div id='iASECategoryCategory'></div>
+      </td>
+    </tr>
+
+    <tr>
+      <td>{'ase_searching_in_subcat'|@translate}</td>
+      <td>
+        <select id='iASECategorySubCat'>
+          <option value='y'>{'ase_y'|@translate}</option>
+          <option value='n'>{'ase_n'|@translate}</option>
+        </select>
+      </td>
+    </tr>
+  </table>
+
+</div>
+
+
Index: extensions/ASearchEngine/templates/ase_dialog_date_choose.tpl
===================================================================
--- extensions/ASearchEngine/templates/ase_dialog_date_choose.tpl	(revision 7196)
+++ extensions/ASearchEngine/templates/ase_dialog_date_choose.tpl	(revision 7196)
@@ -0,0 +1,429 @@
+{known_script id="jquery.ui" src=$ROOT_URL|@cat:"themes/default/js/ui/packed/ui.core.packed.js"}
+{known_script id="jquery.ui.dialog" src=$ROOT_URL|@cat:"themes/default/js/ui/packed/ui.dialog.packed.js"}
+{known_script id="jquery.ui.datepicker" src=$ROOT_URL|@cat:"themes/default/js/ui/packed/ui.datepicker.packed.js"}
+
+{assign var="datepicker_language" value="themes/default/js/ui/i18n/ui.datepicker-"|@cat:$lang_info.code|@cat:".js"}
+{if "PHPWG_ROOT_PATH"|@constant|@cat:$datepicker_language|@file_exists}
+{known_script id="jquery.ui.datepicker-$lang_info.code" src=$ROOT_URL|@cat:$datepicker_language}
+{/if}
+{html_head}
+<link rel="stylesheet" type="text/css" href="{$ROOT_URL}themes/default/js/ui/theme/ui.datepicker.css">
+{/html_head}
+
+{literal}
+<style type='text/css'>
+  #ui-datepicker-div {
+    z-index:1500;
+    display:none;
+  }
+</style>
+
+<script type="text/javascript">
+/**
+ * include this template in a page and use dialogChooseASEDateBox.show({options}) to display
+ * the dialog box
+ *
+ */
+dialogChooseASEDateBox = function()
+{
+  var dialogOptions = {
+      id:'',
+      eventOk:null,
+      cBuilder:null,
+
+      values: {
+        dateType:'c', //c:creation, a:available
+        from:'',
+        to:'',
+        searchType:'bt'
+      },
+    };
+
+  /**
+   * initialize the dialog box
+   */
+  var initDialogBox = function()
+  {
+    $("#iDialogASEDateChoose")
+    .dialog(
+      {
+        autoOpen: false,
+        resizable: false,
+        width:500,
+        height:180,
+        modal: true,
+        draggable:true,
+        dialogClass: 'gcBgTabSheet gcBorder',
+        title: '{/literal}{"ase_choose_date"|@translate}{literal}',
+        open: function(event, ui)
+        {
+        },
+        buttons:
+        {
+          '{/literal}{"ase_ok"|@translate}{literal}':
+            function()
+            {
+              if(checkValidity())
+              {
+                dialogOptions.values.dateType=$('[name=fASEDateDateType]:checked').val();
+                dialogOptions.values.from=$('#iASEDateFrom').val();
+                dialogOptions.values.to=$('#iASEDateTo').val();
+                dialogOptions.values.searchType=$('#iASEDateSearchType').val();
+
+                switch(dialogOptions.values.searchType)
+                {
+                  case 'gt':
+                  case 'eq':
+                    dialogOptions.values.to='';
+                    break;
+                  case 'lt':
+                    dialogOptions.values.from='';
+                    break;
+                }
+
+                if(dialogOptions.cBuilder!=null)
+                {
+                  setCBuilderItem(dialogOptions.id, dialogOptions.values);
+                }
+
+                if(dialogOptions.eventOk!=null)
+                {
+                  dialogOptions.eventOk(dialogOptions.id, dialogOptions.values);
+                }
+                $(this).dialog('close');
+              }
+            },
+          '{/literal}{"ase_cancel"|@translate}{literal}':
+            function()
+            {
+              $(this).dialog('close');
+            }
+        }
+      }
+    );
+
+    $("#iASEDateFrom").datepicker({dateFormat:'yy-mm-dd'});
+    $('#iASEDateTo').datepicker({dateFormat:'yy-mm-dd'});
+    $('#iASEDateSearchType').bind('change', changeSearchType);
+  }
+
+
+  /**
+   * called when the search type is changed
+   */
+  var changeSearchType = function ()
+  {
+    switch($('#iASEDateSearchType').val())
+    {
+      case 'bt':
+        $("#iASEDateFromRow").show();
+        $("#iASEDateToRow").show();
+        break;
+      case 'gt':
+      case 'eq':
+        $("#iASEDateFromRow").show();
+        $("#iASEDateToRow").hide();
+        break;
+      case 'lt':
+        $("#iASEDateFromRow").hide();
+        $("#iASEDateToRow").show();
+        break;
+    }
+  };
+
+
+  var isDate = function (s)
+  {
+    re=/\d{2,4}-\d\d-\d\d/i;
+    return((re.exec(s)!=null));
+  }
+
+  /**
+   * check the validity of the condition
+   * return Boolean : true if OK, otherwise false
+   */
+  var checkValidity = function ()
+  {
+    $(".error").removeClass('error');
+    returned=true;
+
+    switch($('#iASEDateSearchType').val())
+    {
+      case 'bt':
+        if(!isDate($("#iASEDateFrom").val() ))
+        {
+          $("#iASEDateFrom").addClass('error');
+          returned=false;
+          alert("{/literal}{'ase_error_date_from'|@translate}{literal}");
+        }
+        if(!isDate($("#iASEDateTo").val() ))
+        {
+          $("#iASEDateTo").addClass('error');
+          returned=false;
+          alert("{/literal}{'ase_error_date_to'|@translate}{literal}");
+        }
+        if(returned && $("#iASEDateFrom").val() > $("#iASEDateTo").val())
+        {
+          $("#iASEDateTo, #iASEDateFrom").addClass('error');
+          returned=false;
+          alert("{/literal}{'ase_error_period'|@translate}{literal}");
+        }
+        break;
+      case 'gt':
+        if(!isDate($("#iASEDateFrom").val() ))
+        {
+          $("#iASEDateFrom").addClass('error');
+          alert("{/literal}{'ase_error_date'|@translate}{literal}");
+          returned=false;
+        }
+        break;
+      case 'lt':
+        if(!isDate($("#iASEDateTo").val() ))
+        {
+          $("#iASEDateTo").addClass('error');
+          alert("{/literal}{'ase_error_date'|@translate}{literal}");
+          returned=false;
+        }
+        break;
+    }
+
+    return(returned);
+  }
+
+
+  /**
+   * the show() function display and manage a dialog box to choose categories
+   * and the kind of test to apply
+   *
+   * @param options : properties to manage the dialog box
+   *                  - id : a string to identify a DOM object ; this parameter
+   *                         is given to the callback when the OK button is pushed
+   *                  - values : an object with 3 properties
+   *                               - dateType : 'c' for creation or 'a' for available
+   *                               - from :
+   *                               - to :
+   *                  - eventOK : a callback function, with 2 parameters : id of
+   *                              the given DOM object and values parameted
+   *                  - cBuilder : a criteriaBuilder object
+   *                               if set, the dialog box manage automaticaly
+   *                               the criteria builder interface
+   */
+  this.show = function (options)
+  {
+    showDialog(options);
+  }
+
+  /**
+   * private function used to show the dialog box
+   */
+  var showDialog = function(options)
+  {
+    if(options.id!=null)
+    {
+      dialogOptions.id=options.id;
+    }
+    else
+    {
+      dialogOptions.id='';
+    }
+
+    if(options.eventOk!=null)
+    {
+      dialogOptions.eventOk=options.eventOk;
+    }
+
+    if(options.cBuilder!=null)
+    {
+      dialogOptions.cBuilder=options.cBuilder;
+      dialogOptions.cBuilder.doAction('setOptions',
+        {
+          onEdit:function (e) { editCB(e.data); },
+          onDelete:function (e) { deleteCB(e.data); },
+        }
+      );
+    }
+
+    if(options.values!=null)
+    {
+      dialogOptions.values=jQuery.extend(dialogOptions.values, options.values);
+    }
+    else
+    {
+      dialogOptions.values.dateType='c';
+      dialogOptions.values.from='';
+      dialogOptions.values.to='';
+      dialogOptions.values.searchType='bt';
+    }
+
+    if(dialogOptions.values.dateType=='c')
+    {
+      $('#iASEDateDateTypeC').get(0).checked=true;
+    }
+    else
+    {
+      $('#iASEDateDateTypeA').get(0).checked=true;
+    }
+    $('#iASEDateFrom').val(dialogOptions.values.from);
+    $('#iASEDateTo').val(dialogOptions.values.to);
+    $('#iASEDateSearchType').val(dialogOptions.values.searchType);
+
+    changeSearchType();
+
+    $("#iDialogASEDateChoose").dialog('open');
+  }
+
+
+
+  /**
+   * manage the 'edit' button from criteria builder interface
+   * @param String itemId : the itemId
+   */
+  var editCB = function (itemId)
+  {
+    extraData=dialogOptions.cBuilder.doAction('getExtraData', itemId);
+    showDialog(
+      {
+        id:itemId,
+        values:
+          {
+            dateType:extraData.param.dateType,
+            from:extraData.param.from,
+            to:extraData.param.from,
+            searchType:extraData.param.searchType
+          },
+      }
+    );
+  }
+
+  /**
+   * manage the 'delete' button from criteria builder interface
+   * @param String itemId : the itemId
+   */
+  var deleteCB = function (itemId)
+  {
+    dialogOptions.cBuilder.doAction('delete', itemId);
+  }
+
+  /**
+   * set the content for the cBuilder item
+   */
+  var setCBuilderItem = function(id)
+  {
+    var content="<div>{/literal}{'ase_the_date'|@translate}{literal} ";
+
+    if(dialogOptions.values.dateType=='c')
+    {
+      content+="{/literal}{'ase_image_shot'|@translate}{literal}&nbsp;";
+    }
+    else
+    {
+      content+="{/literal}{'ase_image_availability'|@translate}{literal}&nbsp;";
+    }
+
+    switch(dialogOptions.values.searchType)
+    {
+      case 'eq':
+        content+="{/literal}{'ase_is_equal_to'|@translate}{literal} "+dialogOptions.values.from;
+        break;
+      case 'bt':
+        content+="{/literal}{'ase_is_between'|@translate}{literal} "+dialogOptions.values.from+" {/literal}{'ase_is_between_and'|@translate}{literal} "+dialogOptions.values.to;
+        break;
+      case 'gt':
+        content+="{/literal}{'ase_is_greater_or_equal'|@translate}{literal} "+dialogOptions.values.from;
+        break;
+      case 'lt':
+        content+="{/literal}{'ase_is_less_or_equal'|@translate}{literal} "+dialogOptions.values.to;
+        break;
+    }
+    content+="</div>";
+
+
+    if(id=='')
+    {
+      //no id:add a new item in the list
+      dialogOptions.cBuilder.doAction(
+        'add',
+        content,
+        criteriaBuilder.makeExtendedData(
+          'ASEDate',
+          {
+            dateType:dialogOptions.values.dateType,
+            searchType:dialogOptions.values.searchType,
+            from:dialogOptions.values.from,
+            to:dialogOptions.values.to
+          }
+        )
+      );
+    }
+    else
+    {
+      // update item
+      dialogOptions.cBuilder.doAction(
+        'edit',
+        id,
+        content,
+        criteriaBuilder.makeExtendedData(
+          'ASEDate',
+          {
+            dateType:dialogOptions.values.dateType,
+            searchType:dialogOptions.values.searchType,
+            from:dialogOptions.values.from,
+            to:dialogOptions.values.to
+          }
+        )
+      );
+    }
+  }
+
+  initDialogBox();
+}
+
+
+</script>
+{/literal}
+
+<div id="iDialogASEDateChoose" style='display:none;'>
+
+  <table class="formtable">
+    <tr>
+      <td>{'ase_search_on_date'|@translate}</td>
+      <td>
+         <label><input type="radio" id="iASEDateDateTypeC" name='fASEDateDateType' value='c' >&nbsp;{'ase_image_shot'|@translate}</label><br>
+         <label><input type="radio" id="iASEDateDateTypeA" name='fASEDateDateType' value='a' >&nbsp;{'ase_image_availability'|@translate}</label>
+      </td>
+    </tr>
+
+
+    <tr>
+      <td>{'ase_the_date'|@translate}</td>
+      <td>
+        <select id="iASEDateSearchType">
+          <option value="eq">{'ase_is_equal_to'|@translate} ...</option>
+          <option value="bt">{'ase_is_between'|@translate} ... {'ase_is_between_and'|@translate} ...</option>
+          <option value="gt">{'ase_is_greater_or_equal'|@translate} ... </option>
+          <option value="lt">{'ase_is_less_or_equal'|@translate} ... </option>
+        </select>
+      </td>
+    </tr>
+
+
+    <tr id="iASEDateFromRow">
+      <td>&nbsp;</td>
+      <td>
+         <input type="text" id="iASEDateFrom">
+      </td>
+    </tr>
+
+    <tr id="iASEDateToRow">
+      <td>&nbsp;</td>
+      <td>
+         <input type="text" id="iASEDateTo">
+      </td>
+    </tr>
+
+
+  </table>
+
+</div>
+
+
Index: extensions/ASearchEngine/templates/ase_dialog_hd_choose.tpl
===================================================================
--- extensions/ASearchEngine/templates/ase_dialog_hd_choose.tpl	(revision 7196)
+++ extensions/ASearchEngine/templates/ase_dialog_hd_choose.tpl	(revision 7196)
@@ -0,0 +1,252 @@
+{known_script id="jquery.ui" src=$ROOT_URL|@cat:"themes/default/js/ui/packed/ui.core.packed.js"}
+{known_script id="jquery.ui.dialog" src=$ROOT_URL|@cat:"themes/default/js/ui/packed/ui.dialog.packed.js"}
+
+{literal}
+
+<script type="text/javascript">
+/**
+ * include this template in a page and use dialogChooseASEHDBox.show({options}) to display
+ * the dialog box
+ *
+ */
+dialogChooseASEHDBox = function()
+{
+  var dialogOptions = {
+      id:'',
+      eventOk:null,
+      cBuilder:null,
+
+      values: {
+        withHD:'y'
+      },
+    };
+
+  /**
+   * initialize the dialog box
+   */
+  var initDialogBox = function()
+  {
+    $("#iDialogASEHDChoose")
+    .dialog(
+      {
+        autoOpen: false,
+        resizable: false,
+        width:350,
+        height:100,
+        modal: true,
+        draggable:true,
+        dialogClass: 'gcBgTabSheet gcBorder',
+        title: '{/literal}{"ase_search_hd"|@translate}{literal}',
+        open: function(event, ui)
+        {
+        },
+        buttons:
+        {
+          '{/literal}{"ase_ok"|@translate}{literal}':
+            function()
+            {
+              if(checkValidity())
+              {
+                dialogOptions.values.withHD=$('[name=fASEHDWithHD]:checked').val();
+
+                if(dialogOptions.cBuilder!=null)
+                {
+                  setCBuilderItem(dialogOptions.id, dialogOptions.values);
+                }
+
+                if(dialogOptions.eventOk!=null)
+                {
+                  dialogOptions.eventOk(dialogOptions.id, dialogOptions.values);
+                }
+                $(this).dialog('close');
+              }
+            },
+          '{/literal}{"ase_cancel"|@translate}{literal}':
+            function()
+            {
+              $(this).dialog('close');
+            }
+        }
+      }
+    );
+  }
+
+  /**
+   * check the validity of the condition
+   * return Boolean : true if OK, otherwise false
+   */
+  var checkValidity = function ()
+  {
+    $(".error").removeClass('error');
+    returned=true;
+    return(returned);
+  }
+
+
+  /**
+   * the show() function display and manage a dialog box to choose categories
+   * and the kind of test to apply
+   *
+   * @param options : properties to manage the dialog box
+   *                  - id : a string to identify a DOM object ; this parameter
+   *                         is given to the callback when the OK button is pushed
+   *                  - values : an object with 3 properties
+   *                               - withHD : with our without HD picture
+   *                  - eventOK : a callback function, with 2 parameters : id of
+   *                              the given DOM object and values parameted
+   *                  - cBuilder : a criteriaBuilder object
+   *                               if set, the dialog box manage automaticaly
+   *                               the criteria builder interface
+   */
+  this.show = function (options)
+  {
+    showDialog(options);
+  }
+
+  /**
+   * private function used to show the dialog box
+   */
+  var showDialog = function(options)
+  {
+    if(options.id!=null)
+    {
+      dialogOptions.id=options.id;
+    }
+    else
+    {
+      dialogOptions.id='';
+    }
+
+    if(options.eventOk!=null)
+    {
+      dialogOptions.eventOk=options.eventOk;
+    }
+
+    if(options.cBuilder!=null)
+    {
+      dialogOptions.cBuilder=options.cBuilder;
+      dialogOptions.cBuilder.doAction('setOptions',
+        {
+          onEdit:function (e) { editCB(e.data); },
+          onDelete:function (e) { deleteCB(e.data); },
+        }
+      );
+    }
+
+    if(options.values!=null)
+    {
+      dialogOptions.values=jQuery.extend(dialogOptions.values, options.values);
+    }
+    else
+    {
+      dialogOptions.values.withHD='y';
+    }
+
+    $('#iASEHDWithHDY').attr('checked', dialogOptions.values.withHD=='y');
+    $('#iASEHDWithHDN').attr('checked', dialogOptions.values.withHD=='n');
+
+    $("#iDialogASEHDChoose").dialog('open');
+  }
+
+
+
+  /**
+   * manage the 'edit' button from criteria builder interface
+   * @param String itemId : the itemId
+   */
+  var editCB = function (itemId)
+  {
+    extraData=dialogOptions.cBuilder.doAction('getExtraData', itemId);
+    showDialog(
+      {
+        id:itemId,
+        values:
+          {
+            withHD:extraData.param.withHD,
+          },
+      }
+    );
+  }
+
+  /**
+   * manage the 'delete' button from criteria builder interface
+   * @param String itemId : the itemId
+   */
+  var deleteCB = function (itemId)
+  {
+    dialogOptions.cBuilder.doAction('delete', itemId);
+  }
+
+  /**
+   * set the content for the cBuilder item
+   */
+  var setCBuilderItem = function(id)
+  {
+    var content="<div>{/literal}{'ase_the_picture'|@translate}{literal}&nbsp;";
+
+    if(dialogOptions.values.withHD=='y')
+    {
+      content+="{/literal}{'ase_picture_with_hd'|@translate}{literal}";
+    }
+    else
+    {
+      content+="{/literal}{'ase_picture_without_hd'|@translate}{literal}";
+    }
+
+
+    content+="</div>";
+
+    if(id=='')
+    {
+      //no id:add a new item in the list
+      dialogOptions.cBuilder.doAction(
+        'add',
+        content,
+        criteriaBuilder.makeExtendedData(
+          'ASEHD',
+          {
+            withHD:dialogOptions.values.withHD,
+          }
+        )
+      );
+    }
+    else
+    {
+      // update item
+      dialogOptions.cBuilder.doAction(
+        'edit',
+        id,
+        content,
+        criteriaBuilder.makeExtendedData(
+          'ASEHD',
+          {
+            withHD:dialogOptions.values.withHD
+          }
+        )
+      );
+    }
+  }
+
+  initDialogBox();
+}
+
+
+</script>
+{/literal}
+
+<div id="iDialogASEHDChoose" style='display:none;'>
+
+  <table class="formtable">
+    <tr>
+      <td>{'ase_the_picture'|@translate}</td>
+      <td>
+        <label><input type="radio" id='iASEHDWithHDY' name="fASEHDWithHD" value='y'>&nbsp;{'ase_picture_with_hd'|@translate}<label><br>
+        <label><input type="radio" id='iASEHDWithHDN' name="fASEHDWithHD" value='n'>&nbsp;{'ase_picture_without_hd'|@translate}<label>
+      </td>
+    </tr>
+
+  </table>
+
+</div>
+
+
Index: extensions/ASearchEngine/templates/ase_dialog_keyword_choose.tpl
===================================================================
--- extensions/ASearchEngine/templates/ase_dialog_keyword_choose.tpl	(revision 7196)
+++ extensions/ASearchEngine/templates/ase_dialog_keyword_choose.tpl	(revision 7196)
@@ -0,0 +1,319 @@
+{known_script id="jquery.ui" src=$ROOT_URL|@cat:"themes/default/js/ui/packed/ui.core.packed.js"}
+{known_script id="jquery.ui.dialog" src=$ROOT_URL|@cat:"themes/default/js/ui/packed/ui.dialog.packed.js"}
+
+{literal}
+
+<script type="text/javascript">
+/**
+ * include this template in a page and use dialogChooseASEKeywordBox.show({options}) to display
+ * the dialog box
+ *
+ */
+dialogChooseASEKeywordBox = function()
+{
+  var dialogOptions = {
+      id:'',
+      eventOk:null,
+      cBuilder:null,
+
+      values: {
+        keyword:'',
+        optIgnoreCase:'y',
+        optWholeWords:'n',
+        searchName:'y',
+        searchDesc:'y',
+        searchFileName:'n'
+      },
+    };
+
+  /**
+   * initialize the dialog box
+   */
+  var initDialogBox = function()
+  {
+    $("#iDialogASEKeywordChoose")
+    .dialog(
+      {
+        autoOpen: false,
+        resizable: false,
+        width:500,
+        height:180,
+        modal: true,
+        draggable:true,
+        dialogClass: 'gcBgTabSheet gcBorder',
+        title: '{/literal}{"ase_search_keyword"|@translate}{literal}',
+        open: function(event, ui)
+        {
+        },
+        buttons:
+        {
+          '{/literal}{"ase_ok"|@translate}{literal}':
+            function()
+            {
+              if(checkValidity())
+              {
+                dialogOptions.values.keyword=$('#iASEKeywordKeyword').val();
+                dialogOptions.values.optIgnoreCase=$('#iASEKeywordIgnoreCase').attr('checked')?'y':'n';
+                dialogOptions.values.optWholeWords=$('#iASEKeywordWholeWords').attr('checked')?'y':'n';
+                dialogOptions.values.searchName=$('#iASEKeywordSearchName').attr('checked')?'y':'n';
+                dialogOptions.values.searchDesc=$('#iASEKeywordSearchDesc').attr('checked')?'y':'n';
+                dialogOptions.values.searchFileName=$('#iASEKeywordSearchFileName').attr('checked')?'y':'n';
+
+                if(dialogOptions.cBuilder!=null)
+                {
+                  setCBuilderItem(dialogOptions.id, dialogOptions.values);
+                }
+
+                if(dialogOptions.eventOk!=null)
+                {
+                  dialogOptions.eventOk(dialogOptions.id, dialogOptions.values);
+                }
+                $(this).dialog('close');
+              }
+            },
+          '{/literal}{"ase_cancel"|@translate}{literal}':
+            function()
+            {
+              $(this).dialog('close');
+            }
+        }
+      }
+    );
+  }
+
+  /**
+   * check the validity of the condition
+   * return Boolean : true if OK, otherwise false
+   */
+  var checkValidity = function ()
+  {
+    $(".error").removeClass('error');
+    returned=true;
+
+    if($('#iASEKeywordKeyword').val().length<3)
+    {
+      $("#iASEKeywordKeyword").addClass('error');
+      alert("{/literal}{'ase_error_keyword_length'|@translate}{literal}");
+      returned=false;
+    }
+
+    if(!$('#iASEKeywordSearchName').attr('checked') &&
+       !$('#iASEKeywordSearchDesc').attr('checked') &&
+       !$('#iASEKeywordSearchFileName').attr('checked'))
+    {
+      $("#iASEKeywordSearchName, #iASEKeywordSearchDesc, #iASEKeywordSearchFileName").parent().addClass('error');
+      alert("{/literal}{'ase_error_no_target'|@translate}{literal}");
+      returned=false;
+    }
+
+    return(returned);
+  }
+
+
+  /**
+   * the show() function display and manage a dialog box to choose categories
+   * and the kind of test to apply
+   *
+   * @param options : properties to manage the dialog box
+   *                  - id : a string to identify a DOM object ; this parameter
+   *                         is given to the callback when the OK button is pushed
+   *                  - values : an object with 3 properties
+   *                               - keyword : the keyword to find
+   *                               - optIgnoreCase : ignore case or not
+   *                               - optWholeWords : search whol words only or not
+   *                               - searchName : search inside picture name
+   *                               - searchDesc : search inside picture desc
+   *                               - searchFileName : search inside picture filename
+   *                  - eventOK : a callback function, with 2 parameters : id of
+   *                              the given DOM object and values parameted
+   *                  - cBuilder : a criteriaBuilder object
+   *                               if set, the dialog box manage automaticaly
+   *                               the criteria builder interface
+   */
+  this.show = function (options)
+  {
+    showDialog(options);
+  }
+
+  /**
+   * private function used to show the dialog box
+   */
+  var showDialog = function(options)
+  {
+    if(options.id!=null)
+    {
+      dialogOptions.id=options.id;
+    }
+    else
+    {
+      dialogOptions.id='';
+    }
+
+    if(options.eventOk!=null)
+    {
+      dialogOptions.eventOk=options.eventOk;
+    }
+
+    if(options.cBuilder!=null)
+    {
+      dialogOptions.cBuilder=options.cBuilder;
+      dialogOptions.cBuilder.doAction('setOptions',
+        {
+          onEdit:function (e) { editCB(e.data); },
+          onDelete:function (e) { deleteCB(e.data); },
+        }
+      );
+    }
+
+    if(options.values!=null)
+    {
+      dialogOptions.values=jQuery.extend(dialogOptions.values, options.values);
+    }
+    else
+    {
+      dialogOptions.values.keyword='';
+      dialogOptions.values.optIgnoreCase='y';
+      dialogOptions.values.optWholeWords='n';
+      dialogOptions.values.searchName='y';
+      dialogOptions.values.searchDesc='y';
+      dialogOptions.values.searchFileName='n';
+    }
+
+    $('#iASEKeywordKeyword').val(dialogOptions.values.keyword);
+    $('#iASEKeywordIgnoreCase').attr('checked', dialogOptions.values.optIgnoreCase=='y');
+    $('#iASEKeywordWholeWords').attr('checked', dialogOptions.values.optWholeWords=='y');
+    $('#iASEKeywordSearchName').attr('checked', dialogOptions.values.searchName=='y');
+    $('#iASEKeywordSearchDesc').attr('checked', dialogOptions.values.searchDesc=='y');
+    $('#iASEKeywordSearchFileName').attr('checked', dialogOptions.values.searchFileName=='y');
+
+
+    $("#iDialogASEKeywordChoose").dialog('open');
+  }
+
+
+
+  /**
+   * manage the 'edit' button from criteria builder interface
+   * @param String itemId : the itemId
+   */
+  var editCB = function (itemId)
+  {
+    extraData=dialogOptions.cBuilder.doAction('getExtraData', itemId);
+    showDialog(
+      {
+        id:itemId,
+        values:
+          {
+            keyword:extraData.param.keyword,
+            optIgnoreCase:extraData.param.optIgnoreCase,
+            optWholeWords:extraData.param.optWholeWords,
+            searchName:extraData.param.searchName,
+            searchDesc:extraData.param.searchDesc,
+            searchFileName:extraData.param.searchFileName
+          },
+      }
+    );
+  }
+
+  /**
+   * manage the 'delete' button from criteria builder interface
+   * @param String itemId : the itemId
+   */
+  var deleteCB = function (itemId)
+  {
+    dialogOptions.cBuilder.doAction('delete', itemId);
+  }
+
+  /**
+   * set the content for the cBuilder item
+   */
+  var setCBuilderItem = function(id)
+  {
+    var content="<div>{/literal}{'ase_search_the_keyword'|@translate}{literal}&nbsp;";
+
+    content+="\"<span style='font-weight:bold'>"+dialogOptions.values.keyword+"</span>\"&nbsp:";
+
+    if(dialogOptions.values.searchName=='y') content+="<br>&nbsp;-&nbsp;{/literal}{'ase_search_into_name'|@translate}{literal}";
+    if(dialogOptions.values.searchDesc=='y') content+="<br>&nbsp;-&nbsp;{/literal}{'ase_search_into_desc'|@translate}{literal}";
+    if(dialogOptions.values.searchFileName=='y') content+="<br>&nbsp;-&nbsp;{/literal}{'ase_search_into_filename'|@translate}{literal}";
+
+    if(dialogOptions.values.optIgnoreCase=='y') content+="<br>&nbsp;-&nbsp;{/literal}{'ase_search_with_case_ignored'|@translate}{literal}";
+    if(dialogOptions.values.optWholeWords=='y') content+="<br>&nbsp;-&nbsp;{/literal}{'ase_search_with_whole_words'|@translate}{literal}";
+
+
+    content+="</div>";
+
+    if(id=='')
+    {
+      //no id:add a new item in the list
+      dialogOptions.cBuilder.doAction(
+        'add',
+        content,
+        criteriaBuilder.makeExtendedData(
+          'ASEKeyword',
+          {
+            keyword:dialogOptions.values.keyword,
+            optIgnoreCase:dialogOptions.values.optIgnoreCase,
+            optWholeWords:dialogOptions.values.optWholeWords,
+            searchName:dialogOptions.values.searchName,
+            searchDesc:dialogOptions.values.searchDesc,
+            searchFileName:dialogOptions.values.searchFileName
+          }
+        )
+      );
+    }
+    else
+    {
+      // update item
+      dialogOptions.cBuilder.doAction(
+        'edit',
+        id,
+        content,
+        criteriaBuilder.makeExtendedData(
+          'ASEKeyword',
+          {
+            keyword:dialogOptions.values.keyword,
+            optIgnoreCase:dialogOptions.values.optIgnoreCase,
+            optWholeWords:dialogOptions.values.optWholeWords,
+            searchName:dialogOptions.values.searchName,
+            searchDesc:dialogOptions.values.searchDesc,
+            searchFileName:dialogOptions.values.searchFileName
+          }
+        )
+      );
+    }
+  }
+
+  initDialogBox();
+}
+
+
+</script>
+{/literal}
+
+<div id="iDialogASEKeywordChoose" style='display:none;'>
+
+  <table class="formtable">
+    <tr>
+      <td>{'ase_keyword'|@translate}</td>
+      <td>
+        <input type="text" id="iASEKeywordKeyword"><br>
+        <label><input type="checkbox" id='iASEKeywordIgnoreCase'>&nbsp;{'ase_ignore_case'|@translate}<label><br>
+        <label><input type="checkbox" id='iASEKeywordWholeWords'>&nbsp;{'ase_whole_words_only'|@translate}<label>
+      </td>
+    </tr>
+
+    <tr>
+      <td>{'ase_search_into'|@translate}</td>
+      <td>
+        <label><input type="checkbox" id='iASEKeywordSearchName'>&nbsp;{'ase_picture_name'|@translate}<label><br>
+        <label><input type="checkbox" id='iASEKeywordSearchDesc'>&nbsp;{'ase_picture_desc'|@translate}<label><br>
+        <label><input type="checkbox" id='iASEKeywordSearchFileName'>&nbsp;{'ase_picture_filename'|@translate}<label>
+      </td>
+    </tr>
+
+  </table>
+
+</div>
+
+
Index: extensions/ASearchEngine/templates/ase_dialog_rate_choose.tpl
===================================================================
--- extensions/ASearchEngine/templates/ase_dialog_rate_choose.tpl	(revision 7196)
+++ extensions/ASearchEngine/templates/ase_dialog_rate_choose.tpl	(revision 7196)
@@ -0,0 +1,376 @@
+{known_script id="jquery.ui" src=$ROOT_URL|@cat:"themes/default/js/ui/packed/ui.core.packed.js"}
+{known_script id="jquery.ui.dialog" src=$ROOT_URL|@cat:"themes/default/js/ui/packed/ui.dialog.packed.js"}
+
+{literal}
+<style type='text/css'>
+</style>
+
+<script type="text/javascript">
+/**
+ * include this template in a page and use dialogChooseASERateBox.show({options}) to display
+ * the dialog box
+ *
+ */
+dialogChooseASERateBox = function()
+{
+  var dialogOptions = {
+      id:'',
+      eventOk:null,
+      cBuilder:null,
+
+      values: {
+        minValue:'',
+        maxValue:'',
+        searchType:'no'
+      },
+    };
+
+  /**
+   * initialize the dialog box
+   */
+  var initDialogBox = function()
+  {
+    $("#iDialogASERateChoose")
+    .dialog(
+      {
+        autoOpen: false,
+        resizable: false,
+        width:500,
+        height:180,
+        modal: true,
+        draggable:true,
+        dialogClass: 'gcBgTabSheet gcBorder',
+        title: '{/literal}{"ase_choose_rate"|@translate}{literal}',
+        open: function(event, ui)
+        {
+        },
+        buttons:
+        {
+          '{/literal}{"ase_ok"|@translate}{literal}':
+            function()
+            {
+              if(checkValidity())
+              {
+                dialogOptions.values.minValue=$('#iASERateMinValue').val();
+                dialogOptions.values.maxValue=$('#iASERateMaxValue').val();
+                dialogOptions.values.searchType=$('#iASERateSearchType').val();
+
+                switch(dialogOptions.values.searchType)
+                {
+                  case 'gt':
+                  case 'eq':
+                    dialogOptions.values.maxValue='';
+                    break;
+                  case 'lt':
+                    dialogOptions.values.minValue='';
+                    break;
+                }
+
+                if(dialogOptions.cBuilder!=null)
+                {
+                  setCBuilderItem(dialogOptions.id, dialogOptions.values);
+                }
+
+                if(dialogOptions.eventOk!=null)
+                {
+                  dialogOptions.eventOk(dialogOptions.id, dialogOptions.values);
+                }
+                $(this).dialog('close');
+              }
+            },
+          '{/literal}{"ase_cancel"|@translate}{literal}':
+            function()
+            {
+              $(this).dialog('close');
+            }
+        }
+      }
+    );
+
+    $('#iASERateSearchType').bind('change', changeSearchType);
+  }
+
+
+  /**
+   * called when the search type is changed
+   */
+  var changeSearchType = function ()
+  {
+    switch($('#iASERateSearchType').val())
+    {
+      case 'no':
+        $("#iASERateMinValueRow").hide();
+        $("#iASERateMaxValueRow").hide();
+        break;
+      case 'bt':
+        $("#iASERateMinValueRow").show();
+        $("#iASERateMaxValueRow").show();
+        break;
+      case 'gt':
+      case 'eq':
+        $("#iASERateMinValueRow").show();
+        $("#iASERateMaxValueRow").hide();
+        break;
+      case 'lt':
+        $("#iASERateMinValueRow").hide();
+        $("#iASERateMaxValueRow").show();
+        break;
+    }
+  };
+
+
+  var isDate = function (s)
+  {
+    re=/\d{2,4}-\d\d-\d\d/i;
+    return((re.exec(s)!=null));
+  }
+
+  /**
+   * check the validity of the condition
+   * return Boolean : true if OK, otherwise false
+   */
+  var checkValidity = function ()
+  {
+    $(".error").removeClass('error');
+    returned=true;
+
+    if($('#iASERateSearchType').val()=='bt')
+    {
+      if($("#iASERateMinValue").val() > $("#iASERateMaxValue").val())
+      {
+        $("#iASERateMinValue, #iASERateMaxValue").addClass('error');
+        returned=false;
+        alert("{/literal}{'ase_error_rate_range'|@translate}{literal}");
+      }
+    }
+
+    return(returned);
+  }
+
+
+  /**
+   * the show() function display and manage a dialog box to choose categories
+   * and the kind of test to apply
+   *
+   * @param options : properties to manage the dialog box
+   *                  - id : a string to identify a DOM object ; this parameter
+   *                         is given to the callback when the OK button is pushed
+   *                  - values : an object with 3 properties
+   *                               - dateType : 'c' for creation or 'a' for available
+   *                               - from :
+   *                               - to :
+   *                  - eventOK : a callback function, with 2 parameters : id of
+   *                              the given DOM object and values parameted
+   *                  - cBuilder : a criteriaBuilder object
+   *                               if set, the dialog box manage automaticaly
+   *                               the criteria builder interface
+   */
+  this.show = function (options)
+  {
+    showDialog(options);
+  }
+
+  /**
+   * private function used to show the dialog box
+   */
+  var showDialog = function(options)
+  {
+    if(options.id!=null)
+    {
+      dialogOptions.id=options.id;
+    }
+    else
+    {
+      dialogOptions.id='';
+    }
+
+    if(options.eventOk!=null)
+    {
+      dialogOptions.eventOk=options.eventOk;
+    }
+
+    if(options.cBuilder!=null)
+    {
+      dialogOptions.cBuilder=options.cBuilder;
+      dialogOptions.cBuilder.doAction('setOptions',
+        {
+          onEdit:function (e) { editCB(e.data); },
+          onDelete:function (e) { deleteCB(e.data); },
+        }
+      );
+    }
+
+    if(options.values!=null)
+    {
+      dialogOptions.values=jQuery.extend(dialogOptions.values, options.values);
+    }
+    else
+    {
+      dialogOptions.values.maxValue='5';
+      dialogOptions.values.minValue='0';
+      dialogOptions.values.searchType='no';
+    }
+
+    $('#iASERateMinValue').val(dialogOptions.values.minValue);
+    $('#iASERateMaxValue').val(dialogOptions.values.maxValue);
+    $('#iASERateSearchType').val(dialogOptions.values.searchType);
+
+    changeSearchType();
+
+    $("#iDialogASERateChoose").dialog('open');
+  }
+
+
+
+  /**
+   * manage the 'edit' button from criteria builder interface
+   * @param String itemId : the itemId
+   */
+  var editCB = function (itemId)
+  {
+    extraData=dialogOptions.cBuilder.doAction('getExtraData', itemId);
+    showDialog(
+      {
+        id:itemId,
+        values:
+          {
+            maxValue:extraData.param.maxValue,
+            minValue:extraData.param.minValue,
+            searchType:extraData.param.searchType
+          },
+      }
+    );
+  }
+
+  /**
+   * manage the 'delete' button from criteria builder interface
+   * @param String itemId : the itemId
+   */
+  var deleteCB = function (itemId)
+  {
+    dialogOptions.cBuilder.doAction('delete', itemId);
+  }
+
+  /**
+   * set the content for the cBuilder item
+   */
+  var setCBuilderItem = function(id)
+  {
+    var content="<div>{/literal}{'ase_the_rate'|@translate}{literal} ";
+
+    switch(dialogOptions.values.searchType)
+    {
+      case 'no':
+        content="<div>{/literal}{'ase_Dont_have_rate'|@translate}{literal} ";
+        break;
+      case 'eq':
+        content+="{/literal}{'ase_is_equal2'|@translate}{literal} "+dialogOptions.values.minValue;
+        break;
+      case 'bt':
+        content+="{/literal}{'ase_is_between2'|@translate}{literal} "+dialogOptions.values.minValue+" {/literal}{'ase_is_between_and'|@translate}{literal} "+dialogOptions.values.maxValue;
+        break;
+      case 'gt':
+        content+="{/literal}{'ase_is_greater_or_equal2'|@translate}{literal} "+dialogOptions.values.minValue;
+        break;
+      case 'lt':
+        content+="{/literal}{'ase_is_less_or_equal2'|@translate}{literal} "+dialogOptions.values.maxValue;
+        break;
+    }
+
+    content+="</div>";
+
+
+    if(id=='')
+    {
+      //no id:add a new item in the list
+      dialogOptions.cBuilder.doAction(
+        'add',
+        content,
+        criteriaBuilder.makeExtendedData(
+          'ASERate',
+          {
+            searchType:dialogOptions.values.searchType,
+            minValue:dialogOptions.values.minValue,
+            maxValue:dialogOptions.values.maxValue
+          }
+        )
+      );
+    }
+    else
+    {
+      // update item
+      dialogOptions.cBuilder.doAction(
+        'edit',
+        id,
+        content,
+        criteriaBuilder.makeExtendedData(
+          'ASERate',
+          {
+            searchType:dialogOptions.values.searchType,
+            minValue:dialogOptions.values.minValue,
+            maxValue:dialogOptions.values.maxValue
+          }
+        )
+      );
+    }
+  }
+
+  initDialogBox();
+}
+
+
+</script>
+{/literal}
+
+<div id="iDialogASERateChoose" style='display:none;'>
+
+  <table class="formtable">
+
+    <tr>
+      <td>{'ase_the_rate'|@translate}</td>
+      <td>
+        <select id="iASERateSearchType">
+          <option value="no">{'ase_dont_have_rate'|@translate}</option>
+          <option value="eq">{'ase_is_equal2'|@translate} ...</option>
+          <option value="bt">{'ase_is_between2'|@translate} ... {'ase_is_between_and2'|@translate} ...</option>
+          <option value="gt">{'ase_is_greater_or_equal2'|@translate} ... </option>
+          <option value="lt">{'ase_is_less_or_equal2'|@translate} ... </option>
+        </select>
+      </td>
+    </tr>
+
+
+    <tr id="iASERateMinValueRow">
+      <td>&nbsp;</td>
+      <td>
+        <select id="iASERateMinValue">
+          <option value="0">0</option>
+          <option value="1">1</option>
+          <option value="2">2</option>
+          <option value="3">3</option>
+          <option value="4">4</option>
+          <option value="5">5</option>
+        </select>
+      </td>
+    </tr>
+
+    <tr id="iASERateMaxValueRow">
+      <td>&nbsp;</td>
+      <td>
+        <select id="iASERateMaxValue">
+          <option value="0">0</option>
+          <option value="1">1</option>
+          <option value="2">2</option>
+          <option value="3">3</option>
+          <option value="4">4</option>
+          <option value="5">5</option>
+        </select>
+      </td>
+    </tr>
+
+
+  </table>
+
+</div>
+
+
