Index: /extensions/ColorStat/admin/cstat_config.tpl
===================================================================
--- /extensions/ColorStat/admin/cstat_config.tpl	(revision 6106)
+++ /extensions/ColorStat/admin/cstat_config.tpl	(revision 6107)
@@ -1,1 +1,97 @@
+{known_script id="jquery.ui" src=$ROOT_URL|@cat:"themes/default/js/ui/packed/ui.core.packed.js"}
+{known_script id="jquery.ui.slider" src=$ROOT_URL|@cat:"themes/default/js/ui/packed/ui.slider.packed.js"}
+
+
+{literal}
+<style>
+ .ui-slider {
+    width:600px;
+    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;
+  }
+</style>
+<script type="text/javascript">
+
+
+  function init()
+  {
+    formatPct({/literal}{$datas.minPct}{literal});
+    $("#icstat_stat_minPct_slider").slider(
+      {
+        min:0.5,
+        max:60,
+        step:0.25,
+        value:{/literal}{$datas.minPct}{literal},
+        slide: function(event, ui) { formatPct(ui.value); }
+      });
+    $("#icstat_stat_minPct_slider a").addClass('gcBgInput');
+  }
+
+  function formatPct(pct)
+  {
+    $("#icstat_stat_minPct").val(pct);
+    $("#icstat_stat_minPct_display").html(pct.toFixed(2)+"%");
+  }
+</script>
+{/literal}
+
+
+
 <h2>{'cstat_config_plugin'|@translate}</h2>
+
+<form id="iConfig" method="post" action="" class="general">
+
+  <fieldset>
+    <legend>{'cstat_stat_and_search'|@translate}</legend>
+
+    <table class="formtable">
+      <tr>
+        <td colspan="2">{'cstat_percent_min_significant'|@translate}</td>
+      </tr>
+      <tr>
+        <td>
+          <input type="hidden" name="f_stat_minPct" id="icstat_stat_minPct" value="{$datas.minPct}">
+          <div id="icstat_stat_minPct_slider" class="gcBgInput gcBorderInput"></div>
+        </td>
+        <td width="90px">
+          <div id="icstat_stat_minPct_display"></div>
+        </td>
+      </tr>
+    </table>
+
+  </fieldset>
+
+
+  <fieldset>
+    <legend>{'cstat_gallery_integration'|@translate}</legend>
+
+    <label>
+      <input type="checkbox" id='idisplay_gallery_showColorsCBox' onclick="$('#idisplay_gallery_showColors').val(($('#idisplay_gallery_showColorsCBox').get(0).checked=='on')?'y':'n');"  {if $datas.showColors=='y'}checked{/if} >
+      {'cstat_display_colors_on_image'|@translate}
+      <input type="hidden" id='idisplay_gallery_showColors' name='f_display_gallery_showColors' value='{$datas.showColors}'>
+    </label>
+
+  </fieldset>
+
+
+
+  <input type="submit" value="{'cstat_apply'|@translate}" name="submit_save_config" style="margin-left:1em;" >
+
+</form>
+
+
+<script type="text/javascript">
+  init();
+</script>
Index: /extensions/ColorStat/admin/cstat_database.tpl
===================================================================
--- /extensions/ColorStat/admin/cstat_database.tpl	(revision 6106)
+++ /extensions/ColorStat/admin/cstat_database.tpl	(revision 6107)
@@ -1,5 +1,4 @@
 {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}
@@ -60,5 +59,5 @@
 
 
-    doAnalyze="<br><form id='iDialogProgress' class='formtable'>"+
+    doAnalyzeDialog="<br><form id='iDialogProgress' class='formtable'>"+
       "<div id='iprogressbar_contener' class='gcBorderInput'>"+
       "<span id='iprogressbar_bg' class='gcBgInput' style='width:0%;'>&nbsp;</span>"+
@@ -81,5 +80,5 @@
         title: '{/literal}{"cstat_updating_database"|@translate}{literal}&nbsp;('+modeLabel+')',
       }
-    ).html(doAnalyze);
+    ).html(doAnalyzeDialog);
 
     NumberOfItemsPerRequest=$("#iNumberOfItemsPerRequest").val();
Index: /extensions/ColorStat/admin/cstat_install_page.tpl
===================================================================
--- /extensions/ColorStat/admin/cstat_install_page.tpl	(revision 6106)
+++ /extensions/ColorStat/admin/cstat_install_page.tpl	(revision 6107)
@@ -1,5 +1,20 @@
+{known_script id="jquery.ui" src=$ROOT_URL|@cat:"themes/default/js/ui/packed/ui.core.packed.js"}
+{known_script id="jquery.tipTip" src=$ROOT_URL|@cat:"themes/default/js/plugins/jquery.tipTip.minified.js" }
+
 {literal}
 <script type="text/javascript">
 var tableSize='small';
+
+  function init()
+  {
+    $('.tiptip').tipTip(
+      {
+        'delay' : 0,
+        'fadeIn' : 0,
+        'fadeOut' : 0,
+        'edgeOffset' : 5,
+      }
+    );
+  }
 
   function displayTable(size)
@@ -52,5 +67,5 @@
       <table>
         <tr>
-          <td style="min-width:450px;">{$smallTableColor}</td>
+          <td style="min-width:350px;">{$smallTableColor}</td>
 
           <td style='padding-left:30px;vertical-align:top;'>
@@ -85,5 +100,5 @@
       <table>
         <tr>
-          <td style="min-width:450px;">{$largeTableColor}</td>
+          <td style="min-width:350px;">{$largeTableColor}</td>
 
           <td style='padding-left:30px;vertical-align:top;'>
@@ -121,4 +136,6 @@
 </form>
 
+<script type="text/javascript">
+  init();
+</script>
 
