/*
 * Copyright (C) 2018 Robert Bosch GmbH Copyright (C) 2018 Robert Bosch Manufacturing Solutions GmbH, Germany. All rights reserved.
 */

import { Injectable } from '@angular/core';
import { Collection, Feature } from 'ol';
import { GeoJSON } from 'ol/format';
import { Vector as VectorLayer } from 'ol/layer';
import { bbox } from 'ol/loadingstrategy';
import type { ProjectionLike } from 'ol/proj';
import { Vector as VectorSource } from 'ol/source';
import { Options as VectorSourceOptions } from 'ol/source/Vector';
import { Projections } from '../projection.utils';

@Injectable({
  providedIn: 'root',
})
export class OpenLayersLayerFactory {
  //// LAYERS

  // eslint-disable-next-line @typescript-eslint/ban-types
  createVectorLayer(layerSource: VectorSource, zIndex: number, options?: Object): VectorLayer {
    return new VectorLayer({
      source: layerSource,
      zIndex: zIndex,
      ...options,
    });
  }

  createGeoJSONLayer(
    // eslint-disable-next-line @typescript-eslint/ban-types
    geojsonObject: ArrayBuffer | Document | Node | object | string,
    mapProjection: ProjectionLike,
    zIndex: number
  ): VectorLayer {
    return this.createVectorLayer(
      this.createVectorSource(this.createGeoJSONReader(mapProjection).readFeatures(geojsonObject)),
      zIndex
    );
  }

  //// LAYER SOURCES

  createVectorSource(features: Feature[] | Collection<Feature> = [], options?: VectorSourceOptions): VectorSource {
    return new VectorSource({
      strategy: bbox,
      features: features,
      ...options,
    });
  }

  //// FEATURE READER

  createGeoJSONReader(mapProjection: ProjectionLike): GeoJSON {
    return new GeoJSON({
      dataProjection: Projections.GEOJSON, // EPSG:4326 / WGS84, the coordinate system of GeoJSON features defined by the RFC7946
      featureProjection: mapProjection,
    });
  }
}
