text: goog.provide('ol.TileRange');
  
  goog.require('goog.asserts');
  goog.require('ol.Size');
  goog.require('ol.TileCoord');
  
  
  
  /**
   * A representation of a contiguous block of tiles.  A tile range is specified
   * by its min/max tile coordinates and is inclusive of coordinates.
   *
   * @constructor
   * @param {number} minX Minimum X.
   * @param {number} maxX Maximum X.
   * @param {number} minY Minimum Y.
   * @param {number} maxY Maximum Y.
   * @struct
   */
  ol.TileRange = function(minX, maxX, minY, maxY) {
  
    /**
     * @type {number}
     */
    this.minX = minX;
  
    /**
     * @type {number}
     */
    this.maxX = maxX;
  
    /**
     * @type {number}
     */
    this.minY = minY;
  
    /**
     * @type {number}
     */
    this.maxY = maxY;
  
  };
  
  
  /**
   * @param {...ol.TileCoord} var_args Tile coordinates.
   * @return {!ol.TileRange} Bounding tile box.
   */
  ol.TileRange.boundingTileRange = function(var_args) {
    var tileCoord0 = /** @type {ol.TileCoord} */ (arguments[0]);
    var tileCoord0Z = tileCoord0[0];
    var tileCoord0X = tileCoord0[1];
    var tileCoord0Y = tileCoord0[2];
    var tileRange = new ol.TileRange(tileCoord0X, tileCoord0X,
                                     tileCoord0Y, tileCoord0Y);
    var i, ii, tileCoord, tileCoordX, tileCoordY, tileCoordZ;
    for (i = 1, ii = arguments.length; i < ii; ++i) {
      tileCoord = /** @type {ol.TileCoord} */ (arguments[i]);
      tileCoordZ = tileCoord[0];
      tileCoordX = tileCoord[1];
      tileCoordY = tileCoord[2];
      goog.asserts.assert(tileCoordZ == tileCoord0Z);
      tileRange.minX = Math.min(tileRange.minX, tileCoordX);
      tileRange.maxX = Math.max(tileRange.maxX, tileCoordX);
      tileRange.minY = Math.min(tileRange.minY, tileCoordY);
      tileRange.maxY = Math.max(tileRange.maxY, tileCoordY);
    }
    return tileRange;
  };
  
  
  /**
   * @param {number} minX Minimum X.
   * @param {number} maxX Maximum X.
   * @param {number} minY Minimum Y.
   * @param {number} maxY Maximum Y.
   * @param {ol.TileRange|undefined} tileRange TileRange.
   * @return {ol.TileRange} Tile range.
   */
  ol.TileRange.createOrUpdate = function(minX, maxX, minY, maxY, tileRange) {
    if (goog.isDef(tileRange)) {
      tileRange.minX = minX;
      tileRange.maxX = maxX;
      tileRange.minY = minY;
      tileRange.maxY = maxY;
      return tileRange;
    } else {
      return new ol.TileRange(minX, maxX, minY, maxY);
    }
  };
  
  
  /**
   * @param {ol.TileCoord} tileCoord Tile coordinate.
   * @return {boolean} Contains tile coordinate.
   */
  ol.TileRange.prototype.contains = function(tileCoord) {
    return this.containsXY(tileCoord[1], tileCoord[2]);
  };
  
  
  /**
   * @param {ol.TileRange} tileRange Tile range.
   * @return {boolean} Contains.
   */
  ol.TileRange.prototype.containsTileRange = function(tileRange) {
    return this.minX <= tileRange.minX && tileRange.maxX <= this.maxX &&
        this.minY <= tileRange.minY && tileRange.maxY <= this.maxY;
  };
  
  
  /**
   * @param {number} x Tile coordinate x.
   * @param {number} y Tile coordinate y.
   * @return {boolean} Contains coordinate.
   */
  ol.TileRange.prototype.containsXY = function(x, y) {
    return this.minX <= x && x <= this.maxX && this.minY <= y && y <= this.maxY;
  };
  
  
  /**
   * @param {ol.TileRange} tileRange Tile range.
   * @return {boolean} Equals.
   */
  ol.TileRange.prototype.equals = function(tileRange) {
    return this.minX == tileRange.minX && this.minY == tileRange.minY &&
        this.maxX == tileRange.maxX && this.maxY == tileRange.maxY;
  };
  
  
  /**
   * @param {ol.TileRange} tileRange Tile range.
   */
  ol.TileRange.prototype.extend = function(tileRange) {
    if (tileRange.minX < this.minX) {
      this.minX = tileRange.minX;
    }
    if (tileRange.maxX > this.maxX) {
      this.maxX = tileRange.maxX;
    }
    if (tileRange.minY < this.minY) {
      this.minY = tileRange.minY;
    }
    if (tileRange.maxY > this.maxY) {
      this.maxY = tileRange.maxY;
    }
  };
  
  
  /**
   * @return {number} Height.
   */
  ol.TileRange.prototype.getHeight = function() {
    return this.maxY - this.minY + 1;
  };
  
  
  /**
   * @return {ol.Size} Size.
   */
  ol.TileRange.prototype.getSize = function() {
    return [this.getWidth(), this.getHeight()];
  };
  
  
  /**
   * @return {number} Width.
   */
  ol.TileRange.prototype.getWidth = function() {
    return this.maxX - this.minX + 1;
  };
  
  
  /**
   * @param {ol.TileRange} tileRange Tile range.
   * @return {boolean} Intersects.
   */
  ol.TileRange.prototype.intersects = function(tileRange) {
    return this.minX <= tileRange.maxX &&
        this.maxX >= tileRange.minX &&
        this.minY <= tileRange.maxY &&
        this.maxY >= tileRange.minY;
  };
  