text: 'use strict';
  
  /*global require*/
  var defined = require('terriajs-cesium/Source/Core/defined');
  var defineProperties = require('terriajs-cesium/Source/Core/defineProperties');
  var DeveloperError = require('terriajs-cesium/Source/Core/DeveloperError');
  var FunctionParameter = require('./FunctionParameter');
  var inherit = require('../Core/inherit');
  var RegionTypeParameter = require('../Models/RegionTypeParameter');
  
  /**
   * A parameter that specifies a particular region.
   *
   * @alias RegionParameter
   * @constructor
   * @extends FunctionParameter
   *
   * @param {Object} [options] Object with the following properties:
   * @param {Terria} options.terria The Terria instance.
   * @param {String} options.id The unique ID of this parameter.
   * @param {String} [options.name] The name of this parameter.  If not specified, the ID is used as the name.
   * @param {String} [options.description] The description of the parameter.
   * @param {RegionProvider|RegionTypeParameter} options.regionProvider The {@link RegionProvider} from which a region may be selected.  This may also
   *                                                                    be a {@link RegionTypeParameter} that specifies the type of region.
   */
  var RegionParameter = function(options) {
      if (!defined(options) || !defined(options.regionProvider)) {
          throw new DeveloperError('options.regionProvider is required.');
      }
  
      FunctionParameter.call(this, options);
  
      this._regionProvider = options.regionProvider;
  };
  
  inherit(FunctionParameter, RegionParameter);
  
  defineProperties(RegionParameter.prototype, {
      /**
       * Gets the type of this parameter.
       * @memberof RegionParameter.prototype
       * @type {String}
       */
      type: {
          get: function() {
              return 'region';
          }
      },
  
      /**
       * Gets or sets the value of this parameter.  The value is an actual region, i.e. from
       * {@link RegionProvider#regions}.  However, it may be set as a string, in which case
       * a string is treated as the ID of a region and the actual region object is looked up
       * with the region provider.
       * @memberof RegionParameter.prototype
       * @member {Object} value
       */
      value: {
          get: FunctionParameter.defaultValueGetter,
          set: function(value) {
              if (typeof value === 'string' || typeof value === 'number') {
                  value = this.findRegionByID(value);
              }
              FunctionParameter.defaultValueSetter.call(this, value);
          }
      },
  
      /**
       * Gets the region provider indicating the type of region that this property holds data for.
       * @memberof RegionParameter.prototype
       * @type {RegionProvider}
       */
      regionProvider: {
          get: function() {
              return RegionTypeParameter.resolveRegionProvider(this._regionProvider);
          }
      },
  
      /**
       * Gets the {@link RegionTypeParameter} that specifies the type of region, if it exists.
       * @memberof RegionParameter.prototype
       * @type {RegionTypeParameter}
       */
      regionTypeParameter: {
          get: function() {
              if (this._regionProvider instanceof RegionTypeParameter) {
                  return this._regionProvider;
              }
          }
      }
  });
  
  /**
   * Finds a region with a given region ID.
   *
   * @param {String} regionID The ID of the region to find.
   * @return {Region} The region, or undefined if no region matching the ID was found.
   */
  RegionParameter.prototype.findRegionByID = function(regionID) {
      var regionProvider = this.regionProvider;
  
      if (typeof regionID === 'string' && regionProvider.regions[0] && typeof regionProvider.regions[0].id === 'number') {
          regionID = parseInt(regionID, 10);
      } else if (typeof regionID === 'string') {
          regionID = regionID.toLowerCase();
          var replacedValue = regionProvider._appliedReplacements.serverReplacements[regionID];
          if (defined(replacedValue)) {
              regionID = replacedValue;
          }
      }
  
      return regionProvider.regions.filter(function(region) {
          return region.id === regionID;
      })[0];
  };
  
  module.exports = RegionParameter;
  