// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

part of google_maps_flutter_web;

/// Type used when passing an override to the _createMap function.
@visibleForTesting
typedef DebugCreateMapFunction = gmaps.GMap Function(
    HtmlElement div, gmaps.MapOptions options);

/// Encapsulates a [gmaps.GMap], its events, and where in the DOM it's rendered.
class GoogleMapController {
  // The internal ID of the map. Used to broadcast events, DOM IDs and everything where a unique ID is needed.
  final int _mapId;

  // The raw options passed by the user, before converting to gmaps.
  // Caching this allows us to re-create the map faithfully when needed.
  Map<String, dynamic> _rawOptions = {
    'options': {},
  };

  // Creates the 'viewType' for the _widget
  String _getViewType(int mapId) => 'plugins.flutter.io/google_maps_$mapId';

  // The Flutter widget that contains the rendered Map.
  HtmlElementView _widget;
  HtmlElement _div;

  /// The Flutter widget that will contain the rendered Map. Used for caching.
  HtmlElementView get widget {
    if (_widget == null && !_streamController.isClosed) {
      _widget = HtmlElementView(
        viewType: _getViewType(_mapId),
      );
    }
    return _widget;
  }

  // The currently-enabled traffic layer.
  gmaps.TrafficLayer _trafficLayer;

  /// A getter for the current traffic layer. Only for tests.
  @visibleForTesting
  gmaps.TrafficLayer get trafficLayer => _trafficLayer;

  // The underlying GMap instance. This is the interface with the JS SDK.
  gmaps.GMap _googleMap;

  // The StreamController used by this controller and the geometry ones.
  final StreamController<MapEvent> _streamController;

  /// The Stream over which this controller broadcasts events.
  Stream<MapEvent> get events => _streamController.stream;

  // Geometry controllers, for different features of the map.
  CirclesController _circlesController;
  PolygonsController _polygonsController;
  PolylinesController _polylinesController;
  MarkersController _markersController;
  // Keeps track if _attachGeometryControllers has been called or not.
  bool _controllersBoundToMap = false;

  // Keeps track if the map is moving or not.
  bool _mapIsMoving = false;

  /// Initializes the GMap, and the sub-controllers related to it. Wires events.
  GoogleMapController({
    @required int mapId,
    @required StreamController<MapEvent> streamController,
    @required Map<String, dynamic> rawOptions,
  })  : this._mapId = mapId,
        this._streamController = streamController,
        this._rawOptions = rawOptions {
    _circlesController = CirclesController(stream: this._streamController);
    _polygonsController = PolygonsController(stream: this._streamController);
    _polylinesController = PolylinesController(stream: this._streamController);
    _markersController = MarkersController(stream: this._streamController);

    // Register the view factory that will hold the `_div` that holds the map in the DOM.
    // The `_div` needs to be created outside of the ViewFactory (and cached!) so we can
    // use it to create the [gmaps.GMap] in the `init()` method of this class.
    _div = DivElement()..id = _getViewType(mapId);

    ui.platformViewRegistry.registerViewFactory(
      _getViewType(mapId),
      (int viewId) => _div,
    );
  }

  /// Overrides certain properties to install mocks defined during testing.
  @visibleForTesting
  void debugSetOverrides({
    DebugCreateMapFunction createMap,
    MarkersController markers,
    CirclesController circles,
    PolygonsController polygons,
    PolylinesController polylines,
  }) {
    _overrideCreateMap = createMap;
    _markersController = markers ?? _markersController;
    _circlesController = circles ?? _circlesController;
    _polygonsController = polygons ?? _polygonsController;
    _polylinesController = polylines ?? _polylinesController;
  }

  DebugCreateMapFunction _overrideCreateMap;

  gmaps.GMap _createMap(HtmlElement div, gmaps.MapOptions options) {
    if (_overrideCreateMap != null) {
      return _overrideCreateMap(div, options);
    }
    return gmaps.GMap(div, options);
  }