-
Index: /extensions/ColorStat/admin/cstat_search.tpl
===================================================================
--- /extensions/ColorStat/admin/cstat_search.tpl	(revision 6106)
+++ /extensions/ColorStat/admin/cstat_search.tpl	(revision 6107)
@@ -1,1 +1,284 @@
+{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.tipTip" src=$ROOT_URL|@cat:"themes/default/js/plugins/jquery.tipTip.minified.js"}
+
+{known_script id="gpc.pagesNavigator" src=$ROOT_URL|@cat:"plugins/GrumPluginClasses/js/pagesNavigator.js"}
+
+
+{literal}
+<script type="text/javascript">
+var cb=null;
+
+  interfaceManager = function(optionsToSet)
+  {
+    var pn=null;
+    var requestNumber=0;
+
+    options =
+      {
+        requestCriterionsVisible:'',
+        requestCriterionsHidden:'',
+        requestResult:'',
+        requestResultContent:'',
+        requestResultNfo:'',
+        requestResultPagesNavigator:'',
+        requestResultRequestNumber:0,
+        onPageChange:null,
+        numberPerPage:30,
+      };
+
+    /**
+     *
+     */
+    this.doAction = function(fct)
+    {
+      switch(fct)
+      {
+        case 'queryResult':
+          /* function 'queryResult' : when query is executed, prepare the interface
+           */
+          if(arguments.length==3)
+          {
+            displayQueryResult(arguments[1], arguments[2]);
+          }
+          break;
+        case 'queryPage':
+          /* function 'queryPage' : display returned page
+           */
+          if(arguments.length==3)
+          {
+            displayQueryPage(arguments[1], arguments[2]);
+          }
+          break;
+        case 'show':
+          /* function 'show' : show/hide the query/result
+           */
+          if(arguments.length==2)
+          {
+            show(arguments[1]);
+          }
+          break;
+        case 'setOptions':
+          /* function 'setOptions' : allows to set options after the object was
+           *                         created
+           */
+          if(arguments.length==2)
+          {
+            setOptions(arguments[1]);
+          }
+          break;
+      }
+    }
+
+    /**
+     * returns the current request number
+     */
+    this.getRequestNumber = function ()
+    {
+      return(requestNumber);
+    }
+
+    /**
+     * returns the number of items per page
+     */
+    this.getNumberPerPage = function ()
+    {
+      return(options.numberPerPage);
+    }
+
+    /**
+     * this function show/hide the different panels
+     *  'buildQuery'  : hide the result panel and display the panel to build query
+     *  'resultQuery' : hide the panel to build query and display the result panel
+     */
+    var show = function(mode)
+    {
+      switch(mode)
+      {
+        case 'buildQuery':
+          $('.'+options.requestCriterionsVisible).css('display', 'block');
+          $('.'+options.requestCriterionsHidden).css('display', 'none');
+          $('.'+options.requestResult).css('display', 'none');
+          break;
+        case 'resultQuery':
+          $('#iResultQueryContent').html("<br><img src='./plugins/GrumPluginClasses/icons/processing.gif'>");
+          $('.'+options.requestCriterionsVisible).css('display', 'none');
+          $('.'+options.requestCriterionsHidden).css('display', 'block');
+          $('.'+options.requestResult).css('display', 'block');
+          break;
+      }
+    }
+
+    /**
+     * this function display the number of items found and prepare the page
+     * navigator
+     *
+     * @param String nfo : 2 information separated with a semi-colon ';'
+     *                      requestNumber;numberOfItems
+     */
+    var displayQueryResult = function (isSuccess, nfo)
+    {
+      if(isSuccess)
+      {
+        nfo=nfo.split(';');
+
+        requestNumber=nfo[0];
+        $('#iResultQueryNfo').html(nfo[1]);
+        pn.doAction('setOptions', { numberItem:nfo[1], defaultPage:1 } );
+        show('resultQuery');
+      }
+      else
+      {
+        //$('#'+options.requestResultContent).html("");
+        show('buildQuery');
+        alert('Something is wrong on the server-side !');
+      }
+    }
+
+
+    /**
+     * this function display the number of items found and prepare the page
+     * navigator
+     *
+     * @param String nfo : 2 information separated with a semi-colon ';'
+     *                      requestNumber;numberOfItems
+     */
+    var displayQueryPage = function (isSuccess, nfo)
+    {
+      if(isSuccess)
+      {
+        $('#iResultQueryContent').html(nfo);
+      }
+      else
+      {
+        alert('Something is wrong on the server-side !');
+      }
+    }
+
+
+    /**
+     *
+     * @param Object optionsToSet : set the given options
+     */
+    var setOptions = function(optionsToSet)
+    {
+      if(typeof optionsToSet=='object')
+      {
+        options = jQuery.extend(options, optionsToSet);
+      }
+    }
+
+    /**
+     * initialize the object
+     */
+    var init = function (optionsToSet)
+    {
+      setOptions(optionsToSet);
+
+      pn = new pagesNavigator(options.requestResultPagesNavigator,
+        {
+          itemPerPage:options.numberPerPage,
+          displayNumPage:9,
+          classActive:'pnActive{/literal}{$datas.themeName}{literal}',
+          classInactive:'pnInactive{/literal}{$datas.themeName}{literal}',
+          onPageChange: function (page)
+            {
+              if(options.onPageChange!=null && jQuery.isFunction(options.onPageChange))
+              {
+                options.onPageChange(requestNumber, page, options.numberPerPage);
+              }
+            },
+        }
+      );
+
+      requestNumber=options.requestResultRequestNumber;
+    }
+
+    init(optionsToSet);
+  }
+
+
+  function init()
+  {
+    im = new interfaceManager(
+      {
+        requestCriterionsVisible:'cRequestCriterions',
+        requestCriterionsHidden:'cModifyRequest',
+        requestResult:'cResultQuery',
+        requestResultContent:'iResultQueryContent',
+        requestResultNfo:'iResultQueryNfo',
+        requestResultPagesNavigator:'iPagesNavigator',
+      }
+    );
+
+    requestBuilderOptions.imgEditUrl='{/literal}{$ROOT_URL}{$themeconf.admin_icon_dir}{literal}/edit_s.png';
+    requestBuilderOptions.imgDeleteUrl='{/literal}{$ROOT_URL}{$themeconf.admin_icon_dir}{literal}/delete.png';
+    requestBuilderOptions.classGroup='gcBorderInput gcTextInput';
+    requestBuilderOptions.classItem='gcBgInput gcTextInput';
+    requestBuilderOptions.classOperator='cbOperator cbOperatorBg{/literal}{$datas.themeName}{literal} gcLinkHover';
+    requestBuilderOptions.onRequestSuccess = function (msg) { im.doAction('queryResult', true, msg); cb.doAction('getPage', im.getRequestNumber(), 1, im.getNumberPerPage()); };
+    requestBuilderOptions.onRequestError = function (msg) { im.doAction('queryResult', false, msg); };
+    requestBuilderOptions.onGetPageSuccess = function (msg) { im.doAction('queryPage', true, msg); };
+    requestBuilderOptions.onGetPageError = function (msg) { im.doAction('queryPage', false, msg); };
+
+    cb = new criteriaBuilder('iListColorsChoosen', requestBuilderOptions);
+
+    im.doAction('setOptions',
+      { onPageChange:
+          function (requestNumber, page, numberPerPage)
+          {
+            $('#iResultQueryContent').html("<br><img src='./plugins/GrumPluginClasses/icons/processing.gif'>");
+            cb.doAction('getPage', requestNumber, page, numberPerPage);
+          }
+      }
+    );
+
+  }
+
+
+
+</script>
+{/literal}
+
+{$datas.dialogBox}
+
 <h2>{'cstat_search_by_color'|@translate}</h2>
+
+<form>
+  <fieldset>
+    <legend>{'cstat_search_criterion'|@translate}</legend>
+
+    <div id='iRequestCriterions' class='cRequestCriterions'>
+      <div style='width:100%;min-height:250px;margin-bottom:8px;'>
+        <ul id='iListColorsChoosen'>
+        </ul>
+      </div>
+
+      <div class='gcBgInput cbButtons'>{literal}<a onclick="colorBox.show({cBuilder:cb});">{/literal}{'cstat_add_colors'|@translate}</a></div>
+      <div class='gcBgInput cbButtons'>{literal}<a onclick="cb.doAction('clear');">{/literal}{'cstat_clear_colors'|@translate}</a></div>
+    </div>
+    <div class='cModifyRequest' style='display:none;'>
+      <div class='gcBgInput cbButtons'>{literal}<a onclick="im.doAction('show', 'buildQuery');">{/literal}{'cstat_do_modify_request'|@translate}</a></div>
+    </div>
+
+  </fieldset>
+
+  <input type="button" class='cRequestCriterions' style="margin-left:1em;" onclick="cb.doAction('send');" value="{'cstat_search'|@translate}">
+</form>
+
+  <fieldset id='iResultQuery' style='display:none;' class='cResultQuery'>
+    <legend>{'cstat_result_query'|@translate}</legend>
+
+    <div id='iResultQueryContent' style='width:100%;min-height:250px;max-height:450px;overflow:auto;margin-bottom:8px;'></div>
+
+    <div class='gcBgInput gcTextInput'>
+      <div id='iPagesNavigator' style='float:right;'></div>
+      <div style='text-align:left;padding:4px;'>{'cstat_number_of_item_found'|@translate}&nbsp;:&nbsp;<span id='iResultQueryNfo'></span></div>
+    </div>
+
+  </fieldset>
+
+
+<script type="text/javascript">
+ init();
+</script>
Index: /extensions/ColorStat/admin/cstat_stat.tpl
===================================================================
--- /extensions/ColorStat/admin/cstat_stat.tpl	(revision 6106)
+++ /extensions/ColorStat/admin/cstat_stat.tpl	(revision 6107)
@@ -1,2 +1,4 @@
+{known_script id="jquery.ui" src=$ROOT_URL|@cat:"themes/default/js/ui/packed/ui.core.packed.js"}
+{known_script id="jquery.tipTip" src=$ROOT_URL|@cat:"themes/default/js/plugins/jquery.tipTip.minified.js" }
 
 {literal}
@@ -7,4 +9,12 @@
     loadColorList();
     displayColorListOrder();
+    $('.tiptip').tipTip(
+      {
+        'delay' : 0,
+        'fadeIn' : 0,
+        'fadeOut' : 0,
+        'edgeOffset' : 5,
+      }
+    );
   }
 
@@ -87,9 +97,9 @@
           <th style="min-width:180px;" colspan="2"><span id="iHLTOrderColor"></span><a onclick="sortColorList('color');">{'cstat_colors'|@translate}</a></th>
 
-          <th width="60px"><span id="iHLTOrderNumImages"></span><a onclick="sortColorList('img');" title="{'cstat_NumOfImages_help'|@translate}">{'cstat_NumOfImages'|@translate}</a></th>
+          <th width="60px"><span id="iHLTOrderNumImages"></span><a class="tiptip" onclick="sortColorList('img');" title="{'cstat_NumOfImages_help'|@translate}">{'cstat_NumOfImages'|@translate}</a></th>
           <th width="40px">{'cstat_Pct'|@translate}</th>
           <th width="115px">&nbsp;</th>
 
-          <th width="80px"><span id="iHLTOrderNumPixels"></span><a onclick="sortColorList('pixels');" title="{'cstat_NumOfPixels_help'|@translate}">{'cstat_NumOfPixels'|@translate}</a></th>
+          <th width="80px"><span id="iHLTOrderNumPixels"></span><a class="tiptip" onclick="sortColorList('pixels');" title="{'cstat_NumOfPixels_help'|@translate}">{'cstat_NumOfPixels'|@translate}</a></th>
           <th width="40px">{'cstat_Pct'|@translate}</th>
           <th width="130px">&nbsp;</th>
