import Layer from './layer';
import debug from '../debug';
import { flatten } from '../utils/flatten';
import { PROP_TYPES_SYMBOL } from '../lifecycle/constants';
const TRACE_RENDER_LAYERS = 'compositeLayer.renderLayers';
export default class CompositeLayer extends Layer {
  get isComposite() {
    return true;
  }

  get isLoaded() {
    return super.isLoaded && this.getSubLayers().every(layer => layer.isLoaded);
  }

  getSubLayers() {
    return this.internalState && this.internalState.subLayers || [];
  }

  initializeState(context) {}

  setState(updateObject) {
    super.setState(updateObject);
    this.setNeedsUpdate();
  }

  getPickingInfo({
    info
  }) {
    const {
      object
    } = info;
    const isDataWrapped = object && object.__source && object.__source.parent && object.__source.parent.id === this.id;

    if (!isDataWrapped) {
      return info;
    }

    info.object = object.__source.object;
    info.index = object.__source.index;
    return info;
  }

  filterSubLayer(context) {
    return true;
  }

  shouldRenderSubLayer(subLayerId, data) {
    return data && data.length;
  }

  getSubLayerClass(subLayerId, DefaultLayerClass) {
    const {
      _subLayerProps: overridingProps
    } = this.props;
    return overridingProps && overridingProps[subLayerId] && overridingProps[subLayerId].type || DefaultLayerClass;
  }

  getSubLayerRow(row, sourceObject, sourceObjectIndex) {
    row.__source = {
      parent: this,
      object: sourceObject,
      index: sourceObjectIndex
    };
    return row;
  }

  getSubLayerAccessor(accessor) {
    if (typeof accessor === 'function') {
      const objectInfo = {
        index: -1,
        data: this.props.data,
        target: []
      };
      return (x, i) => {
        if (x && x.__source) {
          objectInfo.index = x.__source.index;
          return accessor(x.__source.object, objectInfo);
        }

        return accessor(x, i);
      };
    }

    return accessor;
  }

  getSubLayerProps(sublayerProps = {}) {
    var _this$props$updateTri;

    const {
      opacity,
      pickable,
      visible,
      parameters,
      getPolygonOffset,
      highlightedObjectIndex,
      autoHighlight,
      highlightColor,
      coordinateSystem,
      coordinateOrigin,
      wrapLongitude,
      positionFormat,
      modelMatrix,
      extensions,
      fetch,
      operation,
      _subLayerProps: overridingProps
    } = this.props;
    const newProps = {
      id: '',
      updateTriggers: {},
      opacity,
      pickable,
      visible,
      parameters,
      getPolygonOffset,
      highlightedObjectIndex,
      autoHighlight,
      highlightColor,
      coordinateSystem,
      coordinateOrigin,
      wrapLongitude,
      positionFormat,
      modelMatrix,
      extensions,
      fetch,
      operation
    };
    const overridingSublayerProps = overridingProps && sublayerProps.id && overridingProps[sublayerProps.id];
    const overridingSublayerTriggers = overridingSublayerProps && overridingSublayerProps.updateTriggers;
    const sublayerId = sublayerProps.id || 'sublayer';

    if (overridingSublayerProps) {
      const propTypes = this.props[PROP_TYPES_SYMBOL];
      const subLayerPropTypes = sublayerProps.type ? sublayerProps.type._propTypes : {};

      for (const key in overridingSublayerProps) {
        const propType = subLayerPropTypes[key] || propTypes[key];

        if (propType && propType.type === 'accessor') {
          overridingSublayerProps[key] = this.getSubLayerAccessor(overridingSublayerProps[key]);
        }
      }
    }

    Object.assign(newProps, sublayerProps, overridingSublayerProps);
    newProps.id = `${this.props.id}-${sublayerId}`;
    newProps.updateTriggers = {
      all: (_this$props$updateTri = this.props.updateTriggers) === null || _this$props$updateTri === void 0 ? void 0 : _this$props$updateTri.all,
      ...sublayerProps.updateTriggers,
      ...overridingSublayerTriggers
    };

    for (const extension of extensions) {
      const passThroughProps = extension.getSubLayerProps.call(this, extension);

      if (passThroughProps) {
        Object.assign(newProps, passThroughProps, {
          updateTriggers: Object.assign(newProps.updateTriggers, passThroughProps.updateTriggers)
        });
      }
    }

    return newProps;
  }

  _updateAutoHighlight(info) {
    for (const layer of this.getSubLayers()) {
      layer.updateAutoHighlight(info);
    }
  }

  _getAttributeManager() {
    return null;
  }

  _postUpdate(updateParams, forceUpdate) {
    let subLayers = this.internalState.subLayers;
    const shouldUpdate = !subLayers || this.needsUpdate();

    if (shouldUpdate) {
      const subLayersList = this.renderLayers();
      subLayers = flatten(subLayersList, Boolean);
      this.internalState.subLayers = subLayers;
    }

    debug(TRACE_RENDER_LAYERS, this, shouldUpdate, subLayers);

    for (const layer of subLayers) {
      layer.parent = this;
    }
  }

}
CompositeLayer.layerName = 'CompositeLayer';
//# sourceMappingURL=composite-layer.js.map