text: /*
   * Copyright (C) 2009  Camptocamp
   *
   * This file is part of MapFish Client
   *
   * MapFish Client 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, either version 3 of the License, or
   * (at your option) any later version.
   *
   * MapFish Client 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 MapFish Client.  If not, see <http://www.gnu.org/licenses/>.
   */
  
  /**
   * @requires OpenLayers/Control/SelectFeature.js
   */
  
  Ext.namespace('mapfish.widgets', 'mapfish.widgets.data');
  
  /**
   * Class: mapfish.widgets.data.GridRowFeatureMediator
   * A mediator for selecting feature on grid row selection and
   * vice-vera.
   *
   * Usage example:
   * (start code)
   * var mediator = new mapfish.widgets.data.GridRowFeatureMediator({
   *     grid: grid,
   *     selectControl: selectFeatureControl
   * });
   * (end)
   */
  
  /**
   * Constructor: mapfish.widgets.data.GridRowFeatureMediator
   * Create an instance of mapfish.widgets.data.GridRowFeatureMediator.
   *
   * Parameters:
   * config - {Object}
   *
   * Returns:
   * {<mapfish.widgets.data.GridRowFeatureMediator>}
   */
  mapfish.widgets.data.GridRowFeatureMediator = function(config) {
      Ext.apply(this, config);
      if (!this.grid) {
          OpenLayers.Console.error(
              "no Ext.grid.GridPanel provided");
          return;
      }
      if (!this.selectControl ||
          this.selectControl.CLASS_NAME != "OpenLayers.Control.SelectFeature") {
          OpenLayers.Console.error(
              "no OpenLayers.Control.SelectFeature provided");
          return;
      }
      this.selectModel = this.grid.getSelectionModel();
      if (this.autoActivate) {
          this.activate();
      }
  };
  
  mapfish.widgets.data.GridRowFeatureMediator.prototype = {
      /**
       * APIProperty: autoActivate
       * {Boolean} The instance is activated at creation time, defaults
       *     to true.
       */
      autoActivate: true,
  
      /**
       * APIProperty: selectControl
       * {<OpenLayers.Control.SelectFeature>} The select feature control.
       */
      selectControl: null,
  
      /**
       * APIProperty: grid
       * {Ext.grid.GridPanel} The grid panel.
       */
      grid: null,
  
      /**
       * Property: selectModel
       * {Ext.grid.RowSelectionModel} The row selection model attached to
       *     the grid panel.
       */
      selectModel: null,
  
      /**
       * Property: active
       * {Boolean}
       */
      active: false,
  
      /**
       * APIMethod: activate
       * Activate the mediator.
       *
       * Returns:
       * {Boolean} - False if the mediator was already active, true
       * otherwise.
       */
      activate: function() {
          if (!this.active) {
              this.featureEventsOn();
              this.rowEventsOn();
              this.active = true;
              return true;
          }
          return false;
      },
  
      /**
       * APIMethod: deactivate
       * Deactivate the mediator.
       *
       * Returns:
       * {Boolean} - False if the mediator was already deactive, true
       * otherwise.
       */
      deactivate: function() {
          if (this.active) {
              this.featureEventsOff();
              this.rowEventsOff();
              this.active = false;
              return true;
          }
          return false;
      },
  
      /**
       * Method: featureSelected
       *
       * Parameters:
       * o - {Object} An object with a feature property referencing
       *     the selected feature.
       */
      featureSelected: function(o) {
          var r = this.grid.store.getById(o.feature.id);
          if (r) {
              this.rowEventsOff();
              this.selectModel.selectRecords([r]);
              this.rowEventsOn();
  
              // focus the row in the grid to ensure the row is visible
              this.grid.getView().focusRow(this.grid.store.indexOf(r));
          }
      },
  
      /**
       * Method: featureUnselected
       *
       * Parameters:
       * o - {Object} An object with a feature property referencing
       *     the selected feature.
       */
      featureUnselected: function(o) {
          var r = this.grid.store.getById(o.feature.id);
          if (r) {
              this.rowEventsOff();
              this.selectModel.deselectRow(this.grid.store.indexOf(r));
              this.rowEventsOn();
          }
      },
  
      /**
       * Method: rowSelected
       *
       * Parameters:
       * s - {Ext.grid.RowSelectModel} The row select model.
       * i - {Number} The row index.
       * r - {Ext.data.Record} The record.
       */
      rowSelected: function(s, i, r) {
          var layers = this.selectControl.layers || [this.selectControl.layer], f;
          for (var i = 0, len = layers.length; i < len; i++) {
              f = layers[i].getFeatureById(r.id);
              if (f) {
                  this.featureEventsOff();
                  this.selectControl.select(f);
                  this.featureEventsOn();
                  break;
              }
          }
      },
  
      /**
       * Method: rowDeselected
       *
       * Parameters:
       * s - {Ext.grid.RowSelectModel} The row select model.
       * i - {Number} The row index.
       * r - {Ext.data.Record} The record.
       */
      rowDeselected: function(s, i, r) {
          var layers = this.selectControl.layers || [this.selectControl.layer], f;
          for (var i = 0, len = layers.length; i < len; i++) {
              f = layers[i].getFeatureById(r.id);
              if (f) {
                  this.featureEventsOff();
                  this.selectControl.unselect(f);
                  this.featureEventsOn();
              }
          }
      },
  
      /**
       * Method: rowEventsOff
       * Turn off the row events.
       */
      rowEventsOff: function() {
          this.selectModel.un("rowselect", this.rowSelected, this);
          this.selectModel.un("rowdeselect", this.rowDeselected, this);
      },
  
      /**
       * Method: rowEventsOn
       * Turn on the row events.
       */
      rowEventsOn: function() {
          this.selectModel.on("rowselect", this.rowSelected, this);
          this.selectModel.on("rowdeselect", this.rowDeselected, this);
      },
  
      /**
       * Method: featureEventsOff
       * Turn off the feature events.
       */
      featureEventsOff: function() {
          var layers = this.selectControl.layers || [this.selectControl.layer];
          for (var i = 0, len = layers.length; i < len; i++) {
              layers[i].events.un({
                  featureselected: this.featureSelected,
                  featureunselected: this.featureUnselected,
                  scope: this
              });
          }
      },
  
      /**
       * Method: featureEventsOn
       * Turn on the feature events.
       */
      featureEventsOn: function() {
          var layers = this.selectControl.layers || [this.selectControl.layer];
          for (var i = 0, len = layers.length; i < len; i++) {
              layers[i].events.on({
                  featureselected: this.featureSelected,
                  featureunselected: this.featureUnselected,
                  scope: this
              });
          }
      }
  };
  