  /// Initializes the [gmaps.GMap] instance from the stored `rawOptions`.
  ///
  /// This method actually renders the GMap into the cached `_div`. This is
  /// called by the [GoogleMapsPlugin.init] method when appropriate.
  ///
  /// Failure to call this method would result in the GMap not rendering at all,
  /// and most of the public methods on this class no-op'ing.
  void init() {
    var options = _rawOptionsToGmapsOptions(_rawOptions);
    // Initial position can only to be set here!
    options = _applyInitialPosition(_rawOptions, options);

    // Create the map...
    _googleMap = _createMap(_div, options);

    _attachMapEvents(_googleMap);
    _attachGeometryControllers(_googleMap);

    _renderInitialGeometry(
      markers: _rawOptionsToInitialMarkers(_rawOptions),
      circles: _rawOptionsToInitialCircles(_rawOptions),
      polygons: _rawOptionsToInitialPolygons(_rawOptions),
      polylines: _rawOptionsToInitialPolylines(_rawOptions),
    );

    _setTrafficLayer(_googleMap, _isTrafficLayerEnabled(_rawOptions));
  }

  // Funnels map gmap events into the plugin's stream controller.
  void _attachMapEvents(gmaps.GMap map) {
    map.onClick.listen((event) {
      _streamController.add(
        MapTapEvent(_mapId, _gmLatLngToLatLng(event.latLng)),
      );
    });
    map.onRightclick.listen((event) {
      _streamController.add(
        MapLongPressEvent(_mapId, _gmLatLngToLatLng(event.latLng)),
      );
    });
    map.onBoundsChanged.listen((event) {
      if (!_mapIsMoving) {
        _mapIsMoving = true;
        _streamController.add(CameraMoveStartedEvent(_mapId));
      }
      _streamController.add(
        CameraMoveEvent(_mapId, _gmViewportToCameraPosition(map)),
      );
    });
    map.onIdle.listen((event) {
      _mapIsMoving = false;
      _streamController.add(CameraIdleEvent(_mapId));
    });
  }

  // Binds the Geometry controllers to a map instance
  void _attachGeometryControllers(gmaps.GMap map) {
    // Now we can add the initial geometry.
    // And bind the (ready) map instance to the other geometry controllers.
    _circlesController.bindToMap(_mapId, map);
    _polygonsController.bindToMap(_mapId, map);
    _polylinesController.bindToMap(_mapId, map);
    _markersController.bindToMap(_mapId, map);
    _controllersBoundToMap = true;
  }

  // Renders the initial sets of geometry.
  void _renderInitialGeometry({
    Set<Marker> markers,
    Set<Circle> circles,
    Set<Polygon> polygons,
    Set<Polyline> polylines,
  }) {
    assert(
        _controllersBoundToMap,
        'Geometry controllers must be bound to a map before any geometry can ' +
            'be added to them. Ensure _attachGeometryControllers is called first.');
    _markersController.addMarkers(markers);
    _circlesController.addCircles(circles);
    _polygonsController.addPolygons(polygons);
    _polylinesController.addPolylines(polylines);
  }

  // Merges new options coming from the plugin into the `key` entry of the _rawOptions map.
  //
  // By default: `key` is 'options'.
  //
  // Returns the updated _rawOptions object.
  Map<String, dynamic> _mergeRawOptions(
    Map<String, dynamic> newOptions, {
    String key = 'options',
  }) {
    _rawOptions[key] = <String, dynamic>{
      ...(_rawOptions[key] ?? {}),
      ...newOptions,
    };
    return _rawOptions;
  }

  /// Updates the map options from a `Map<String, dynamic>`.
  ///
  /// This method converts the map into the proper [gmaps.MapOptions]
  void updateRawOptions(Map<String, dynamic> optionsUpdate) {
    final newOptions = _mergeRawOptions(optionsUpdate);

    _setOptions(_rawOptionsToGmapsOptions(newOptions));
    _setTrafficLayer(_googleMap, _isTrafficLayerEnabled(newOptions));
  }

  // Sets new [gmaps.MapOptions] on the wrapped map.
  void _setOptions(gmaps.MapOptions options) {
    _googleMap?.options = options;
  }