Index: /extensions/ColorStat/cstat.css
===================================================================
--- /extensions/ColorStat/cstat.css	(revision 6106)
+++ /extensions/ColorStat/cstat.css	(revision 6107)
@@ -32,2 +32,73 @@
   font-size:130%;
 }
+
+.cellColorChoose {
+  width:15px;
+  height:15px;
+  margin:2px;
+  float:left;
+  cursor:pointer;
+}
+
+
+#iListColorsChoosen { padding:0px; }
+
+#iListColorsChoosen ul li, #dragHelper ul li {
+  clear:both;
+  min-height:32px;
+  list-style-image:none;
+  list-style-position:outside;
+  list-style-type:none;
+  margin:4px;
+  padding:0px;
+}
+
+#iListColorsChoosen ul { padding:0px; }
+
+
+.cbGroup { border-width:1px; border-style:solid; padding:0px; margin:2px; min-height:30px; list-style:none; }
+.cbItem {   padding:2px; margin:8px; min-height:34px; list-style:none; }
+
+#iListColorsChoosen ul li.cbItem, #dragHelper ul li.cbItem { padding:2px; }
+
+.cbItemButtons { padding:2px; }
+.cbItem img { cursor: pointer; }
+
+.cbSortHandle { cursor:move; }
+
+div.cbOperator {
+ cursor:pointer;
+ padding:4px;
+ text-align:left;
+ font-weight:bold;
+}
+
+div.cbOperatorBgroma {
+ background:#333333;
+}
+
+div.cbOperatorBgclear {
+ background:#dbe8f3;
+}
+
+.cbButtons {
+  float:left;
+  margin:2px;
+  padding:8px;
+}
+
+.helper {
+ border:2px dashed #777777;
+}
+
+.cPnActive, .cPnDisabled, .cPnInactive { margin:2px; padding:2px;  min-width:20px; text-align:center; }
+.pnInactiveclear, .pnInactiveroma { cursor:pointer; }
+.pnInactiveclear:hover { background:#F1F1F1; }
+.pnActiveclear { background:#F1F1F1; font-weight:bold; }
+.pnInactiveroma:hover { background:#999999; color:#444444; }
+.pnActiveroma { background:#999999; color:#444444; font-weight:bold; }
+#iPagesNavigator ul { margin:0px; }
+
+.color1px { border-spacing:1px; }
+.color0px { border-spacing:0px; }
+
Index: /extensions/ColorStat/cstat_aip.class.inc.php
===================================================================
--- /extensions/ColorStat/cstat_aip.class.inc.php	(revision 6106)
+++ /extensions/ColorStat/cstat_aip.class.inc.php	(revision 6107)
@@ -1,5 +1,5 @@
 <?php
 /* -----------------------------------------------------------------------------
-  Plugin     : LMT
+  Plugin     : ColorStat
   Author     : Grum
     email    : grum@piwigo.org
@@ -10,10 +10,14 @@
   See main.inc.php for release information
 
-  LMT_AIP : classe to manage plugin admin pages
+  CStat_AIP : classe to manage plugin admin pages
 
   --------------------------------------------------------------------------- */
+
+if(!defined('PHPWG_ROOT_PATH')) die('Hacking attempt!');
 
 include_once('cstat_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');
 
@@ -25,4 +29,6 @@
   {
     parent::__construct($prefixeTable, $filelocation);
+    $this->checkRequest();
+
     $this->loadConfig();
     $this->initEvents();
@@ -55,4 +61,9 @@
   {
     parent::initEvents();
+    if($_REQUEST['f_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();
@@ -65,6 +76,4 @@
   {
     global $template;
-
-    $this->checkRequest();
 
     $this->returnAjaxContent();
@@ -154,5 +163,5 @@
       {
         if(!isset($_REQUEST['selectMode'])) $_REQUEST['selectMode']='caddieAdd';
-        if(!isset($_REQUEST['numOfItems'])) $_REQUEST['numOfItems']=$this->config['analyze.itemPerRequest'];
+        if(!isset($_REQUEST['numOfItems'])) $_REQUEST['numOfItems']=$this->config['analyze_itemPerRequest'];
 
         if(!($_REQUEST['selectMode']=='notAnalyzed' or
@@ -181,4 +190,5 @@
     }
 
+
   }
 
@@ -195,5 +205,5 @@
     $datas=Array(
       'urlRequest' => $this->getAdminLink(),
-      'numberOfItemsPerRequest' => $this->config['analyze.itemPerRequest']
+      'numberOfItemsPerRequest' => $this->config['analyze_itemPerRequest']
     );
     $template->assign('datas', $datas);
@@ -211,44 +221,17 @@
                 dirname($this->getFileLocation()).'/admin/cstat_stat.tpl');
 
-    $generalStats=$this->getGeneralStats();
-
-    $colors=Array();
-    $sql="SELECT color_id, num_images, num_pixels
-          FROM ".$this->tables['color_table']."
-          WHERE num_images > 0
-          ORDER BY color_id ";
-    $result=pwg_query($sql);
-    if($result)
-    {
-      while($row=pwg_db_fetch_assoc($result))
-      {
-        $colors[$row['color_id']]=Array('num_images' => $row['num_images'], 'num_pixels' => $row['num_pixels']);
-      }
-    }
-
-    $colorTable=ColorStat::getColorTable(
-      $this->colorTableSize[$this->config['analyze.colorTable']][0],
-      $this->colorTableSize[$this->config['analyze.colorTable']][1]
-    );
-    foreach($colorTable as $key=>$val)
-    {
-      foreach($val as $key2=>$val2)
-      {
-        $rgb=$val2->getRGB()->getHexString();
-        $colorTable[$key][$key2]=Array(
-          'color' => $rgb,
-          'pct'   => (array_key_exists($rgb, $colors))?sprintf("%.2f", round(100*$colors[$rgb]['num_pixels']/$generalStats['pixelsAnalyzedSum'],2)):"",
-          'num'   => (array_key_exists($rgb, $colors))?$colors[$rgb]['num_images']:"",
-        );
-      }
-    }
+    $colorTable=$this->getColorTableWithStat();
+
 
     $datas=Array(
+      //'themeconf' => Array('name' => $template->get_themeconf('name')),
       'colorTable' => $this->htmlColorTable(
                         $colorTable,
-                        ($this->config['analyze.colorTable']=='small')?19:10
+                        ($this->config['analyze_colorTable']=='small')?19:10,
+                        "",
+                        "color0px"
                       ),
       'urlRequest' => $this->getAdminLink(),
-      'config_GetListColors_OrderType' => $this->config['display.stat.orderType'],
+      'config_GetListColors_OrderType' => $this->config['display_stat_orderType'],
     );
     $template->assign('datas', $datas);
@@ -267,4 +250,11 @@
                 dirname($this->getFileLocation()).'/admin/cstat_search.tpl');
 
+    $datas=Array(
+      'dialogBox' => $this->dialogBoxColor(),
+      'themeName' => $template->get_themeconf('name'),
+    );
+
+    $template->assign('datas', $datas);
+
     $template->assign_var_from_handle('CSTAT_BODY_PAGE', 'body_page');
   } //displaySearchPage
@@ -276,5 +266,6 @@
   protected function displayConfigPage()
   {
-    /*
+    $tmpPct=$this->config['stat_minPct'];
+
     if(!$this->adviser_abort())
     {
@@ -283,26 +274,18 @@
         foreach($this->config as $key => $val)
         {
-          if(is_array($val))
+          if(isset($_REQUEST['f_'.$key]))
           {
-            foreach($languages as $key2 => $val2)
-            {
-              if(isset($_REQUEST[str2url('f_'.$key.'_'.$key2)]))
-              {
-                $this->config[$key][$key2] = htmlspecialchars(stripslashes($_REQUEST[str2url('f_'.$key.'_'.$key2)]), ENT_QUOTES);
-              }
-            }
+            $this->config[$key] = $_REQUEST['f_'.$key];
           }
-          else
-          {
-            if(isset($_REQUEST['f_'.$key]))
-            {
-              $this->config[$key] = $_REQUEST['f_'.$key];
-            }
-          }
-
         }
-        $this->displayResult(l10n('lmt_save_config'), $this->saveConfig());
-      }
-    }*/
+        $this->displayResult(l10n('cstat_save_config'), $this->saveConfig());
+      }
+    }
+
+    if($tmpPct!=$this->config['stat_minPct'])
+    {
+      $this->updateDatabaseConsolidation();
+    }
+
     $this->displayConfig();
   }
@@ -317,4 +300,11 @@
     $template->set_filename('body_page',
                 dirname($this->getFileLocation()).'/admin/cstat_config.tpl');
+
+    $datas=Array(
+      'minPct' => $this->config['stat_minPct'],
+      'showColors' => $this->config['display_gallery_showColors']
+    );
+
+    $template->assign('datas', $datas);
 
     $template->assign_var_from_handle('CSTAT_BODY_PAGE', 'body_page');
@@ -353,6 +343,6 @@
         'quality' => 8,
         'numColors' => 16,
-        'maxTime' => $this->config['analyze.maxTime'],
-        'pps' => $this->config['analyze.pps'],
+        'maxTime' => $this->config['analyze_maxTime'],
+        'pps' => $this->config['analyze_pps'],
       )
     );
@@ -443,4 +433,47 @@
   }
 
+
+  /**
+   * make consolidation for the color_table :
+   *  - count number of images using a color
+   *  - count number of pixels of a color
+   */
+  protected function updateDatabaseConsolidation()
+  {
+    $sql="UPDATE ".$this->tables['color_table']." cct
+          SET cct.num_images=0,
+              cct.num_pixels=0;";
+    pwg_query($sql);
+
+    $sql="UPDATE ".$this->tables['color_table']." cct,
+                 (SELECT color_id,
+                         count(image_id) AS num_images,
+                         sum(num_pixels) AS num_pixels
+                  FROM ".$this->tables['images_colors']."
+                  WHERE pct >= ".$this->config['stat_minPct']."
+                  GROUP BY color_id) cic
+          SET cct.num_images=cic.num_images,
+              cct.num_pixels=cic.num_pixels
+          WHERE cct.color_id=cic.color_id;";
+    pwg_query($sql);
+
+    $sql="UPDATE ".$this->tables['images']." pci
+          SET pci.colors = '',
+              pci.colors_pct = ''";
+    pwg_query($sql);
+
+    $sql="UPDATE ".$this->tables['images']." pci,
+          (SELECT image_id,
+                  GROUP_CONCAT(color_id ORDER BY pct DESC SEPARATOR ',') AS colors,
+                  GROUP_CONCAT(pct ORDER BY pct DESC SEPARATOR ',') AS colors_pct
+           FROM ".$this->tables['images_colors']."
+           WHERE pct >= ".$this->config['stat_minPct']."
+           GROUP BY image_id) pcic
+          SET pci.colors = pcic.colors,
+              pci.colors_pct = pcic.colors_pct
+          WHERE pci.image_id = pcic.image_id;";
+    pwg_query($sql);
+  }
+
   /* ---------------------------------------------------------------------------
     ajax functions
@@ -593,6 +626,6 @@
       {
         $colorTable=ColorStat::getColorTable(
-          $this->colorTableSize[$this->config['analyze.colorTable']][0],
-          $this->colorTableSize[$this->config['analyze.colorTable']][1]
+          $this->colorTableSize[$this->config['analyze_colorTable']][0],
+          $this->colorTableSize[$this->config['analyze_colorTable']][1]
         );
 
@@ -629,14 +662,5 @@
   private function ajax_cstat_updateDatabaseConsolidation()
   {
-    $sql="UPDATE ".$this->tables['color_table']." cct,
-                 (SELECT color_id,
-                         count(image_id) AS num_images,
-                         sum(num_pixels) AS num_pixels
-                  FROM ".$this->tables['images_colors']."
-                  GROUP BY color_id) cic
-          SET cct.num_images=cic.num_images,
-              cct.num_pixels=cic.num_pixels
-          WHERE cct.color_id=cic.color_id;";
-    pwg_query($sql);
+    $this->updateDatabaseConsolidation();
     return("ok");
   }
@@ -657,5 +681,5 @@
     global $template;
 
-    $this->config['display.stat.orderType'] = $orderType;
+    $this->config['display_stat_orderType'] = $orderType;
     $this->saveConfig();
 
Index: /extensions/ColorStat/cstat_aip_install.class.inc.php
===================================================================
--- /extensions/ColorStat/cstat_aip_install.class.inc.php	(revision 6106)
+++ /extensions/ColorStat/cstat_aip_install.class.inc.php	(revision 6107)
@@ -10,7 +10,7 @@
   See main.inc.php for release information
 
-  LMT_AIP : classe to manage plugin admin pages
-
   --------------------------------------------------------------------------- */
+
+  if(!defined('PHPWG_ROOT_PATH')) die('Hacking attempt!');
 
 include_once('cstat_root.class.inc.php');
@@ -128,6 +128,6 @@
     $smallColorTable=ColorStat::getColorTable($this->colorTableSize['small'][0],$this->colorTableSize['small'][1]);
     $largeColorTable=ColorStat::getColorTable($this->colorTableSize['large'][0],$this->colorTableSize['large'][1]);
-    $template->assign('smallTableColor', $this->htmlColorTable($smallColorTable, 19));
-    $template->assign('largeTableColor', $this->htmlColorTable($largeColorTable, 10));
+    $template->assign('smallTableColor', $this->htmlColorTable($smallColorTable, 19, '', 'color0px'));
+    $template->assign('largeTableColor', $this->htmlColorTable($largeColorTable, 10, '', 'color0px'));
 
     $template->assign(
@@ -135,5 +135,5 @@
       $this->htmlColorList(
         ColorStat::getFileColors(dirname($this->getFileLocation()).'/image/sample1.png', $smallColorTable, Array('quality' => 8, 'numColors' => 16)),
-        16, 18, '', 'colorListSample'
+        16, 18, '', 'colorListSample color0px'
       )
     );
@@ -144,5 +144,5 @@
       $this->htmlColorList(
         ColorStat::getFileColors(dirname($this->getFileLocation()).'/image/sample1.png', $largeColorTable, Array('quality' => 8, 'numColors' => 16)),
-        16, 18, '', 'colorListSample'
+        16, 18, '', 'colorListSample color0px'
       )
     );
@@ -153,5 +153,5 @@
       $this->htmlColorList(
         ColorStat::getFileColors(dirname($this->getFileLocation()).'/image/sample2.png', $smallColorTable, Array('quality' => 8, 'numColors' => 16)),
-        16, 18, '', 'colorListSample'
+        16, 18, '', 'colorListSample color0px'
       )
     );
