"use strict";

var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.layerIndexResolver = layerIndexResolver;
exports.default = void 0;

var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));

var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));

var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits"));

var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn"));

var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf"));

var _pass = _interopRequireDefault(require("./pass"));

function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }

function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }

function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }

function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = (0, _getPrototypeOf2.default)(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = (0, _getPrototypeOf2.default)(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return (0, _possibleConstructorReturn2.default)(this, result); }; }

function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }

var LayersPass = function (_Pass) {
  (0, _inherits2.default)(LayersPass, _Pass);

  var _super = _createSuper(LayersPass);

  function LayersPass() {
    var _this;

    (0, _classCallCheck2.default)(this, LayersPass);

    for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
      args[_key] = arguments[_key];
    }

    _this = _super.call.apply(_super, [this].concat(args));
    _this._lastRenderIndex = -1;
    return _this;
  }

  var _proto = LayersPass.prototype;

  _proto.render = function render(options) {
    var _options$clearColor;

    var _this$device$canvasCo = this.device.canvasContext.getDrawingBufferSize(),
        _this$device$canvasCo2 = (0, _slicedToArray2.default)(_this$device$canvasCo, 2),
        width = _this$device$canvasCo2[0],
        height = _this$device$canvasCo2[1];

    var renderPass = this.device.beginRenderPass({
      framebuffer: options.target,
      parameters: {
        viewport: [0, 0, width, height]
      },
      clearColor: (_options$clearColor = options.clearColor) !== null && _options$clearColor !== void 0 ? _options$clearColor : options.clearCanvas ? [0, 0, 0, 0] : false,
      clearDepth: options.clearCanvas ? 1 : undefined
    });

    try {
      return this._drawLayers(renderPass, options);
    } finally {
      renderPass.end();
    }
  };

  _proto._drawLayers = function _drawLayers(renderPass, options) {
    var target = options.target,
        moduleParameters = options.moduleParameters,
        viewports = options.viewports,
        views = options.views,
        onViewportActive = options.onViewportActive,
        _options$clearStack = options.clearStack,
        clearStack = _options$clearStack === void 0 ? true : _options$clearStack;
    options.pass = options.pass || 'unknown';

    if (clearStack) {
      this._lastRenderIndex = -1;
    }

    var renderStats = [];

    var _iterator = _createForOfIteratorHelper(viewports),
        _step;

    try {
      for (_iterator.s(); !(_step = _iterator.n()).done;) {
        var _viewport = _step.value;
        var view = views && views[_viewport.id];
        onViewportActive === null || onViewportActive === void 0 ? void 0 : onViewportActive(_viewport);

        var drawLayerParams = this._getDrawLayerParams(_viewport, options);

        var subViewports = _viewport.subViewports || [_viewport];

        var _iterator2 = _createForOfIteratorHelper(subViewports),
            _step2;

        try {
          for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
            var subViewport = _step2.value;

            var stats = this._drawLayersInViewport(renderPass, {
              target: target,
              moduleParameters: moduleParameters,
              viewport: subViewport,
              view: view,
              pass: options.pass,
              layers: options.layers
            }, drawLayerParams);

            renderStats.push(stats);
          }
        } catch (err) {
          _iterator2.e(err);
        } finally {
          _iterator2.f();
        }
      }
    } catch (err) {
      _iterator.e(err);
    } finally {
      _iterator.f();
    }

    return renderStats;
  };

  _proto._getDrawLayerParams = function _getDrawLayerParams(viewport, _ref) {
    var layers = _ref.layers,
        pass = _ref.pass,
        _ref$isPicking = _ref.isPicking,
        isPicking = _ref$isPicking === void 0 ? false : _ref$isPicking,
        layerFilter = _ref.layerFilter,
        cullRect = _ref.cullRect,
        effects = _ref.effects,
        moduleParameters = _ref.moduleParameters;
    var evaluateShouldDrawOnly = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
    var drawLayerParams = [];
    var indexResolver = layerIndexResolver(this._lastRenderIndex + 1);
    var drawContext = {
      layer: layers[0],
      viewport: viewport,
      isPicking: isPicking,
      renderPass: pass,
      cullRect: cullRect
    };
    var layerFilterCache = {};

    for (var layerIndex = 0; layerIndex < layers.length; layerIndex++) {
      var _layer = layers[layerIndex];

      var shouldDrawLayer = this._shouldDrawLayer(_layer, drawContext, layerFilter, layerFilterCache);

      var layerParam = {
        shouldDrawLayer: shouldDrawLayer
      };

      if (shouldDrawLayer && !evaluateShouldDrawOnly) {
        layerParam.layerRenderIndex = indexResolver(_layer, shouldDrawLayer);
        layerParam.moduleParameters = this._getModuleParameters(_layer, effects, pass, moduleParameters);
        layerParam.layerParameters = this.getLayerParameters(_layer, layerIndex, viewport);
      }

      drawLayerParams[layerIndex] = layerParam;
    }

    return drawLayerParams;
  };

  _proto._drawLayersInViewport = function _drawLayersInViewport(renderPass, _ref2, drawLayerParams) {
    var layers = _ref2.layers,
        globalModuleParameters = _ref2.moduleParameters,
        pass = _ref2.pass,
        target = _ref2.target,
        viewport = _ref2.viewport,
        view = _ref2.view;
    var glViewport = getGLViewport(this.device, {
      moduleParameters: globalModuleParameters,
      target: target,
      viewport: viewport
    });

    if (view && view.props.clear) {
      console.warn("".concat(view.id, ": Per view clearing not yet implemented in deck.gl v9"));
    }

    var renderStatus = {
      totalCount: layers.length,
      visibleCount: 0,
      compositeCount: 0,
      pickableCount: 0
    };
    renderPass.setParameters({
      viewport: glViewport
    });

    for (var layerIndex = 0; layerIndex < layers.length; layerIndex++) {
      var _layer2 = layers[layerIndex];
      var _drawLayerParams$laye = drawLayerParams[layerIndex],
          shouldDrawLayer = _drawLayerParams$laye.shouldDrawLayer,
          layerRenderIndex = _drawLayerParams$laye.layerRenderIndex,
          moduleParameters = _drawLayerParams$laye.moduleParameters,
          layerParameters = _drawLayerParams$laye.layerParameters;

      if (shouldDrawLayer && _layer2.props.pickable) {
        renderStatus.pickableCount++;
      }

      if (_layer2.isComposite) {
        renderStatus.compositeCount++;
      } else if (shouldDrawLayer) {
        renderStatus.visibleCount++;
        this._lastRenderIndex = Math.max(this._lastRenderIndex, layerRenderIndex);
        moduleParameters.viewport = viewport;
        _layer2.context.renderPass = renderPass;

        try {
          _layer2._drawLayer({
            renderPass: renderPass,
            moduleParameters: moduleParameters,
            uniforms: {
              layerIndex: layerRenderIndex
            },
            parameters: layerParameters
          });
        } catch (err) {
          _layer2.raiseError(err, "drawing ".concat(_layer2, " to ").concat(pass));
        }
      }
    }

    return renderStatus;
  };

  _proto.shouldDrawLayer = function shouldDrawLayer(layer) {
    return true;
  };

  _proto.getModuleParameters = function getModuleParameters(layer, effects) {
    return null;
  };

  _proto.getLayerParameters = function getLayerParameters(layer, layerIndex, viewport) {
    return layer.props.parameters;
  };

  _proto._shouldDrawLayer = function _shouldDrawLayer(layer, drawContext, layerFilter, layerFilterCache) {
    var shouldDrawLayer = layer.props.visible && this.shouldDrawLayer(layer);

    if (!shouldDrawLayer) {
      return false;
    }

    drawContext.layer = layer;
    var parent = layer.parent;

    while (parent) {
      if (!parent.props.visible || !parent.filterSubLayer(drawContext)) {
        return false;
      }

      drawContext.layer = parent;
      parent = parent.parent;
    }

    if (layerFilter) {
      var rootLayerId = drawContext.layer.id;

      if (!(rootLayerId in layerFilterCache)) {
        layerFilterCache[rootLayerId] = layerFilter(drawContext);
      }

      if (!layerFilterCache[rootLayerId]) {
        return false;
      }
    }

    layer.activateViewport(drawContext.viewport);
    return true;
  };

  _proto._getModuleParameters = function _getModuleParameters(layer, effects, pass, overrides) {
    var _layer$internalState;

    var devicePixelRatio = this.device.canvasContext.cssToDeviceRatio();
    var moduleParameters = Object.assign(Object.create(((_layer$internalState = layer.internalState) === null || _layer$internalState === void 0 ? void 0 : _layer$internalState.propsInTransition) || layer.props), {
      autoWrapLongitude: layer.wrapLongitude,
      viewport: layer.context.viewport,
      mousePosition: layer.context.mousePosition,
      picking: {
        isActive: 0
      },
      devicePixelRatio: devicePixelRatio
    });

    if (effects) {
      var _iterator3 = _createForOfIteratorHelper(effects),
          _step3;

      try {
        for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
          var _effect$getModulePara;

          var effect = _step3.value;
          Object.assign(moduleParameters, (_effect$getModulePara = effect.getModuleParameters) === null || _effect$getModulePara === void 0 ? void 0 : _effect$getModulePara.call(effect, layer));
        }
      } catch (err) {
        _iterator3.e(err);
      } finally {
        _iterator3.f();
      }
    }

    return Object.assign(moduleParameters, this.getModuleParameters(layer, effects), overrides);
  };

  return LayersPass;
}(_pass.default);

