// The MIT License (MIT)
//
// Copyright (c) 2021-2024 Camptocamp SA
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
// the Software, and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
/* global google */
import { StreetviewService } from './Service';
/**
 * Service for streetview functionality with Google Street View
 */
export default class GoogleStreetviewService extends StreetviewService {
    /**
     * @param {angular.IScope} $scope Scope.
     * @param {?import('ol/Map').default} map The map
     * @param {(newCoordinates: import('ol/coordinate').Coordinate | null) => void}handlePanoramaPositionChange Position change handler
     * @param {number} radius The radius
     * @param {JQuery} $element Element
     */
    constructor($scope, map, handlePanoramaPositionChange, radius, $element) {
        super($scope, map, handlePanoramaPositionChange);
        /**
         * radius for which images are searched
         *
         * @type {number}
         * @private
         */
        this.radius_ = radius;
        /**
         * @type {google.maps.StreetViewService}
         * @private
         */
        this.streetViewService_ = new google.maps.StreetViewService();
        /**
         * @type {google.maps.StreetViewPanorama}
         * @private
         */
        this.panorama_ = new google.maps.StreetViewPanorama($element[0], {
            pov: {
                heading: 0,
                pitch: 0,
            },
            visible: false,
            zoom: 1,
        });
        /**
         * @type {?google.maps.MapsEventListener}
         * @private
         */
        this.panoramaListener_ = null;
    }
    /**
     * Called when the panorama position changes. Update the location.
     *
     * @private
     */
    positionChange_() {
        const position = this.panorama_.getPosition();
        const newCoordinates = this.fromLonLat_([position.lng(), position.lat()]);
        super.panoramaPositionChange(newCoordinates);
    }
    /**
     * @param {?google.maps.StreetViewPanoramaData} data Data.
     * @param {google.maps.StreetViewStatus} status Status.
     * @private
     */
    handleStreetViewServiceGetPanorama_(data, status) {
        if (!data) {
            this.noDataAtLocation = true;
            this.scope_.$apply();
            return;
        }
        if (!data.location) {
            throw new Error('Missing data.location');
        }
        if (!data.location.latLng) {
            throw new Error('Missing data.location.latLng');
        }
        const panorama = this.panorama_;
        if (status === google.maps.StreetViewStatus.OK) {
            this.noDataAtLocation = false;
            panorama.setPosition(data.location.latLng);
        }
        else {
            this.noDataAtLocation = true;
        }
        this.scope_.$apply();
    }
    /**
     * Get image for the given location.
     *
     * @param {import('ol/coordinate').Coordinate} coordinates Map view projection coordinates.
     */
    getPanorama(coordinates) {
        const lonLat = this.toLonLat_(coordinates);
        this.streetViewService_.getPanorama({
            location: {
                lat: lonLat[1],
                lng: lonLat[0],
            },
            radius: this.radius_,
        }, this.handleStreetViewServiceGetPanorama_.bind(this));
    }
    /**
     * Toggle visibility of streetview / add or remove its listener
     *
     * @param {boolean} show If the streetview is to show
     */
    toggleShow(show) {
        this.panorama_.setVisible(show);
        if (show) {
            this.panoramaListener_ = google.maps.event.addListener(this.panorama_, 'position_changed', this.positionChange_.bind(this));
        }
        else if (this.panoramaListener_) {
            google.maps.event.removeListener(this.panoramaListener_);
            this.panoramaListener_ = null;
        }
    }
}
GoogleStreetviewService.$inject = ['$scope', 'map', 'handlePanoramaPositionChange', 'radius', '$element'];
//# sourceMappingURL=GoogleStreetviewService.js.map