@@ -162,5 +162,5 @@
       $this->htmlColorList(
         ColorStat::getFileColors(dirname($this->getFileLocation()).'/image/sample2.png', $largeColorTable, Array('quality' => 8, 'numColors' => 16)),
-        16, 18, '', 'colorListSample'
+        16, 18, '', 'colorListSample color0px'
       )
     );
@@ -170,5 +170,5 @@
     unset($largeColorTable);
 
-    $this->config['analyze.pps']=round($pps/4,0);
+    $this->config['analyze_pps']=round($pps/4,0);
     $this->saveConfig();
 
@@ -202,5 +202,5 @@
   {
     $this->config['newInstall']='n';
-    $this->config['analyze.colorTable']=$tableSize;
+    $this->config['analyze_colorTable']=$tableSize;
     $this->saveConfig();
 
Index: /extensions/ColorStat/cstat_colorstat.class.inc.php
===================================================================
--- /extensions/ColorStat/cstat_colorstat.class.inc.php	(revision 6106)
+++ /extensions/ColorStat/cstat_colorstat.class.inc.php	(revision 6107)
@@ -45,4 +45,6 @@
 
   --------------------------------------------------------------------------- */
+
+  if(!defined('PHPWG_ROOT_PATH')) die('Hacking attempt!');
 
 /**
Index: /extensions/ColorStat/cstat_install.class.inc.php
===================================================================
--- /extensions/ColorStat/cstat_install.class.inc.php	(revision 6106)
+++ /extensions/ColorStat/cstat_install.class.inc.php	(revision 6107)
@@ -14,7 +14,10 @@
   --------------------------------------------------------------------------- */
 
-   include_once('cstat_version.inc.php'); // => Don't forget to update this file !!
-   include_once('cstat_root.class.inc.php');
-   include_once(PHPWG_PLUGINS_PATH.'GrumPluginClasses/classes/GPCTables.class.inc.php');
+  if(!defined('PHPWG_ROOT_PATH')) die('Hacking attempt!');
+
+  include_once('cstat_version.inc.php'); // => Don't forget to update this file !!
+  include_once('cstat_root.class.inc.php');
+  include_once(PHPWG_PLUGINS_PATH.'GrumPluginClasses/classes/GPCTables.class.inc.php');
+  include_once(PHPWG_PLUGINS_PATH.'GrumPluginClasses/classes/GPCRequestBuilder.class.inc.php');
 
   /* CStat class for install process */
@@ -79,8 +82,9 @@
   `time` float unsigned NOT NULL default '0',
   `quality` tinyint(4) NOT NULL default '0',
+  `colors` char(111) NOT NULL default '',
+  `colors_pct` char(111) NOT NULL default '',
   PRIMARY KEY  (`image_id`),
   KEY `by_analyzed` (`analyzed`)
 )",
-
       );
 
