MapComp.zoomToCameraLocation = (d) => {
    let that = d.this;
    let pos = new google.maps.LatLng(d.lat, d.lng);

    that.centerTooltip.externalPanCheck();
    that.map.panTo(pos);
    let currentZoom = that.map.getZoom();

    if ($(window).width() > 992) {
        if (currentZoom < 13) {
            that.map.setZoom(13);
        }
        that.appPublicApi.appHelper.showInfoWindowForItem(d.layer, d.id, null, pos);
        d.hash(d.controller);
    } else {
        if (currentZoom < 17) {
            that.map.setZoom(17);
        }
        that.appPublicApi.appHelper.showInfoWindowForItem(d.layer, d.id, null, pos);
        d.hash('map-col-container');
    }
}

MapComp.layerIconsUpdated = (d) => {

    let that = d.this;

    let position = new google.maps.LatLng(d.lng, d.lat);

    that.centerTooltip.externalPanCheck();
    that.map.panTo(position);
    let currentZoom = that.map.getZoom();
    if ($(window).width() > 992) {
        if (currentZoom < 13) {
            that.map.setZoom(13);
        }
    } else if (currentZoom < 17) {
        that.map.setZoom(17);
    }
    that.appPublicApi.appHelper.showInfoWindowForItem(d.layer, d.title, null, position);
}


MapComp.setMapEvents = (d) => {

    //listen to google map events.
    google.maps.event.addListener(d.map, 'zoom_changed', function () {
        d.closeInfoWindow();
        d.delayRefresh(false);
    });
    google.maps.event.addListener(d.map, 'bounds_changed', function () {
        d.delayRefresh(false);
    });
    google.maps.event.addListener(d.map, 'dragstart', function () {
        d.setMapBeingDragged(true);
    });
    google.maps.event.addListener(d.map, 'dragend', function () {
        d.setMapBeingDragged(false);
    });

    //prevent panning of the edge of the map in latitude direction.
    d.noPanOffEarth(d.map);
}

MapComp.updateMapCookie = (d) => {

    let updateCookie = function () {
        //get map details.
        let center = d.map.getCenter();
        let zoom = d.map.getZoom();

        //set cookie values related to map.
        d.setMapZoomAndCenterCookie({
            lat: center.lat(), lng: center.lng(), zoom: zoom, mapType: 'google' });
    };

    google.maps.event.addListener(d.map, 'zoom_changed', updateCookie);
    google.maps.event.addListener(d.map, 'dragend', updateCookie);
} 
MapComp.map = undefined;
MapComp.isGoogle = true;
MapComp.isLibre = false;
MapComp.callback = {};
MapComp.library = 'google';

MapComp.mountMap = (d) => {
    d.bounds = null;
    MapComp.map = new google.maps.Map(document.getElementById(d.idTag), d);
    google.maps.event.addListenerOnce(MapComp.map, 'idle', () => {
        d.mapDoneLoading();
    });

    google.maps.event.addListener(MapComp.map, 'maptypeid_changed', d.maptypeid_changed);
    return MapComp.map;
};


MapComp.mapSize = (numbers) => {
    return new google.maps.Size(numbers[0], numbers[1]);;
}

MapComp.mapPoint = (numbers) => {
    return new google.maps.Point(numbers[0], numbers[1]);
}

MapComp.infoWindow = (d) => {
    return new google.maps.InfoWindow({ maxWidth: d.maxWidth });
}

MapComp.latLng = (latitude, longitude) => {
    return new google.maps.LatLng(latitude, longitude)
}

MapComp.latLngVals = (latLng) => {
    return [latLng.lat(), latLng.lng()];
}

MapComp.createRouteMarker = (d) => {
    return new google.maps.Marker(d);
}

MapComp.ControlPosition = (position) => {
    return google.maps.ControlPosition[position]
}

MapComp.MapTypeControlStyle = (style) => {
    return google.maps.MapTypeControlStyle[style];
}

MapComp.StyledMapType = (layer, options) => {
    return new google.maps.StyledMapType(layer, options);
}

