import {IMapAdapter, MapOptions, LatLng, getLngLat, Zone, RouteOptions} from './map-adapter.interface';
import { LibreAdapter } from './libre-adapter';
import { LeafletAdapter } from './leaflet-adapter';

export class MapFacade implements IMapAdapter<any> {
  private readonly adapter: IMapAdapter<any>;
  private readonly leafletZoomOffset = 1;

  constructor(forceRaster: boolean, webglAvailable: boolean) {
    if (forceRaster || !webglAvailable) {
      this.adapter = new LeafletAdapter();
    } else {
      this.adapter = new LibreAdapter();
    }
  }

  init(container: HTMLElement, options: MapOptions): void {
    if (this.adapter instanceof LeafletAdapter)
      options.zoom += this.leafletZoomOffset;
    this.adapter.init(container, options);
  }

  setCenter(latLng: LatLng): void {
    this.adapter.setCenter(latLng);
  }

  setZoom(zoom: number): void {
    if (this.adapter instanceof LeafletAdapter)
      zoom += this.leafletZoomOffset;
    this.adapter.setZoom(zoom);
  }

  addMarker(latLng: LatLng, options: { id?: string; color?: string; icon?: any}): void {
    this.adapter.addMarker(latLng, options);
  }

  getMarker(id: string): any | undefined {
    return this.adapter.getMarker(id);
  }

  getAllMarkers(): Record<string, any> {
    return this.adapter.getAllMarkers();
  }

  removeMarker(id?: string): void {
    this.adapter.removeMarker(id);
  }

  hasMarker(id: string): boolean {
    return this.adapter.hasMarker(id);
  }

  updateMarkerIcon(id: string, icon: any): void {
    this.adapter.updateMarkerIcon(id, icon);
  }

  updateMarkerPopup(id: string, popup: any): void {
    this.adapter.updateMarkerPopup(id, popup);
  }

  addMarkerClickHandler(id: string, handler: (e: any) => void): void {
    this.adapter.addMarkerClickHandler(id, handler);
  }

  addZone(zones: Zone[]): void
  {
    this.adapter.addZone(zones);
  }
  updateZone(zones: Zone[]): void
  {
    this.adapter.updateZone(zones);
  }
  openZonePopup(zone: Zone) : void
  {
    this.adapter.openZonePopup(zone);
  }
  closePopup(): void
  {
    this.adapter.closePopup();
  }

  addRoute(id: string, waypoints: LatLng[], options?: RouteOptions): void {
    this.adapter.addRoute(id, waypoints, options);
  }

  updateRoute(id: string, waypoints: LatLng[], options?: RouteOptions): void {
    this.adapter.updateRoute(id, waypoints, options);
  }

  removeRoute(id: string): void {
    this.adapter.removeRoute(id);
  }

  removeAllRoutes(): void {
    this.adapter.removeAllRoutes();
  }

  on(type: string, event: (e: any) => void): void
  {
    this.adapter.on(type, event);
  }
  destroy(): void {
    this.adapter.destroy();
  }
}