@@ -121,5 +125,5 @@
                       quality=0;");
       pwg_query("INSERT INTO ".$this->tables['images']."
-                  SELECT id, 'n', 0, 0, 0, 0, 0, 0
+                  SELECT id, 'n', 0, 0, 0, 0, 0, 0, ''
                     FROM ".IMAGES_TABLE."
                     WHERE id NOT IN (SELECT image_id FROM ".$this->tables['images'].")");
Index: /extensions/ColorStat/cstat_pip.class.inc.php
===================================================================
--- /extensions/ColorStat/cstat_pip.class.inc.php	(revision 6106)
+++ /extensions/ColorStat/cstat_pip.class.inc.php	(revision 6107)
@@ -1,5 +1,5 @@
 <?php
 /* -----------------------------------------------------------------------------
-  Plugin     : LMT
+  Plugin     : ColorStat
   Author     : Grum
     email    : grum@piwigo.org
@@ -10,12 +10,12 @@
   See main.inc.php for release information
 
-  LMT_PIP : classe to manage plugin public pages
+  CStat_PIP : classe to manage plugin public pages
 
   --------------------------------------------------------------------------- */
 
-include_once('lmt_root.class.inc.php');
+include_once('cstat_root.class.inc.php');
 //include_once(PHPWG_PLUGINS_PATH.'GrumPluginClasses/classes/GPCPublicIntegration.class.inc.php');
 
-class LMT_PIP extends LMT_root
+class CStat_PIP extends CStat_root
 {
   protected $section_page;
@@ -36,37 +36,24 @@
   }
 
-  /*
-    load language file
-  */
+  /**
+   * load language file
+   */
   public function load_lang()
   {
     global $lang;
 
-    load_language('plugin.lang', LMT_PATH);
-
-    // ajax is managed here ; this permit to use user&language properties inside
-    // ajax content
-    //$this->return_ajax_content();
+    load_language('plugin.lang', CSTAT_PATH);
   }
 
-  /*
-    initialize events call for the plugin
-  */
+  /**
+   * initialize events call for the plugin
+   */
   public function initEvents()
   {
     parent::initEvents();
-/*
-    add_event_handler('blockmanager_apply', array(&$this, 'blockmanager_apply') );
-    add_event_handler('loading_lang', array(&$this, 'load_lang'));
-*/
-    if($this->config['lmt_licence_activated']=='y')
+
+    if($this->config['display_gallery_showColors']=='y')
     {
-      add_event_handler('loc_end_page_header', array(&$this->css_icn, 'applyCSS'));
-      add_event_handler('loc_end_picture', array(&$this, 'manage_licence_element'));
-
-      if($this->config['lmt_warning_visible']=='y')
-      {
-        add_event_handler('loc_end_page_tail', array(&$this, 'manage_warning_text'));
-      }
+      add_event_handler('loc_begin_picture', array(&$this, 'addColors'));
     }
   }
@@ -75,111 +62,37 @@
 
   /* -------------------------------------------------------------------------
-    FUNCTIONS TO MANAGE LMT DISPLAY
+    FUNCTIONS TO MANAGE COLORS DISPLAY
   ------------------------------------------------------------------------- */
-  public function manage_licence_element()
+  public function addColors()
   {
-    global $template, $page, $user;
+    global $page, $template;
 
-    $licence=$this->get_image_licence($page['image_id']);
-    if($licence['licence']=="")
+    $colors=$this->getImageColors($page['image_id']);
+
+
+    if(count($colors['colors'])>0)
     {
-      return("");
+      $metadata=$template->get_template_vars('metadata');
+
+      $tmp=Array();
+
+      for($i=0;$i<count($colors['colors']);$i++)
+      {
+        $tmp[$colors['colors'][$i]]['pct']=$colors['colors_pct'][$i];
+      }
+
+      $colorsNfo=Array(
+        'TITLE' => l10n('cstat_colors'),
+        'lines' => Array(
+          l10n('cstat_colors_on_image') => $this->htmlColorList($tmp, 8, 25, "", "color1px", "/"),
+        )
+      );
+
+      $metadata[]=$colorsNfo;
+
+      $template->assign('metadata', $metadata);
     }
-
-    if($this->config['lmt_redirect_activated']=='y')
-    {
-      $url=$this->config['lmt_redirect_url-'.strToLower($licence['licence'])][$user['language']];
-      if($url=='')
-      {
-        $url=$this->config['lmt_redirect_url-'.strToLower($licence['licence'])]['en_UK'];
-      }
-    }
-    else
-    {
-      $url="";
-    }
-
-    $style="";
-    $text="";
-    $target=($this->config['lmt_redirect_open_target']=="y")?" onclick='window.open(this.href); return false;'":"";
-    switch($this->config['lmt_licence_logo'])
-    {
-      case '80x15':
-        if($url!="")
-        {
-          $text = "<br/><a href='".$url."'".$target."><img class='logo80x15' src='". LMT_PATH."img/".strToLower($licence['licence'])."_80x15.png'></a>".$licence['aut_text1']." ".$licence['aut_text2'];
-        }
-        else
-        {
-          $text = "<br/><img class='logo80x15' src='". LMT_PATH."img/".strToLower($licence['licence'])."_80x15.png'>".$licence['aut_text1']." ".$licence['aut_text2'];
-        }
-      break;
-      case '88x31';
-        $style=" style='text-align:left;'";
-        if($url!="")
-        {
-          $text = "<table style='margin:auto;'><tr><td><a href='".$url."'".$target."><img class='logo88x31' style='top:-4px;' src='". LMT_PATH."img/".strToLower($licence['licence'])."_88x31.png'></a></td><td>".$licence['aut_text1']."<br/>".$licence['aut_text2']."</td></tr></table>";
-        }
-        else
-        {
-          $text = "<table style='margin:auto;'><tr><td><img class='logo88x31' style='top:-4px;' src='". LMT_PATH."img/".strToLower($licence['licence'])."_88x31.png'></td><td>".$licence['aut_text1']."<br/>".$licence['aut_text2']."</td></tr></table>";
-        }
-        break;
-      case 'text';
-        if($url!="")
-        {
-          $text ="<br/>".l10n("lmt_lbl_under-".strToLower($licence['licence']))." <a href='".$url."'".$target.">".l10n("lmt_lbl_cc_s-".strToLower($licence['licence']))."</a> ".$licence['aut_text1']." ".$licence['aut_text2'];
-        }
-        else
-        {
-          $text ="<br/>".l10n("lmt_lbl_under-".strToLower($licence['licence']))." ".l10n("lmt_lbl_cc_s-".strToLower($licence['licence']))." ".$licence['aut_text1']." ".$licence['aut_text2'];
-        }
-        break;
-    }
-
-    $template->concat('COMMENT_IMG', '<span class="licencetag" '.$style.'>'.$text.'</span>');
   }
 
-  public function manage_warning_text()
-  {
-    global $template, $user;
-
-
-    if(isset($this->config['lmt_warning_texts'][$user['language']]))
-    {
-      $text=$this->config['lmt_warning_texts'][$user['language']];
-    }
-    else
-    {
-      $text=$this->config['lmt_warning_texts']['en_UK'];
-    }
-
-    $patterns = array('/\[logo=80x15\]/i', '/\[logo=88x31\]/i', '/\[logo=text\]/i');
-    $replacements = array(
-      "<img class='logo80x15' src='". LMT_PATH."img/".strToLower($this->config['lmt_licence_default'])."_80x15.png'>",
-      "<img class='logo88x31' src='". LMT_PATH."img/".strToLower($this->config['lmt_licence_default'])."_88x31.png'>",
-      l10n("lmt_lbl_cc_s-".strToLower($this->config['lmt_licence_default']))
-    );
-
-    if($this->config['lmt_redirect_activated']=='y')
-    {
-      $url=$this->config['lmt_redirect_url-'.strToLower($this->config['lmt_licence_default'])][$user['language']];
-      if($url=='')
-      {
-        $url=$this->config['lmt_redirect_url-'.strToLower($this->config['lmt_licence_default'])]['en_UK'];
-      }
-      if($url!="")
-      {
-        $target=($this->config['lmt_redirect_open_target']=="y")?" onclick='window.open(this.href); return false;'":"";
-        $replacements[0]="<a href='".$url."'".$target.">".$replacements[0]."</a>";
-        $replacements[1]="<a href='".$url."'".$target.">".$replacements[1]."</a>";
-        $replacements[2]="<a href='".$url."'".$target.">".$replacements[2]."</a>";
-      }
-    }
-
-    $text = preg_replace($patterns, $replacements, $text);
-
-    $template->append("footer_elements", "<span>".htmlspecialchars_decode($text)."</span>");
-  }
 
 
Index: /extensions/ColorStat/cstat_rb_callback.class.inc.php
===================================================================
--- /extensions/ColorStat/cstat_rb_callback.class.inc.php	(revision 6107)
+++ /extensions/ColorStat/cstat_rb_callback.class.inc.php	(revision 6107)
@@ -0,0 +1,167 @@
+<?php
+/* -----------------------------------------------------------------------------
+  Plugin     : ColorStat
+  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', CSTAT_PATH);
+
+class RBCallBackColorStat extends GPCSearchCallback {
+
+  /**
+   * the getSelect function must return an attribute list separated with a comma
+   *
+   * "att1, att2, att3, att4"
+   */
+  static public function getSelect($param="")
+  {
+    return("pci.colors AS csColors, pci.colors_pct AS csColorsPct");
+  }
+
+  /**
+   * 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."cstat_images pci");
+  }
+
+  /**
+   * 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="")
+  {
+    $returned='';
+
+    $not=false;
+    if($param['mode']=='not')
+    {
+      $param['mode']='or';
+      $not=true;
+    }
+
+    $colors=split(',', $param['colors']);
+    if(count($colors)>0)
+    {
+      foreach($colors as $key=>$val)
+      {
+        if($returned!='') $returned.=" ".$param['mode']." ";
+        $returned.=" pci.colors LIKE '%".trim($val)."%'";
+      }
+    }
+
+    if($not) $returned=' NOT('.$returned.') ';
+
+    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("pci.image_id = pit.id");
+  }
+
+
+
+  /**
+   * 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'
+     *    );
+     */
+    $colors=explode(',', $attributes['csColors']);
+    $pct=explode(',', $attributes['csColorsPct']);
+
+    $colorList=Array();
+    $i=0;
+    foreach($colors as $key => $val)
+    {
+      $colorList[$val]=$pct[$i];
+      $i++;
+    }
+    return(self::htmlColorList($colorList, 16, 15,"","color1px"));
+  }
+
+
+  /**
+   * return HTML code for a given colors list
+   *
+   * ==> this is the same function than the CStat_root::htmlColorList() function
+   *     make a copy here only top optimize performance (don't load the
+   *     CStat_root file for one function)
+   *
+   * @param Array $colors : list of colors
+   * @param Int $size     : size for colorbox in the HTML table
+   * @return String : HTML code
+   */
+  static private function htmlColorList($colorList, $split=8, $size=5, $id="", $class="")
+  {
+    global $template;
+
+    $template->set_filename('color_table_page',
+                  dirname(__FILE__).'/templates/cstat_color_table.tpl');
+
+    $colors=Array();
+
+    $row=0;
+    $num=0;
+    foreach($colorList as $key => $val)
+    {
+      $colors[$row][]=Array('color' => $key, 'pct' => $val, 'num' => "");
+      $num++;
+      if($num==$split)
+      {
+        $num=0;
+        $row++;
+      }
+    }
+
+    $data=array(
+      'colorTable' => $colors,
+      'size' => $size,
+      'id' => $id,
+      'class' => $class,
+      'br' => ' / ',
+    );
+
+    $template->assign('data', $data);
+    unset($data);
+
+    return($template->parse('color_table_page', true));
+  }
+
+}
+
+?>
Index: /extensions/ColorStat/cstat_root.class.inc.php
===================================================================
--- /extensions/ColorStat/cstat_root.class.inc.php	(revision 6106)
+++ /extensions/ColorStat/cstat_root.class.inc.php	(revision 6107)
@@ -13,4 +13,8 @@
 
   --------------------------------------------------------------------------- */
