'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});

var _index = require('./index.js');

var _index2 = _interopRequireDefault(_index);

var _size = require('./size.js');

var _size2 = _interopRequireDefault(_size);

var _extent = require('./extent.js');

var _extent2 = _interopRequireDefault(_extent);

var _corner = require('./extent/corner.js');

var _corner2 = _interopRequireDefault(_corner);

var _obj = require('./obj.js');

var _obj2 = _interopRequireDefault(_obj);

var _proj = require('./proj.js');

var _proj2 = _interopRequireDefault(_proj);

var _units = require('./proj/units.js');

var _units2 = _interopRequireDefault(_units);

var _tilegrid = require('./tilegrid/tilegrid.js');

var _tilegrid2 = _interopRequireDefault(_tilegrid);

function _interopRequireDefault(obj) {
  return obj && obj.__esModule ? obj : { default: obj };
}

var _ol_tilegrid_ = {};

/**
 * @param {ol.proj.Projection} projection Projection.
 * @return {!ol.tilegrid.TileGrid} Default tile grid for the passed projection.
 */
_ol_tilegrid_.getForProjection = function (projection) {
  var tileGrid = projection.getDefaultTileGrid();
  if (!tileGrid) {
    tileGrid = _ol_tilegrid_.createForProjection(projection);
    projection.setDefaultTileGrid(tileGrid);
  }
  return tileGrid;
};

/**
 * @param {ol.tilegrid.TileGrid} tileGrid Tile grid.
 * @param {ol.TileCoord} tileCoord Tile coordinate.
 * @param {ol.proj.Projection} projection Projection.
 * @return {ol.TileCoord} Tile coordinate.
 */
_ol_tilegrid_.wrapX = function (tileGrid, tileCoord, projection) {
  var z = tileCoord[0];
  var center = tileGrid.getTileCoordCenter(tileCoord);
  var projectionExtent = _ol_tilegrid_.extentFromProjection(projection);
  if (!_extent2.default.containsCoordinate(projectionExtent, center)) {
    var worldWidth = _extent2.default.getWidth(projectionExtent);
    var worldsAway = Math.ceil((projectionExtent[0] - center[0]) / worldWidth);
    center[0] += worldWidth * worldsAway;
    return tileGrid.getTileCoordForCoordAndZ(center, z);
  } else {
    return tileCoord;
  }
};

/**
 * @param {ol.Extent} extent Extent.
 * @param {number=} opt_maxZoom Maximum zoom level (default is
 *     ol.DEFAULT_MAX_ZOOM).
 * @param {number|ol.Size=} opt_tileSize Tile size (default uses
 *     ol.DEFAULT_TILE_SIZE).
 * @param {ol.extent.Corner=} opt_corner Extent corner (default is
 *     ol.extent.Corner.TOP_LEFT).
 * @return {!ol.tilegrid.TileGrid} TileGrid instance.
 */
_ol_tilegrid_.createForExtent = function (extent, opt_maxZoom, opt_tileSize, opt_corner) {
  var corner = opt_corner !== undefined ? opt_corner : _corner2.default.TOP_LEFT;

  var resolutions = _ol_tilegrid_.resolutionsFromExtent(extent, opt_maxZoom, opt_tileSize);

  return new _tilegrid2.default({
    extent: extent,
    origin: _extent2.default.getCorner(extent, corner),
    resolutions: resolutions,
    tileSize: opt_tileSize
  });
};

/**
 * Creates a tile grid with a standard XYZ tiling scheme.
 * @param {olx.tilegrid.XYZOptions=} opt_options Tile grid options.
 * @return {!ol.tilegrid.TileGrid} Tile grid instance.
 * @api
 */
_ol_tilegrid_.createXYZ = function (opt_options) {
  var options = /** @type {olx.tilegrid.TileGridOptions} */{};
  _obj2.default.assign(options, opt_options !== undefined ? opt_options : /** @type {olx.tilegrid.XYZOptions} */{});
  if (options.extent === undefined) {
    options.extent = _proj2.default.get('EPSG:3857').getExtent();
  }
  options.resolutions = _ol_tilegrid_.resolutionsFromExtent(options.extent, options.maxZoom, options.tileSize);
  delete options.maxZoom;

  return new _tilegrid2.default(options);
};

/**
 * Create a resolutions array from an extent.  A zoom factor of 2 is assumed.
 * @param {ol.Extent} extent Extent.
 * @param {number=} opt_maxZoom Maximum zoom level (default is
 *     ol.DEFAULT_MAX_ZOOM).
 * @param {number|ol.Size=} opt_tileSize Tile size (default uses
 *     ol.DEFAULT_TILE_SIZE).
 * @return {!Array.<number>} Resolutions array.
 */
_ol_tilegrid_.resolutionsFromExtent = function (extent, opt_maxZoom, opt_tileSize) {
  var maxZoom = opt_maxZoom !== undefined ? opt_maxZoom : _index2.default.DEFAULT_MAX_ZOOM;

  var height = _extent2.default.getHeight(extent);
  var width = _extent2.default.getWidth(extent);

  var tileSize = _size2.default.toSize(opt_tileSize !== undefined ? opt_tileSize : _index2.default.DEFAULT_TILE_SIZE);
  var maxResolution = Math.max(width / tileSize[0], height / tileSize[1]);

  var length = maxZoom + 1;
  var resolutions = new Array(length);
  for (var z = 0; z < length; ++z) {
    resolutions[z] = maxResolution / Math.pow(2, z);
  }
  return resolutions;
};

/**
 * @param {ol.ProjectionLike} projection Projection.
 * @param {number=} opt_maxZoom Maximum zoom level (default is
 *     ol.DEFAULT_MAX_ZOOM).
 * @param {number|ol.Size=} opt_tileSize Tile size (default uses
 *     ol.DEFAULT_TILE_SIZE).
 * @param {ol.extent.Corner=} opt_corner Extent corner (default is
 *     ol.extent.Corner.BOTTOM_LEFT).
 * @return {!ol.tilegrid.TileGrid} TileGrid instance.
 */
_ol_tilegrid_.createForProjection = function (projection, opt_maxZoom, opt_tileSize, opt_corner) {
  var extent = _ol_tilegrid_.extentFromProjection(projection);
  return _ol_tilegrid_.createForExtent(extent, opt_maxZoom, opt_tileSize, opt_corner);
};

/**
 * Generate a tile grid extent from a projection.  If the projection has an
 * extent, it is used.  If not, a global extent is assumed.
 * @param {ol.ProjectionLike} projection Projection.
 * @return {ol.Extent} Extent.
 */
_ol_tilegrid_.extentFromProjection = function (projection) {
  projection = _proj2.default.get(projection);
  var extent = projection.getExtent();
  if (!extent) {
    var half = 180 * _proj2.default.METERS_PER_UNIT[_units2.default.DEGREES] / projection.getMetersPerUnit();
    extent = _extent2.default.createOrUpdate(-half, -half, half, half);
  }
  return extent;
};
exports.default = _ol_tilegrid_;
module.exports = exports['default'];