exports.default = LayersPass;

function layerIndexResolver() {
  var startIndex = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0;
  var layerIndices = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
  var resolvers = {};

  var resolveLayerIndex = function resolveLayerIndex(layer, isDrawn) {
    var indexOverride = layer.props._offset;
    var layerId = layer.id;
    var parentId = layer.parent && layer.parent.id;
    var index;

    if (parentId && !(parentId in layerIndices)) {
      resolveLayerIndex(layer.parent, false);
    }

    if (parentId in resolvers) {
      var resolver = resolvers[parentId] = resolvers[parentId] || layerIndexResolver(layerIndices[parentId], layerIndices);
      index = resolver(layer, isDrawn);
      resolvers[layerId] = resolver;
    } else if (Number.isFinite(indexOverride)) {
      index = indexOverride + (layerIndices[parentId] || 0);
      resolvers[layerId] = null;
    } else {
      index = startIndex;
    }

    if (isDrawn && index >= startIndex) {
      startIndex = index + 1;
    }

    layerIndices[layerId] = index;
    return index;
  };

  return resolveLayerIndex;
}

function getGLViewport(device, _ref3) {
  var moduleParameters = _ref3.moduleParameters,
      target = _ref3.target,
      viewport = _ref3.viewport;
  var pixelRatio = moduleParameters && moduleParameters.devicePixelRatio || device.canvasContext.cssToDeviceRatio();

  var _device$canvasContext = device.canvasContext.getDrawingBufferSize(),
      _device$canvasContext2 = (0, _slicedToArray2.default)(_device$canvasContext, 2),
      drawingBufferHeight = _device$canvasContext2[1];

  var height = target ? target.height : drawingBufferHeight;
  var dimensions = viewport;
  return [dimensions.x * pixelRatio, height - (dimensions.y + dimensions.height) * pixelRatio, dimensions.width * pixelRatio, dimensions.height * pixelRatio];
}
//# sourceMappingURL=layers-pass.js.map