+
+  if(!defined('PHPWG_ROOT_PATH')) die('Hacking attempt!');
+
+
   include_once('cstat_colorstat.class.inc.php');
   include_once(PHPWG_PLUGINS_PATH.'GrumPluginClasses/classes/CommonPlugin.class.inc.php');
@@ -63,9 +67,11 @@
       $this->config=array(
         'newInstall' => 'n',
-        'analyze.maxTime' => 0.1,
-        'analyze.colorTable' => 'small',
-        'analyze.pps' => 0,
-        'analyze.itemPerRequest' => 10,
-        'display.stat.orderType' => 'img',
+        'analyze_maxTime' => 0.1,
+        'analyze_colorTable' => 'small',
+        'analyze_pps' => 0,
+        'analyze_itemPerRequest' => 10,
+        'display_gallery_showColors' => 'n',
+        'display_stat_orderType' => 'img',
+        'stat_minPct' => 3.5,
       );
     }
@@ -137,5 +143,5 @@
      * @return String : HTML code
      */
-    public function htmlColorList($colorList, $split=8, $size=5, $id="", $class="")
+    public function htmlColorList($colorList, $split=8, $size=5, $id="", $class="", $br='<br>')
     {
       global $template;
@@ -163,5 +169,6 @@
         'size' => $size,
         'id' => $id,
-        'class' => $class
+        'class' => $class,
+        'br' => $br,
       );
 
@@ -172,20 +179,110 @@
     }
 
-
-
-
-    protected function displayResult($action_msg, $result)
-    {
-      global $page;
-
+    /**
+     * returns an array of colors & colors percent of an image
+     *
+     * @param Integer $imageId : id of the image
+     * @return Array('colors' => Array(), 'colors_pct' => Array())
+     */
+    public function getImageColors($imageId)
+    {
+      $returned=Array(
+        'colors' => Array(),
+        'colors_pct' => Array(),
+      );
+
+      $sql="SELECT colors, colors_pct
+            FROM ".$this->tables['images']."
+            WHERE image_id='".$imageId."'";
+      $result=pwg_query($sql);
       if($result)
       {
-        array_push($page['infos'], $action_msg);
-      }
-      else
-      {
-        array_push($page['errors'], $action_msg);
-      }
-    }
+        while($row=pwg_db_fetch_assoc($result))
+        {
+          $returned['colors']=explode(',', $row['colors']);
+          $returned['colors_pct']=explode(',', $row['colors_pct']);
+        }
+      }
+      return($returned);
+    }
+
+
+
+    /**
+     *  return all HTML&JS code necessary to display a dialogbox to choose
+     *  colors
+     */
+    protected function dialogBoxColor()
+    {
+      global $template;
+
+      $template->set_filename('colors_choose',
+                    dirname($this->getFileLocation()).'/templates/cstat_dialog_colors_choose.tpl');
+
+      $colorTable=$this->getColorTableWithStat();
+
+      $datas=Array(
+        'colorTable' => $this->htmlColorTable(
+                          $colorTable,
+                          ($this->config['analyze_colorTable']=='small')?16:8,
+                          "",
+                          "color0px"
+                        ),
+        //'urlRequest' => $this->getAdminLink(),
+      );
+
+      $template->assign('datas', $datas);
+      unset($data);
+
+      return($template->parse('colors_choose', true));
+    }
+
+
+    /**
+     * return a color table with stat on color
+     *
+     * @return Array : a color table with statistics on colors
+     */
+    protected function getColorTableWithStat()
+    {
+      $generalStats=$this->getGeneralStats();
+
+      $colors=Array();
+      $sql="SELECT color_id, num_images, num_pixels
+            FROM ".$this->tables['color_table']."
+            WHERE num_images > 0
+            ORDER BY color_id ";
+      $result=pwg_query($sql);
+      if($result)
+      {
+        while($row=pwg_db_fetch_assoc($result))
+        {
+          $colors[$row['color_id']]=Array('num_images' => $row['num_images'], 'num_pixels' => $row['num_pixels']);
+        }
+      }
+
+      $colorTable=ColorStat::getColorTable(
+        $this->colorTableSize[$this->config['analyze_colorTable']][0],
+        $this->colorTableSize[$this->config['analyze_colorTable']][1]
+      );
+      foreach($colorTable as $key=>$val)
+      {
+        foreach($val as $key2=>$val2)
+        {
+          $rgb=$val2->getRGB()->getHexString();
+          $colorTable[$key][$key2]=Array(
+            'color' => $rgb,
+            'pct'   => '', //(array_key_exists($rgb, $colors))?sprintf("%.2f", round(100*$colors[$rgb]['num_pixels']/$generalStats['pixelsAnalyzedSum'],2)):"",
+            'num'   => (array_key_exists($rgb, $colors))?$colors[$rgb]['num_images']:"",
+          );
+        }
+      }
+
+      unset($colors);
+      return($colorTable);
+    }
+
+
+
 
 
Index: /extensions/ColorStat/language/en_UK/plugin.lang.php
===================================================================
--- /extensions/ColorStat/language/en_UK/plugin.lang.php	(revision 6106)
+++ /extensions/ColorStat/language/en_UK/plugin.lang.php	(revision 6107)
@@ -59,14 +59,27 @@
 $lang['cstat_NumOfImages']='Number of images';
 $lang['cstat_NumOfPixels']='Number of pixels';