MapComp.EventAddDomListener = (target, action, callback) => {
    google.maps.event.addDomListener(target, action, callback);
}

MapComp.setNearbyKml = (d) => {
    return new google.maps.KmlLayer(d.url, d.kmlOptions);
}

MapComp.addOverlayMapTypes = (d) => {
    MapComp.map.overlayMapTypes.push(d.labelsLayerType);
}

MapComp.lat = (n) => {
    return n.lat();
}

MapComp.lng = (n) => {
    return n.lng();
}

MapComp.clearRouteMarkers = (location) => {
    if (location && location.marker) {
        location.marker.setMap(null);
    }
}

MapComp.updateTooltipOffsetWithLine = () => {
    return;
}
MapComp.mapModeStyles = {
    dark: function (displayPois) {
        return this.darklLblsBase(displayPois).concat([
            {
                "elementType": "geometry",
                "stylers": [
                    {
                        "color": "#242f3e"
                    }
                ]
            },
            {
                "featureType": "poi.park", 
                "elementType": "geometry",
                "stylers": [
                    {
                        "color": "#263c3f"
                    }
                ]
            },
            {
                "featureType": "road",
                "elementType": "geometry",
                "stylers": [
                    {
                        "color": "#38414e"
                    }
                ]
            },
            {
                "featureType": "road",
                "elementType": "geometry.stroke",
                "stylers": [
                    {
                        "color": "#212a37"
                    }
                ]
            },

            {
                "featureType": "road.highway",
                "elementType": "geometry",
                "stylers": [
                    {
                        "color": "#746855"
                    }
                ]
            },
            {
                "featureType": "road.highway",
                "elementType": "geometry.stroke",
                "stylers": [
                    {
                        "color": "#1f2835"
                    }
                ]
            },

            {
                "featureType": "transit",
                "elementType": "geometry",
                "stylers": [
                    {
                        "color": "#2f3948"
                    }
                ]
            },

            {
                "featureType": "water",
                "elementType": "geometry",
                "stylers": [
                    {
                        "color": "#17263c"
                    }
                ]
            }
        ]);
    },
    light: function(displayPois, includeOptionalStyles) {

        let result = [
            {
                featureType: 'all',
                elementType: 'labels',
                stylers: [
                    { visibility: 'on' } //This is on to avoid labels control issue in Satellite mode.
                ]
            },
            {
                featureType: 'poi',
                elementType: 'labels',
                stylers: [
                    { visibility: displayPois }
                ]
            },
            {
                featureType: "administrative.province",
                elementType: "geometry.stroke",
                stylers: [
                    {
                        visibility: "on"
                    },
                    {
                        gamma: "10.00"
                    },
                    {
                        lightness: "-100"
                    },
                    {
                        weight: "1.13"
                    },
                    {
                        color: "#000080" //navy blue
                    }
                ]
            }
        ];

        if (includeOptionalStyles) {
            result = result.concat(this.satelliteStyles());
        }

        return result;
    },
    lightLabelsLayer: function (displayPois) {
        return this.allLblsBase(displayPois)
    },
    satelliteLabels: function(displayPois) {
        return this.allLblsBase(displayPois).concat(this.satelliteStyles()); 
    },
    satelliteStyles: function() {
        return [{ elementType: "labels.text.fill", stylers: [{ color: "#ffffff" }] },
        { elementType: "labels.text.stroke", stylers: [{ color: "#222222" }] }]
    },
    darklLblsBase: function(displayPois) {
        return [{
            "elementType": "labels.text.fill",
            "stylers": [
                {
                    "color": "#DEC69F"
                }
            ]
        }, {
            "elementType": "labels.text.stroke",
            "stylers": [
                {
                    "color": "#242f3e"
                },
                {
                    "saturation": -100
                },
                {
                    "lightness": -100
                },
                {
                    "weight": 0
                }
            ]
        }, {
            "featureType": "administrative.locality",
            "elementType": "labels.text.fill",
            "stylers": [
                {
                    "color": "#e5bfa1"
                }
            ]
            },
            {
                featureType: "administrative.province",
                elementType: "geometry.stroke",
                stylers: [
                    {
                        visibility: "on"
                    },
                    {
                        gamma: "10.00"
                    },
                    {
                        lightness: "-100"
                    },
                    {
                        weight: "1.13"
                    },
                    {
                        color: "#d49665"
                    }
                ]
            },
            {
                "featureType": "administrative.country",
                "elementType": "geometry.stroke",
                "stylers": [{
                    visibility: "on"
                    },
                    {
                        gamma: "10.00"
                    },
                    {
                        lightness: "-100"
                    },
                    {
                        weight: "1.13"
                    },
                    {
                        "color": "#d49665"
                    }
                ]
            },
        {
            "featureType": "poi",
            "elementType": "labels.text.fill",
            "stylers": [
                {
                    "color": "#d59563"
                }
            ]
        }, {
            "featureType": "poi.park",
            "elementType": "labels.text.fill",
            "stylers": [
                {
                    "color": "#98C862"
                }
            ]
        }, {
            "featureType": "road",
            "elementType": "labels.text.fill",
            "stylers": [
                {
                    "color": "#E0E0E0"
                }
            ]
        }, {
            "featureType": "road.highway",
            "elementType": "labels.text.fill",
            "stylers": [
                {
                    "color": "#f3d19c"
                }
            ]
        }, {
            "featureType": "transit.station",
            "elementType": "labels.text.fill",
            "stylers": [
                {
                    "color": "#e5bfa1"
                }
            ]
        }, {
            "featureType": "water",
            "elementType": "labels.text.fill",
            "stylers": [
                {
                    "color": "#C9C9C9"
                }
            ]
        }, {
            "featureType": "water",
            "elementType": "labels.text.stroke",
            "stylers": [
                {
                    "color": "#9E9E9E"
                }
            ]
        }, {
            featureType: 'poi',
            elementType: 'labels',
            stylers: [
                { visibility: displayPois }
            ]
        }
        ]

    },
    allLblsBase: function(displayPois) {
        return [
            {
                featureType: 'all',
                stylers: [
                    { visibility: 'off' }
                ]
            },
            {
                featureType: 'administrative',
                elementType: 'labels',
                stylers: [
                    { visibility: 'on' }
                ]
            },
            {
                featureType: 'landscape',
                elementType: 'labels',
                stylers: [
                    { visibility: 'on' }
                ]
            },
            {
                featureType: 'poi',
                elementType: 'labels',
                stylers: [
                    { visibility: displayPois }
                ]
            },
            {
                featureType: 'road',
                elementType: 'labels',
                stylers: [
                    { visibility: 'on' }
                ]
            },
            {
                featureType: 'transit',
                elementType: 'labels',
                stylers: [
                    { visibility: 'on' }
                ]
            },
            {
                featureType: 'water',
                elementType: 'labels',
                stylers: [
                    { visibility: 'on' }
                ]
            }
        ]
    },
    darkLabelsLayer: function(displayPois) {

        return this.allLblsBase(displayPois).concat(this.darklLblsBase(displayPois));
    }
}
MapComp.setupThemeModeBtn = (d) => {

    d.controlDiv.className = 'toggleDarkLMapContainer customMapCtrl';
    d.controlDiv.setAttribute('id', 'toggleDarkLMapContainer');
    let toggleMapModeButton = document.createElement('button');
    toggleMapModeButton.className = 'toggleMapModeButton btn btn-default';
    toggleMapModeButton.setAttribute('id', 'toggleMapModeButton');
    toggleMapModeButton.setAttribute('type', 'button');
    toggleMapModeButton.setAttribute('title', d.text.ToggleDarkLightMap);
    // Add for AODA
    toggleMapModeButton.setAttribute('aria-label', d.text.ToggleDarkLightMap);
    let btnImage = document.createElement('i');
    btnImage.className = 'fas fa-adjust';
    // Add for AODA
    btnImage.setAttribute('aria-hidden', 'true');
    btnImage.setAttribute('title', d.text.ToggleDarkLightMap);
    toggleMapModeButton.appendChild(btnImage);
    d.controlDiv.appendChild(toggleMapModeButton);

    google.maps.event.addDomListener(toggleMapModeButton, 'click', d.toggleMapMode);

}