  // Attaches/detaches a Traffic Layer on the passed `map` if `attach` is true/false.
  void _setTrafficLayer(gmaps.GMap map, bool attach) {
    if (attach && _trafficLayer == null) {
      _trafficLayer = gmaps.TrafficLayer();
      _trafficLayer.set('map', map);
    }
    if (!attach && _trafficLayer != null) {
      _trafficLayer.set('map', null);
      _trafficLayer = null;
    }
  }

  // _googleMap manipulation
  // Viewport

  /// Returns the [LatLngBounds] of the current viewport.
  Future<LatLngBounds> getVisibleRegion() async {
    return _gmLatLngBoundsTolatLngBounds(await _googleMap.bounds);
  }

  /// Returns the [ScreenCoordinate] for a given viewport [LatLng].
  Future<ScreenCoordinate> getScreenCoordinate(LatLng latLng) async {
    final point =
        _googleMap.projection.fromLatLngToPoint(_latLngToGmLatLng(latLng));
    return ScreenCoordinate(x: point.x, y: point.y);
  }

  /// Returns the [LatLng] for a `screenCoordinate` (in pixels) of the viewport.
  Future<LatLng> getLatLng(ScreenCoordinate screenCoordinate) async {
    final gmaps.LatLng latLng =
        _pixelToLatLng(_googleMap, screenCoordinate.x, screenCoordinate.y);
    return _gmLatLngToLatLng(latLng);
  }

  /// Applies a `cameraUpdate` to the current viewport.
  Future<void> moveCamera(CameraUpdate cameraUpdate) async {
    return _applyCameraUpdate(_googleMap, cameraUpdate);
  }

  /// Returns the zoom level of the current viewport.
  Future<double> getZoomLevel() async => _googleMap.zoom.toDouble();

  // Geometry manipulation

  /// Applies [CircleUpdates] to the currently managed circles.
  void updateCircles(CircleUpdates updates) {
    _circlesController?.addCircles(updates.circlesToAdd);
    _circlesController?.changeCircles(updates.circlesToChange);
    _circlesController?.removeCircles(updates.circleIdsToRemove);
  }

  /// Applies [PolygonUpdates] to the currently managed polygons.
  void updatePolygons(PolygonUpdates updates) {
    _polygonsController?.addPolygons(updates.polygonsToAdd);
    _polygonsController?.changePolygons(updates.polygonsToChange);
    _polygonsController?.removePolygons(updates.polygonIdsToRemove);
  }

  /// Applies [PolylineUpdates] to the currently managed lines.
  void updatePolylines(PolylineUpdates updates) {
    _polylinesController?.addPolylines(updates.polylinesToAdd);
    _polylinesController?.changePolylines(updates.polylinesToChange);
    _polylinesController?.removePolylines(updates.polylineIdsToRemove);
  }

  /// Applies [MarkerUpdates] to the currently managed markers.
  void updateMarkers(MarkerUpdates updates) {
    _markersController?.addMarkers(updates.markersToAdd);
    _markersController?.changeMarkers(updates.markersToChange);
    _markersController?.removeMarkers(updates.markerIdsToRemove);
  }

  /// Shows the [InfoWindow] of the marker identified by its [MarkerId].
  void showInfoWindow(MarkerId markerId) {
    _markersController?.showMarkerInfoWindow(markerId);
  }

  /// Hides the [InfoWindow] of the marker identified by its [MarkerId].
  void hideInfoWindow(MarkerId markerId) {
    _markersController?.hideMarkerInfoWindow(markerId);
  }

  /// Returns true if the [InfoWindow] of the marker identified by [MarkerId] is shown.
  bool isInfoWindowShown(MarkerId markerId) {
    return _markersController?.isInfoWindowShown(markerId);
  }

  // Cleanup

  /// Disposes of this controller and its resources.
  void dispose() {
    _widget = null;
    _googleMap = null;
    _circlesController = null;
    _polygonsController = null;
    _polylinesController = null;
    _markersController = null;
    _streamController.close();
  }
}