-$lang['cstat_NumOfImages_help']="Indicates the number of images in which color is present. The percentage is relative to the number of images analyzed.";
-$lang['cstat_NumOfPixels_help']="Indicates the number of pixels for which color has been determined. The percentage is relative to the number of pixels analyzed and represents the 'area' occupied on all photos.";
+$lang['cstat_NumOfImages_help']="Indicates the number of images in which color is present.<br>The percentage is relative to the number of images analyzed.";
+$lang['cstat_NumOfPixels_help']="Indicates the number of pixels for which color has been determined.<br>The percentage is relative to the number of pixels analyzed and represents the 'area' occupied on all photos.";
 $lang['cstat_images']='images';
 $lang['cstat_surface']='surface';
 
 
+
 $lang['cstat_search']='Search';
+$lang['cstat_search_by_color']='Search by color';
+$lang['cstat_choose_colors']='Sélection de couleurs';
+$lang['cstat_choosen_colors']='Couleurs sélectionnées';
+$lang['cstat_operator_and']="Toutes les couleurs sélectionnées doivent être présentes dans l'image";
+$lang['cstat_operator_or']="Au moins une des couleurs sélectionnées doit être présente dans l'image";
+$lang['cstat_operator_not']="Aucune des couleurs sélectionnées ne doit être présente dans l'image'";
+$lang['cstat_color_already_choosen']='La couleur est déjà sélectionnée dans la liste';
+$lang['cstat_add_colors']='Ajouter une sélection de couleurs';
+$lang['cstat_clear_colors']='Réinitialiser les critères';
+$lang['cstat_do_modify_request']='Modifier la recherche';
+$lang['cstat_search_criterion'] = 'Critères de recherche';
+
+
 $lang['cstat_config']='Configuration';
 
-$lang['cstat_search_by_color']='Search by color';
 $lang['cstat_config_plugin']='Configuring the plugin';
 
Index: /extensions/ColorStat/language/fr_FR/plugin.lang.php
===================================================================
--- /extensions/ColorStat/language/fr_FR/plugin.lang.php	(revision 6106)
+++ /extensions/ColorStat/language/fr_FR/plugin.lang.php	(revision 6107)
@@ -9,4 +9,5 @@
 $lang['cstat_release'] = 'v';
 $lang['cstat_ok']='OK';
+$lang['cstat_cancel']='Annuler';
 
 $lang['cstat_install'] = 'Installation';
@@ -63,6 +64,6 @@
 $lang['cstat_NumOfImages']='Nombre d\'images';
 $lang['cstat_NumOfPixels']='Nombre de pixels';
-$lang['cstat_NumOfImages_help']="Indique le nombre d'images dans lesquelles la couleur est présente. Le pourcentage est relatif au nombre d'images analysées.";
-$lang['cstat_NumOfPixels_help']="Indique le nombre de pixels pour lesquels la couleur a été déterminée. Le pourcentage est relatif au nombre de pixels analysés et représente la 'surface' occupée sur l'ensemble des photos.";
+$lang['cstat_NumOfImages_help']="Indique le nombre d'images dans lesquelles la couleur est présente.<br>Le pourcentage est relatif au nombre d'images analysées.";
+$lang['cstat_NumOfPixels_help']="Indique le nombre de pixels pour lesquels la couleur a été déterminée.<br>Le pourcentage est relatif au nombre de pixels analysés et représente la 'surface' occupée sur l'ensemble des photos.";
 $lang['cstat_images']='images';
 $lang['cstat_surface']='surface';
@@ -70,8 +71,29 @@
 
 $lang['cstat_search']='Recherche';
+$lang['cstat_search_by_color']='Effectuer une recherche par couleur';
+$lang['cstat_choose_colors']='Sélection de couleurs';
+$lang['cstat_choosen_colors']='Couleurs sélectionnées';
+$lang['cstat_operator_and']="Toutes les couleurs sélectionnées doivent être présentes dans l'image";
+$lang['cstat_operator_or']="Au moins une des couleurs sélectionnées doit être présente dans l'image";
+$lang['cstat_operator_not']="Aucune des couleurs sélectionnées ne doit être présente dans l'image'";
+$lang['cstat_color_already_choosen']='La couleur est déjà sélectionnée dans la liste';
+$lang['cstat_add_colors']='Ajouter une sélection de couleurs';
+$lang['cstat_clear_colors']='Réinitialiser les critères';
+$lang['cstat_do_modify_request']='Modifier la recherche';
+$lang['cstat_search_criterion'] = 'Critères de recherche';
+$lang['cstat_number_of_item_found']='Nombre d\'images trouvées';
+$lang['cstat_result_query']='Résultat de la recherche';
+
 $lang['cstat_config']='Configuration';
+$lang['cstat_gallery_integration']='Intégration dans la galerie';
+$lang['cstat_apply']='Appliquer';
+$lang['cstat_stat_and_search']='Statistiques & Recherches';
+$lang['cstat_save_config']='Configuration enregistrée';
+$lang['cstat_display_colors_on_image']='Afficher les couleurs associées à l\'image';
+$lang['cstat_percent_min_significant']='Présence minimum au sein d\'une image pour qu\'une couleur soit considérée comme pertinente lors d\'une recherche :';
 
-$lang['cstat_search_by_color']='Effectuer une recherche par couleur';
 $lang['cstat_config_plugin']='Configuration du plugin';
 
+$lang['cstat_colors_on_image']='Couleurs associées à l\'image';
+
 ?>
Index: /extensions/ColorStat/main.inc.php
===================================================================
--- /extensions/ColorStat/main.inc.php	(revision 6106)
+++ /extensions/ColorStat/main.inc.php	(revision 6107)
@@ -85,8 +85,7 @@
 {
   //CStat public interface loaded and active only if in public page
-  /*include_once("cstat_pip.class.inc.php");
+  include_once("cstat_pip.class.inc.php");
   $obj=new CStat_PIP($prefixeTable, __FILE__);
   set_plugin_data($plugin['id'], $obj);
-  */
 }
 
Index: /extensions/ColorStat/maintain.inc.php
===================================================================
--- /extensions/ColorStat/maintain.inc.php	(revision 6106)
+++ /extensions/ColorStat/maintain.inc.php	(revision 6107)
@@ -72,4 +72,5 @@
     }
     GPCCore::register($obj->getPluginName(), CSTAT_VERSION, $gpcNeeded);
+    GPCRequestBuilder::register($obj->getPluginName(), dirname($obj->getFileLocation()).'/cstat_rb_callback.class.inc.php');
   }
   else
@@ -117,4 +118,5 @@
     $obj = new CStat_Install($prefixeTable, __FILE__);
     $obj->uninstall();
+    GPCRequestBuilder::unregister($obj->getPluginName());
     GPCCore::unregister($obj->getPluginName());
   }
Index: /extensions/ColorStat/templates/cstat_color_table.tpl
===================================================================
--- /extensions/ColorStat/templates/cstat_color_table.tpl	(revision 6106)
+++ /extensions/ColorStat/templates/cstat_color_table.tpl	(revision 6107)
@@ -1,8 +1,9 @@
-<table {if $data.id!=''}id="{$datas.id}"{/if} {if $data.class!=''}class="{$data.class}"{/if} style="border-collapse:collapse;">
+<table {if $data.id!=''}id="{$data.id}"{/if} {if $data.class!=''}class="{$data.class}"{/if} >
   {foreach from=$data.colorTable item=row}
   <tr>
     {foreach from=$row item=col}
-    <td style="width:{$data.size}px;height:{$data.size}px;background-color:#{$col.color};"
-        title="{'cstat_color'|@translate}&nbsp;#{$col.color} {if $col.num!=''}&nbsp;-&nbsp;{$col.num}&nbsp;{'cstat_images'|@translate}{/if} {if $col.pct!=''}&nbsp;-&nbsp;{'cstat_surface'|@translate}&nbsp;{$col.pct}%{/if} "></td>
+    <td id="cellColor_{$col.color}" style="width:{$data.size}px;height:{$data.size}px;background-color:#{$col.color};{if $col.num!=''}cursor:pointer;{/if}" class="tiptip {if $col.num!=''}csSelectable{/if}"
+        title="{'cstat_color'|@translate}&nbsp;#{$col.color}{if $col.num!=''}&nbsp;:&nbsp;{$col.num}&nbsp;{'cstat_images'|@translate}{/if}{if $col.pct!=''} {$data.br} {'cstat_surface'|@translate}&nbsp;{$col.pct}%{/if}">
+    </td>
     {/foreach}
   </tr>