MapComp.toggleMapMode = (d) => {

    if (MapComp.map.getMapTypeId() === 'hybrid' || MapComp.map.getMapTypeId() === 'satellite') {
        document.getElementsByClassName('gm-style-mtc')[0].getElementsByTagName('button')[0].click();
    }

    let newOptions = { styles: d.isDarkMode ? MapComp.mapModeStyles.dark(d.displayPois) : MapComp.mapModeStyles.light(d.displayPois) };
    MapComp.map.setOptions(newOptions);

}

MapComp.setDarkLabelsState = (d) => {

    let darkLblLayerIndex = MapComp.map.overlayMapTypes.getArray().indexOf(d.darkLabelsLayerType);
    if (d.isDarkMode) {
        if (darkLblLayerIndex > -1) {
            MapComp.map.overlayMapTypes.setAt(0, d.darkLabelsLayerType);
        }
        else {
            MapComp.map.overlayMapTypes.push(d.darkLabelsLayerType);
        }
    } else if (darkLblLayerIndex > -1) {
            MapComp.map.overlayMapTypes.removeAt(darkLblLayerIndex);
        }


}

MapComp.setupZoomButtons = (d) => {
    // Creating divs & styles for custom zoom control
    d.controlDiv.className = 'zoomControlContainer customMapCtrl';

    // Set CSS for the control wrapper
    var controlWrapper = document.createElement('div');
    controlWrapper.className = "zoomControl";
    d.controlDiv.appendChild(controlWrapper);

    // Set CSS for the zoomIn
    var zoomInButton = document.createElement('i');
    zoomInButton.className = "far fa-plus";
    //Add for AODA to ZoomIn button
    zoomInButton.setAttribute('title', d.text.ZoomInMap);
    zoomInButton.setAttribute("aria-label", d.text.ZoomInMap);
    zoomInButton.setAttribute("role", "button");
    zoomInButton.setAttribute("tabindex", "0");
    controlWrapper.appendChild(zoomInButton);


    // Set CSS for the zoomOut
    var zoomOutButton = document.createElement('i');
    zoomOutButton.className = "far fa-minus";
    //Add for AODA to ZoomIn button
    zoomOutButton.setAttribute('title', d.text.ZoomOutMap);
    zoomOutButton.setAttribute("aria-label", d.text.ZoomOutMap);
    zoomOutButton.setAttribute("role", "button");
    zoomOutButton.setAttribute("tabindex", "0");
    controlWrapper.appendChild(zoomOutButton);

    return [zoomInButton, zoomOutButton];

}


MapComp.setZoomEvents = (d) => {

    // Setup the click event listener - zoomIn
    google.maps.event.addDomListener(d.zoomInButton, 'click', () =>{
        MapComp.map.setZoom(MapComp.map.getZoom() + 1);
    });

    google.maps.event.addDomListener(d.zoomInButton, 'keydown', (e) => {
        if (e.code === 'Enter' || e.code === "Space") {
            MapComp.map.setZoom(MapComp.map.getZoom() + 1);
        }
    });

    // Setup the click event listener - zoomOut
    google.maps.event.addDomListener(d.zoomOutButton, 'click', () => {
        MapComp.map.setZoom(MapComp.map.getZoom() - 1);
    });

    google.maps.event.addDomListener(d.zoomOutButton, 'keydown', (e) => {
        if (e.code === 'Enter' || e.code === "Space") {
            MapComp.map.setZoom(MapComp.map.getZoom() - 1);
        }
    });

}

MapComp.MountZoomControl = (d) => {
    MapComp.map.controls[d.zoomPos].push(d.zoomControlDiv);
}
