'use strict';

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

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

var _index2 = _interopRequireDefault(_index);

var _tileurlfunction = require('../tileurlfunction.js');

var _tileurlfunction2 = _interopRequireDefault(_tileurlfunction);

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

var _extent2 = _interopRequireDefault(_extent);

var _net = require('../net.js');

var _net2 = _interopRequireDefault(_net);

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

var _proj2 = _interopRequireDefault(_proj);

var _state = require('../source/state.js');

var _state2 = _interopRequireDefault(_state);

var _tileimage = require('../source/tileimage.js');

var _tileimage2 = _interopRequireDefault(_tileimage);

var _tilecoord = require('../tilecoord.js');

var _tilecoord2 = _interopRequireDefault(_tilecoord);

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

var _tilegrid2 = _interopRequireDefault(_tilegrid);

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

/**
 * @classdesc
 * Layer source for Bing Maps tile data.
 *
 * @constructor
 * @extends {ol.source.TileImage}
 * @param {olx.source.BingMapsOptions} options Bing Maps options.
 * @api
 */
var _ol_source_BingMaps_ = function (options) {

  /**
   * @private
   * @type {boolean}
   */
  this.hidpi_ = options.hidpi !== undefined ? options.hidpi : false;

  _tileimage2.default.call(this, {
    cacheSize: options.cacheSize,
    crossOrigin: 'anonymous',
    opaque: true,
    projection: _proj2.default.get('EPSG:3857'),
    reprojectionErrorThreshold: options.reprojectionErrorThreshold,
    state: _state2.default.LOADING,
    tileLoadFunction: options.tileLoadFunction,
    tilePixelRatio: this.hidpi_ ? 2 : 1,
    wrapX: options.wrapX !== undefined ? options.wrapX : true,
    transition: options.transition
  });

  /**
   * @private
   * @type {string}
   */
  this.culture_ = options.culture !== undefined ? options.culture : 'en-us';

  /**
   * @private
   * @type {number}
   */
  this.maxZoom_ = options.maxZoom !== undefined ? options.maxZoom : -1;

  /**
   * @private
   * @type {string}
   */
  this.apiKey_ = options.key;

  /**
   * @private
   * @type {string}
   */
  this.imagerySet_ = options.imagerySet;

  var url = 'https://dev.virtualearth.net/REST/v1/Imagery/Metadata/' + this.imagerySet_ + '?uriScheme=https&include=ImageryProviders&key=' + this.apiKey_ + '&c=' + this.culture_;

  _net2.default.jsonp(url, this.handleImageryMetadataResponse.bind(this), undefined, 'jsonp');
};

_index2.default.inherits(_ol_source_BingMaps_, _tileimage2.default);

/**
 * The attribution containing a link to the Microsoft® Bing™ Maps Platform APIs’
 * Terms Of Use.
 * @const
 * @type {string}
 * @api
 */
_ol_source_BingMaps_.TOS_ATTRIBUTION = '<a class="ol-attribution-bing-tos" ' + 'href="https://www.microsoft.com/maps/product/terms.html">' + 'Terms of Use</a>';

/**
 * Get the api key used for this source.
 *
 * @return {string} The api key.
 * @api
 */
_ol_source_BingMaps_.prototype.getApiKey = function () {
  return this.apiKey_;
};

/**
 * Get the imagery set associated with this source.
 *
 * @return {string} The imagery set.
 * @api
 */
_ol_source_BingMaps_.prototype.getImagerySet = function () {
  return this.imagerySet_;
};

/**
 * @param {BingMapsImageryMetadataResponse} response Response.
 */
_ol_source_BingMaps_.prototype.handleImageryMetadataResponse = function (response) {
  if (response.statusCode != 200 || response.statusDescription != 'OK' || response.authenticationResultCode != 'ValidCredentials' || response.resourceSets.length != 1 || response.resourceSets[0].resources.length != 1) {
    this.setState(_state2.default.ERROR);
    return;
  }

  var brandLogoUri = response.brandLogoUri;
  if (brandLogoUri.indexOf('https') == -1) {
    brandLogoUri = brandLogoUri.replace('http', 'https');
  }
  //var copyright = response.copyright;  // FIXME do we need to display this?
  var resource = response.resourceSets[0].resources[0];
  var maxZoom = this.maxZoom_ == -1 ? resource.zoomMax : this.maxZoom_;

  var sourceProjection = this.getProjection();
  var extent = _tilegrid2.default.extentFromProjection(sourceProjection);
  var tileSize = resource.imageWidth == resource.imageHeight ? resource.imageWidth : [resource.imageWidth, resource.imageHeight];
  var tileGrid = _tilegrid2.default.createXYZ({
    extent: extent,
    minZoom: resource.zoomMin,
    maxZoom: maxZoom,
    tileSize: tileSize / (this.hidpi_ ? 2 : 1)
  });
  this.tileGrid = tileGrid;

  var culture = this.culture_;
  var hidpi = this.hidpi_;
  this.tileUrlFunction = _tileurlfunction2.default.createFromTileUrlFunctions(resource.imageUrlSubdomains.map(function (subdomain) {
    var quadKeyTileCoord = [0, 0, 0];
    var imageUrl = resource.imageUrl.replace('{subdomain}', subdomain).replace('{culture}', culture);
    return (
      /**
       * @param {ol.TileCoord} tileCoord Tile coordinate.
       * @param {number} pixelRatio Pixel ratio.
       * @param {ol.proj.Projection} projection Projection.
       * @return {string|undefined} Tile URL.
       */
      function (tileCoord, pixelRatio, projection) {
        if (!tileCoord) {
          return undefined;
        } else {
          _tilecoord2.default.createOrUpdate(tileCoord[0], tileCoord[1], -tileCoord[2] - 1, quadKeyTileCoord);
          var url = imageUrl;
          if (hidpi) {
            url += '&dpi=d1&device=mobile';
          }
          return url.replace('{quadkey}', _tilecoord2.default.quadKey(quadKeyTileCoord));
        }
      }
    );
  }));

  if (resource.imageryProviders) {
    var transform = _proj2.default.getTransformFromProjections(_proj2.default.get('EPSG:4326'), this.getProjection());

    this.setAttributions(function (frameState) {
      var attributions = [];
      var zoom = frameState.viewState.zoom;
      resource.imageryProviders.map(function (imageryProvider) {
        var intersects = false;
        var coverageAreas = imageryProvider.coverageAreas;
        for (var i = 0, ii = coverageAreas.length; i < ii; ++i) {
          var coverageArea = coverageAreas[i];
          if (zoom >= coverageArea.zoomMin && zoom <= coverageArea.zoomMax) {
            var bbox = coverageArea.bbox;
            var epsg4326Extent = [bbox[1], bbox[0], bbox[3], bbox[2]];
            var extent = _extent2.default.applyTransform(epsg4326Extent, transform);
            if (_extent2.default.intersects(extent, frameState.extent)) {
              intersects = true;
              break;
            }
          }
        }
        if (intersects) {
          attributions.push(imageryProvider.attribution);
        }
      });

      attributions.push(_ol_source_BingMaps_.TOS_ATTRIBUTION);
      return attributions;
    });
  }

  this.setLogo(brandLogoUri);

  this.setState(_state2.default.READY);
};
exports.default = _ol_source_BingMaps_;
module.exports = exports['default'];