Index: /extensions/ColorStat/templates/cstat_dialog_colors_choose.tpl
===================================================================
--- /extensions/ColorStat/templates/cstat_dialog_colors_choose.tpl	(revision 6107)
+++ /extensions/ColorStat/templates/cstat_dialog_colors_choose.tpl	(revision 6107)
@@ -0,0 +1,324 @@
+{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.tipTip" src=$ROOT_URL|@cat:"themes/default/js/plugins/jquery.tipTip.minified.js"}
+
+
+{literal}
+<script type="text/javascript">
+
+/**
+ * include this template in a page and use colorBox.show({options}) to display
+ * the dialog box
+ *
+ */
+dialogChooseColorBox = function()
+{
+  var selectedColors = new Array();
+  var dialogColorOptions = {
+      colorList:'',
+      mode:'and',
+      id:'',
+      eventOk:null,
+      cBuilder:null,
+    };
+
+  /**
+   * initialize the dialog box
+   */
+  var initDialogBox = function()
+  {
+    $('.tiptip').tipTip(
+      {
+        'delay' : 0,
+        'fadeIn' : 0,
+        'fadeOut' : 0,
+        'edgeOffset' : 5,
+      }
+    );
+
+    $("#iDialogColorChoose")
+    .dialog(
+      {
+        autoOpen: false,
+        resizable: false,
+        width:720,
+        height:400,
+        modal: true,
+        draggable:true,
+        dialogClass: 'gcBgTabSheet gcBorder',
+        title: '{/literal}{"cstat_choose_colors"|@translate}{literal}',
+        open: function(event, ui)
+        {
+
+        },
+        buttons:
+        {
+          '{/literal}{"cstat_ok"|@translate}{literal}':
+            function()
+            {
+              list='';
+              nbColor=$('#iDCCchoosenColors div').length;
+              for(i=0;i<nbColor;i++)
+              {
+                if(list!='') { list+=','; }
+                list+=$('#iDCCchoosenColors div').get(i).id.substr(13);
+              }
+
+              if($('#iDCCOperatorAnd').get(0).checked)
+              {
+                mode='and';
+              }
+              else if($('#iDCCOperatorOr').get(0).checked)
+              {
+                mode='or';
+              }
+              else if($('#iDCCOperatorNot').get(0).checked)
+              {
+                mode='not';
+              }
+
+              if(dialogColorOptions.cBuilder!=null)
+              {
+                setCBuilderItem(dialogColorOptions.id, list, mode);
+              }
+
+              if(dialogColorOptions.eventOk!=null)
+              {
+                dialogColorOptions.eventOk(dialogColorOptions.id, list, mode);
+              }
+
+              $(this).dialog('close');
+            },
+          '{/literal}{"cstat_cancel"|@translate}{literal}':
+            function()
+            {
+              $(this).dialog('close');
+            }
+        }
+      }
+    );
+
+    $('#iDCCtableColor td.csSelectable').bind('click', function() { addColorList(this.id.substr(10)); });
+  }
+
+  /**
+   * remove a color from the choosen colors list
+   * event.data : the color top remove
+   */
+  var removeColorList = function(event)
+  {
+    $('#iDCCselected_'+event.data).remove();
+  }
+
+  /**
+   * add a color from the choosen colors list
+   */
+  var addColorList = function(color)
+  {
+    if($('#iDCCselected_'+color).get(0)==null)
+    {
+      $('#iDCCchoosenColors').append("<div id='iDCCselected_"+color+"' class='cellColorChoose' style='background-color:#"+color+";'></div>");
+      $('#iDCCselected_'+color).bind('click', color, removeColorList);
+    }
+    else
+    {
+      alert("{/literal}{'cstat_color_already_choosen'|@translate}{literal}")
+    }
+  }
+
+
+  /**
+   * the show() function display and manage a dialog box to choose
+   * a set of colors from a color table
+   *
+   * @param options : properties to manage the dialog box
+   *                  - colorList : a string of hex color, separated with a comma
+   *                                example: 'ff0000,00ff00,0000ff'
+   *                                if set, theses colors are selected when the
+   *                                dialog box is open
+   *                  - id : a string to identify a DOM object ; this parameter
+   *                         is given to the callback when the OK button is pushed
+   *                  - mode : a string to identify the default mode selected
+   *                           values : 'and', 'or', 'not'
+   *                  - eventOK : a callback function, with 2 parameters : id of
+   *                              the given DOM object and the color list
+   *                  - 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.colorList!=null)
+    {
+      dialogColorOptions.colorList=options.colorList;
+    }
+    else
+    {
+      dialogColorOptions.colorList='';
+    }
+
+    if(options.mode!=null)
+    {
+      dialogColorOptions.mode=options.mode;
+    }
+    else
+    {
+      dialogColorOptions.mode='and';
+    }
+
+    if(options.id!=null)
+    {
+      dialogColorOptions.id=options.id;
+    }
+    else
+    {
+      dialogColorOptions.id='';
+    }
+
+    if(options.eventOk!=null)
+    {
+      dialogColorOptions.eventOk=options.eventOk;
+    }
+
+    if(options.cBuilder!=null)
+    {
+      dialogColorOptions.cBuilder=options.cBuilder;
+      dialogColorOptions.cBuilder.doAction('setOptions',
+        {
+          onEdit:function (e) { editCB(e.data); },
+          onDelete:function (e) { deleteCB(e.data); },
+        }
+      );
+    }
+
+
+    $('#iDCCchoosenColors').html('');
+
+    if(dialogColorOptions.colorList!='')
+    {
+      selectedColors=dialogColorOptions.colorList.split(',');
+      for(i=0;i<selectedColors.length;i++)
+      {
+        addColorList(selectedColors[i]);
+      }
+    }
+    switch(dialogColorOptions.mode)
+    {
+      case 'and':
+        $('#iDCCOperatorAnd').attr('checked', true);
+        break;
+      case 'or':
+        $('#iDCCOperatorOr').attr('checked', true);
+        break;
+      case 'not':
+        $('#iDCCOperatorNot').attr('checked', true);
+        break;
+    }
+    $("#iDialogColorChoose").dialog('open');
+  }
+
+
+
+  /**
+   * manage the 'edit' button from criteria builder interface
+   * @param String itemId : the itemId
+   */
+  var editCB = function (itemId)
+  {
+    extraData=dialogColorOptions.cBuilder.doAction('getExtraData', itemId);
+    showDialog(
+      {
+        id:itemId,
+        colorList:extraData.param.colors,
+        mode:extraData.param.mode,
+      }
+    );
+  }
+
+  /**
+   * manage the 'delete' button from criteria builder interface
+   * @param String itemId : the itemId
+   */
+  var deleteCB = function (itemId)
+  {
+    dialogColorOptions.cBuilder.doAction('delete', itemId);
+  }
+
+  /**
+   * set the content for the cBuilder item
+   */
+  var setCBuilderItem = function(id, colorList, mode)
+  {
+    content="<div>";
+    switch(mode)
+    {
+      case 'and':
+        content+="{/literal}{'cstat_operator_and'|@translate}{literal}";
+        break;
+      case 'or':
+        content+="{/literal}{'cstat_operator_or'|@translate}{literal}";
+        break;
+      case 'not':
+        content+="{/literal}{'cstat_operator_not'|@translate}{literal}";
+        break;
+    }
+    content+="</div>";
+
+    content+="<div style='float:left;'>";
+    selectedColors=colorList.split(',');
+    for(i=0;i<selectedColors.length;i++)
+    {
+      content+="<div class='cellColorChoose' style='background-color:#"+selectedColors[i]+";'></div>";
+    }
+    content+="</div>";
+
+    if(id=='')
+    {
+      //no id:add a new item in the list
+      dialogColorOptions.cBuilder.doAction('add', content, criteriaBuilder.makeExtendedData('ColorStat', {mode:mode, colors:colorList} ) );
+    }
+    else
+    {
+      // update item
+      dialogColorOptions.cBuilder.doAction('edit', id,  content, criteriaBuilder.makeExtendedData('ColorStat', {mode:mode, colors:colorList} ) );
+    }
+  }
+
+  initDialogBox();
+}
+
+
+</script>
+{/literal}
+
+<div id="iDialogColorChoose">
+  <table style="padding-top:8px;">
+    <tr>
+      <td style='width:350px;' id='iDCCtableColor'>{$datas.colorTable}</td>
+      <td style='padding:12px;'>
+        <span>{'cstat_choosen_colors'|@translate}</span>
+
+        <div id='iDCCchoosenColors' style='height:56px;border:1px solid;margin:2px;padding:4px;'>
+        </div>
+
+        <div style='text-align:justify;padding:8px;'>
+          <label><input type="radio" name="f_operator" id="iDCCOperatorAnd" checked>&nbsp;{'cstat_operator_and'|@translate}</label><br>
+          <label><input type="radio" name="f_operator" id="iDCCOperatorOr">&nbsp;{'cstat_operator_or'|@translate}</label><br>
+          <label><input type="radio" name="f_operator" id="iDCCOperatorNot">&nbsp;{'cstat_operator_not'|@translate}</label>
+        </div>
+      </td>
+    </tr>
+  </table>
+</div>
+
+<script type="text/javascript">
+ var colorBox=new dialogChooseColorBox();
+</script>
