"use strict";
import Browser from '../modules/browser';
import getTpl from "../libs/gettpl";
import keys from 'lodash/keys';
var getService = require("../libs/get-service").default;
var findNearestCasinoForm = require('../modules/find-nearest-casino-form').default;

class CASINOLOCATORJEU {

    constructor(el) {

        this.el = $(el);

        const isDisabled = !Browser.hasLocalStorage();

        if (isDisabled)
        {
            this.el.find('.casino-locator-state[data-state="disabled"]').addClass("is-active");
            return;
        }

        this.el.find('.casino-locator-state[data-state="normal"]').addClass("is-active");
        this.assetsDir = this.el.data("assetsDir");
        this.device = this.getCurrentDevice();
        this.urlParams = Browser.parseQueryParams(window.location.search);

        this.geolocationBtn = this.el.find('#geolocationBtn');
        this.resetFilterBtn = this.el.find('.js-resetFilterBtn');
        this.searchInput = this.el.find('#searchInput');
        this.searchForm = this.el.find("#searchForm");
        this.checkboxs = this.el.find("input[type='checkbox']");
        this.selectMobile = this.el.find("select");
        this.mobileResults = this.el.find('.casino-locator-mobile-results');
        this.nbMobileResults = this.el.find('.casino-locator-mobile-results-count');
        this.nbMobileResultsCount = this.nbMobileResults.find('.js-result-count');
        this.nbMobileResultsLabel = this.nbMobileResults.find('.js-result-text');

        /* Marker geoloc */
        this.geolocMarker = null; // todo clear this marker on new search or reset filters

        // searched markers (with Google Places Autocomplete)
        this.searched_markers = [];

        /* Array */
        this.tabData = [];
        this.tabMarkers = [];
        this.tabInfoWindow = [];
        this.filters = [];
        this.filtersSelected = [];

        /* initialisations */
        this.initForDevice();

        /* mobile */
        // this.mobileFilters();
        // this.setEvents();
    }


    /* ********** initialisations mobile / desktop ********** */

    initForDevice(noData) {
        if (!noData) this.loadMap();
        this.watchUI();
        this.watchUIMobile();
        this.loadData();
    }

    /* ********** show all casino for mobile devices ********* */
    showAllCasinosMobile() {
        var infoWindowContent = [];
        var nbResults = this.tabData.length;
        for (var i = 0; i < nbResults; i++) {
            infoWindowContent[i] = this.getInfoWindowDetails(this.tabData[i]);
        }
        this.insertHTMLresult(this.tabData.length, infoWindowContent);
    }


    /* ********** only on mobile devices ********** */
    /**
     * @deprecated
     */
    casinoMobileInfo() {

        var context = this;
        this.showAllCasinosMobile();

        var infoWindowContent = [];
        var nbResults = this.tabData.length;
        for (var i = 0; i < nbResults; i++) {
            infoWindowContent[i] = this.getInfoWindowDetails(this.tabData[i]);
        }

        this.resetFilterBtn.click(function (e) {
            e.preventDefault();
            context.resetCheckboxes();
            $('.casino-locator-mobile-results').empty().append(infoWindowContent);
            $('.casino-locator-mobile-results-count').find('span').text(nbResults);
        });
    }

    /* calcul radius for bounds to know distance */
    rad(x) {
        return x * Math.PI / 180;
    }

    /* function to find the closest markers */

    findClosestMarker(home, markers, excluded_marker) {
        var excluded = excluded_marker || {};
        var lat = home.lat;
        var lng = home.lng;
        var R = 6371; // radius of earth in km
        var distances = [];
        var closest = -1;
        var context = this;
        for (var i = 0; i < markers.length; i++) {
            if (markers[i] == excluded) {
                continue;
            }
            var mlat = markers[i].position.lat();
            var mlng = markers[i].position.lng();
            var dLat = context.rad(mlat - lat);
            var dLong = context.rad(mlng - lng);
            var a = Math.sin(dLat / 2) * Math.sin(dLat / 2) + Math.cos(context.rad(lat)) * Math.cos(context.rad(lat)) * Math.sin(dLong / 2) * Math.sin(dLong / 2);
            var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
            var d = R * c;

            distances[i] = d;
            if (closest == -1 || d < distances[closest]) {
                closest = i;
            }
        }

        return markers[closest];

    }

    /* function to clear all search markers */
    clearSearchedMarkers() {
        this.searched_markers.forEach(function (marker) {
            marker.setMap(null);
        });
        this.searched_markers = [];//
    }

    /* get the map object's and the map's zoom to be able to calculate it */
    pixelToLatlng(point) {
        var context = this;
        var ne = context.map.getBounds().getNorthEast();
        var sw = context.map.getBounds().getSouthWest();
        var projection = context.map.getProjection();
        var topRight = projection.fromLatLngToPoint(ne);
        var bottomLeft = projection.fromLatLngToPoint(sw);
        var scale = 1 << context.map.getZoom();
        return projection.fromPointToLatLng(new google.maps.Point(point.x / scale + bottomLeft.x, point.y / scale + topRight.y));
    }

    /* calcul from api to get zoom */
    newMarkerCoordsFromDeltaInPx(latlng_source, px_delta) {
        var context = this;
        var zoom = context.map.getZoom();
        var scale = 1 << zoom; // 256 / 512 etc i have no idea how to explain what/why
        var searched_pt = context.map.getProjection().fromLatLngToPoint(latlng_source);

        // searched place pixels coordinates relative to map container
        var nw = new google.maps.LatLng(
            context.map.getBounds().getNorthEast().lat(),
            context.map.getBounds().getSouthWest().lng()
        );
        var worldCoordinateNW = context.map.getProjection().fromLatLngToPoint(nw);
        var searched_pos_px_coords_relative = new google.maps.Point(
            Math.floor((searched_pt.x - worldCoordinateNW.x) * scale),
            Math.floor((searched_pt.y - worldCoordinateNW.y) * scale)
        );

        // then add extra pixels to the left
        searched_pos_px_coords_relative.x -= px_delta;

        // then convert to coordinates
        return context.pixelToLatlng(searched_pos_px_coords_relative);
    }

    /**
     * specific for mobile dislpay
     * @param {Number|String} count
     * @param {String} hmtl
     */
    insertHTMLresult(count, hmtl) {
        this.mobileResults.html(hmtl);
        let resultText = this.nbMobileResults.data('i18n-result' + (count > 1 ? 's' : ''));
        this.nbMobileResultsCount.text(count);
        this.nbMobileResultsLabel.text(resultText);
    }

    initGooglePlaceAutocomplete() {
        var context = this;
        var map = context.map;

        // Create the search box and link it to the UI element.
        var input = context.searchInput[0];
        var searchBox = new google.maps.places.SearchBox(input);

        // prevent form to submit on ENTER pressed
        google.maps.event.addDomListener(input, 'keydown', function (e) {
            if (e.keyCode == 13 && !document.querySelectorAll('.pac-item-selected').length > 0) {
                e.stopImmediatePropagation();
            }
        });

        // Listen for the event fired when the user selects a prediction and retrieve
        // more details for that place.
        searchBox.addListener('places_changed', function () {
            var places = searchBox.getPlaces();
            if (places.length == 0) {
                return;
            }

            context.resetFilterHandler();

            var searched_place = places[0].geometry.location;
            var my_position = {
                lat: searched_place.lat(),
                lng: searched_place.lng()
            };

            // find the first 2 casinos closest to my searched place
            // first casino
            var mk_nearest = context.findClosestMarker(my_position, context.tabMarkers);
            var mk_nearest_coords = new google.maps.LatLng(mk_nearest.position.lat(), mk_nearest.position.lng());

            // second casino
            var mk_nearest_2nd = context.findClosestMarker(my_position, context.tabMarkers, mk_nearest);
            var mk_nearest_2nd_coords = new google.maps.LatLng(mk_nearest_2nd.position.lat(), mk_nearest_2nd.position.lng());

            // with all these markers (2 casinos + the searched place) we create bounds, a rectangle area
            var bounds = new google.maps.LatLngBounds();

            //todo specific mobile
            let casinoHtml = context.findCasinoFromMarker(mk_nearest) + context.findCasinoFromMarker(mk_nearest_2nd);
            context.insertHTMLresult(2, casinoHtml);

            bounds.extend(mk_nearest_coords);
            bounds.extend(mk_nearest_2nd_coords);
            bounds.extend(searched_place);

            // fit to these bounds
            map.fitBounds(bounds);

            // add extra marker on the left so the bounds are wider to consider the sidebar
            var extra_marker = context.newMarkerCoordsFromDeltaInPx(bounds.getSouthWest(), 400);

            bounds.extend(extra_marker);
            map.fitBounds(bounds);

            // Clear out the old markers.
            context.clearSearchedMarkers();

            // For each place found, get the icon, name and location.
            places.forEach(function (place) {//
                var icon = {
                    url: place.icon,
                    size: new google.maps.Size(71, 71),
                    origin: new google.maps.Point(0, 0),
                    anchor: new google.maps.Point(17, 34),
                    scaledSize: new google.maps.Size(25, 25)
                };

                // Create a marker for each place.
                context.searched_markers.push(new google.maps.Marker({
                    map: map,
                    icon: icon,
                    title: place.name,
                    position: place.geometry.location
                }));
            });
        });
    }


    /* ********** Bind events for UI elements (DESKTOP) ********** */
    watchUI() {
        this.geolocationBtn.click(this.geolocationHandler.bind(this));
        this.resetFilterBtn.click(this.resetFilterHandler.bind(this));
        this.resetFilterBtn.click(this.resetSearchInput.bind(this));
        this.searchForm.submit(this.formSubmitHandler);

    }


    /* ********** Bind events for UI elements (MOBILE) ********** */
    /**
     * @deprecated
     */
    watchUIMobile() {
        this.selectMobile.change(this.checkboxHandlerMobile.bind(this));
    }


    /* ********** Reset default filter ********** */

    resetFilterHandler(e) {
        if (e) e.preventDefault();
        this.resetCheckboxes();
        // this.resetSearchInput();
        this.resetAllMarkers();
        this.closeAllInfoWindow();
        this.resetMapPosition();
        this.showAllCasinosMobile();
    }


    /* ********** Handler filter checkbox (DESKTOP) ********** */

    checkboxHandler() {
        var context = this;

        this.filtersSelected = [];

        $(this.checkboxs).each(function () {
            if ($(this).is(':checked')) context.filtersSelected.push($(this).val());
        });

        // Format string
        var searchString = this.filtersSelected.toString();
        searchString = searchString.split(',').join(' ');

        if (searchString !== "") {
            this.closeAllInfoWindow();
            this.filterData(searchString);
        }
        else {
            this.closeAllInfoWindow();
            this.resetAllMarkers();
            this.showAllCasinosMobile();
        }
        this.resetMapPosition();
        this.resetSearchInput();

    }


    /* ********** Handler filter checkbox (MOBILE) ********** */

    checkboxHandlerMobile() {
        var context = this;
        var searchString = $(context.selectMobile).find('option:selected').val();

        if (searchString !== "") {
            this.resetSearchInput();
            this.filterDataMobile(searchString);
        }
    }

    /* ********** Unchecked all checkbox ********** */

    resetCheckboxes() {
        $(this.checkboxs).each(function () {
            $(this).attr('checked', false);
        });
    }

    /* ********* Handler for HTML5 geolocation ********** */

    geolocationHandler() {

        // Close all open InfoWindow
        this.closeAllInfoWindow();
        this.resetCheckboxes();
        this.resetSearchInput();
        this.clearSearchedMarkers();

        if (navigator.geolocation) {
            this.geolocationBtn.addClass('waiting');
            navigator.geolocation.getCurrentPosition(this.getCurrentPositionHandler.bind(this), this.getCurrentPositionError());
        }

        return false;
    }

    /* ********** Handler navigator.geolocation ********** */

    getCurrentPositionHandler(position) {

        if (this.geolocationBtn.hasClass('waiting')) this.geolocationBtn.removeClass('waiting');
        var icon = {
            url: 'img/skin/marker-geoloc.png',
            anchor: new google.maps.Point(13, 27)
        };

        var location = new google.maps.LatLng(position.coords.latitude, position.coords.longitude);

        this.geolocMarker = new google.maps.Marker({
            position: location,
            icon: icon,
            map: this.map
        });

        this.map.setZoom(10);
        this.map.setCenter(location);

    }

    getCurrentPositionError() {
        if (this.geolocationBtn.hasClass('waiting')) this.geolocationBtn.removeClass('waiting');
    }

    /* ********** Handler search input text (DESKTOP) ********** */

    searchInputHandler() {
        /*    var val = this.searchInput.val();
         if (val !== "") {
         this.closeAllInfoWindow();
         this.searchData(val);
         //this.resetMapPosition();
         }
         else {
         this.closeAllInfoWindow();
         this.resetAllMarkers();
         this.resetMapPosition();
         }
         return false;*/
    }


    /* ********** Handler search input text (MOBILE) ********* */
    /**
     * @deprecated
     */
    searchInputHandlerMobile() {
        var val = this.searchInput.val();
        if (val !== "") {
            this.filterDataMobile(val);
        }
        else {
            this.showAllCasinosMobile();
        }
        return false;
    }


    /* ********** Clear Input search ********** */

    resetSearchInput() {
        this.searchInput.val('');
    }

    /* ********** Focus Input search ********** */

    focusInputHandler() {
        // reset Checkbox
        this.resetCheckboxes();
    }

    /* ********** prevent Form submit ********** */

    formSubmitHandler(e) {
        e.preventDefault();
    }


    /* ********** CP Zoom ********** */

    checkCodePostal(data, marker) {
        if (data.length === 5) {

            var infoWindowContent = [],
                map = this.map,
                context = this;

            setTimeout(function () {
                map.setCenter(marker.getPosition());
                //map.setZoom(12);
            }, 80);
        }
        return false;
    }

    /* ********** Handler filter data (DESKTOP) ********** */
    // search field
    searchData(data) {
        var result = this.searchIndex.search(data);

        if (result.length > 0) {

            // HideAll
            for (var j in this.tabMarkers) this.tabMarkers[j].setVisible(false);
            for (var i = 0; i < result.length; i++) {

                var ref = result[i].ref;
                var marker = this.findMarker(ref);
                marker.setVisible(true);

                this.checkCodePostal(data, marker);

            }

        } else {

            // reset All markers
            for (var k = 0; k < this.tabMarkers.length; k++) {
                var marker = this.tabMarkers[k];
                marker.setVisible(false);
            }
        }
    }

    // check filters
    check_all_filters(mk, searched) {
        for (var i = 0; i < searched.length; i++) {
            if (mk.filters.indexOf(' ' + searched[i] + ' ') < 0) {
                return false;
            }
        }
        return true;
    }

    /* ********** Handler filter data (DESKTOP) ********** */
    // search field
    filterData(data) {
        var searched = data.split(' '); // searched item must have spaces before and after (case blackjack and blackjack-lucky-ladies)
        // HideAll
        let context = this;
        let casinoHtml = '';
        let count = 0;
        for (var marker in this.tabMarkers) {
            this.tabMarkers[marker].setVisible(false);
        }
        // search
        for (var j in this.tabMarkers) {
            var mk = this.tabMarkers[j];
            var isVisible = this.check_all_filters(mk, searched);
            mk.setVisible(isVisible);
            if (isVisible) {
                casinoHtml += context.findCasinoFromMarker(mk);
                count++;
            }
        }
        context.insertHTMLresult(count, casinoHtml);
    }


    /* ********** Handler filter data (MOBILE) ********** */

    /**
     * @deprecated
     */
    filterDataMobile(data) {
        var searched = data.split(" ").join(',.');
        var $info_windows = $('.casino-locator-mobile-results').find('.casino-locator-infowindow');

        // HideAll
        $info_windows.hide();

        // search
        var $found = $info_windows.filter("." + searched);

        // show found items
        $found.show();
        this.nbMobileResultsCount.text($found.length);
    }


    /* ********** reset all markers on map ********** */
    resetAllMarkers() {
        // reset All markers
        for (var i = 0; i < this.tabMarkers.length; i++) {
            var marker = this.tabMarkers[i];
            marker.setVisible(true);
        }
    }


    /* ********** Close all InfoWindow (googlemap.infoWindow) ********** */
    closeAllInfoWindow() {

        // reset All markers
        for (var i = 0; i < this.tabInfoWindow.length; i++) {

            var tabInfoWindow = this.tabInfoWindow[i];
            tabInfoWindow.close();

        }

    }


    /* ********** Helper : find Marker by ID ********** */
    findMarker(id) {
        for (var i = 0; i < this.tabMarkers.length; i++) {
            if (this.tabMarkers[i].id === id) return this.tabMarkers[i];
        }
    }


    /* ********** Load JSON for build Store Locator (DESKTOP) ********** */
    loadData() {
        var context = this;

        getService('casinos').done(function (data) {
            context.tabData = data;
            context.initSearchEngine();
            context.placeMarkers();
            context.buildFilters();
            context.showAllCasinosMobile();
            context.buildFiltersMobile();

            const urlParams = context.urlParams;
            const filters = context.filters;
            const filterNames = keys(urlParams)
                .map(key => (filters.indexOf(key) > -1 && urlParams[key] === 'true') ? key : false)
                .filter(filter => filter !== false);

            context.checkFilters(filterNames);
        });
    }


    /* ********** Load JSON for build Store Locator (MOBILE) ********** */
    /**
     * @deprecated
     */
    loadDataMobile() {
        var context = this;
        getService('casinos').done(function (data) {
            context.tabData = data;
            context.initSearchEngine();
            context.casinoMobileInfo();
            context.buildFiltersMobile();
        });
    }

    countFilters(data) {
        var casinos = data;
        let filters = {};
        let filters_type = $('.js-filters').data('filters-type') || 'casino-features'; // casino-features or games
        var nb_casinos = casinos.length;
        var is_games = filters_type == 'games';
        var is_casino_feat = filters_type == 'casino-features';
        for (var i = 0; i < nb_casinos; i++) {
            var casino = casinos[i];
            // count filters before

            var c_filters = casino.locator.filters; // if casino-features (default)
            c_filters = is_games ? casino.games : c_filters;

            for (var j = 0; j < c_filters.length; j++) {
                var name = is_casino_feat ? c_filters[j].type.toLowerCase() : 'error'; // if casino-features (default)
                var label = is_casino_feat ? c_filters[j].label : 'error';// if casino-features (default)

                name = is_games ? c_filters[j].name.toLowerCase().replace(/ /g, '-') : name;
                label = is_games ? c_filters[j].name : label;
                var id = is_games ? c_filters[j].id : 'error';
                //var checked = is_games ? c_filters[j].id == JSONendpointSettings.defaultGame : false;

                filters[name] = filters[name] || {};
                filters[name].id = id;
                filters[name].label = label;
                //filters[name].checked = checked;
                filters[name].count = filters[name].count + 1 || 1;
            }
        }
        return filters;
    }

    findCasinoFromMarker(marker) {
        let context = this;
        let result = context.tabData.filter(function (casinoItem) {
            return casinoItem.id === marker.id;
        });
        return this.getInfoWindowDetails(result[0]);
    }

    /* ********** Build filters (checkboxes) from json data ********** */

    buildFilters() {
        let html = '';
        let filters = this.countFilters(this.tabData);

        // now build html items
        for (var filter in filters) {
            if (filters.hasOwnProperty(filter)) {
                var checked = filters[filter].id == JSONendpointSettings.defaultGame;
                html += getTpl({
                    jeuValue: filter,
                    jeuLabel: filters[filter].label + ' (' + filters[filter].count + ')',
                    jeuId: 'jeu-' + filter,
                    jeuChecked: (checked ? 'checked' : ''),
                }, 'casinolocatorjeu-filter');
                this.filters.push(filter);
                if (checked)
                    this.filterData(filter);
            }
        }

        // insert checkboxes
        var $container = $('.js-casino-locator-panel-form-checkbox');
        $container.html(html);

        // reassign checkboxes
        this.checkboxs = this.el.find("input[type='checkbox']");

        // and rebind them
        this.checkboxs.change(this.checkboxHandler.bind(this));
    }

    /* ********** Build filters (checkboxes) from json data ********** */
    /**
     * @deprecated
     */
    buildFiltersMobile() {
        let html = '';
        let filters = this.countFilters(this.tabData);

        // now build html items
        var first_option_val = '';
        for (var filter in filters) {
            if (filters.hasOwnProperty(filter)) {
                var checked = filters[filter].id == JSONendpointSettings.defaultGame;
                first_option_val += first_option_val != '' ? ' ' + filter : filter;
                html += getTpl({
                    jeuValue: filter,
                    jeuLabel: filters[filter].label + ' (' + filters[filter].count + ')',
                    jeuId: 'jeu-' + filter,
                    jeuChecked: (checked ? 'selected' : ''),
                }, 'casinolocatorjeu-filter-mobile');

                if (checked)
                    this.filterDataMobile(filter);
            }
        }

        var first_option_html = getTpl({
            jeuValue: first_option_val,
            jeuLabel: 'tous les casinos'
        }, 'casinolocatorjeu-filter-mobile');

        html = first_option_html + html;

        // insert checkboxes
        $('.js-casino-locator-form-select-mobile select').append(html);
    }

    /* ********** Build Search engine -> lunr.js ********** */

    initSearchEngine() {

        // lunr
        this.searchIndex = lunr(function () {
            this.field('name', {boost: 5})
            this.field('postalCode', {boost: 10})
            this.field('city', {boost: 11})
            this.field('country', {boost: 12})
            this.field('filters', {boost: 100})
            this.ref('id')
        });

        // build search data
        for (var i = 0; i < this.tabData.length; i++) {
            var obj = this.tabData[i];
            var filtres = this.getFiltersCasinoFeatures(obj);
            filtres += this.getFiltersGames(obj);

            obj.filters = filtres;
            this.searchIndex.add(obj);
        }
    }


    /* ********** set Map ********** */

    loadMap() {

        var styles = [
            {
                "featureType": "administrative",
                "elementType": "all",
                "stylers": [
                    {
                        "visibility": "on"
                    }
                ]
            },
            {
                "featureType": "administrative",
                "elementType": "labels.text.fill",
                "stylers": [
                    {
                        "color": "#444444"
                    }
                ]
            },
            {
                "featureType": "administrative.province",
                "elementType": "all",
                "stylers": [
                    {
                        "visibility": "off"
                    }
                ]
            },
            {
                "featureType": "administrative.locality",
                "elementType": "all",
                "stylers": [
                    {
                        "visibility": "simplified"
                    }
                ]
            },
            {
                "featureType": "administrative.neighborhood",
                "elementType": "all",
                "stylers": [
                    {
                        "visibility": "off"
                    }
                ]
            },
            {
                "featureType": "administrative.land_parcel",
                "elementType": "all",
                "stylers": [
                    {
                        "visibility": "off"
                    }
                ]
            },
            {
                "featureType": "landscape",
                "elementType": "all",
                "stylers": [
                    {
                        "color": "#f2f2f2"
                    },
                    {
                        "visibility": "simplified"
                    }
                ]
            },
            {
                "featureType": "landscape.natural",
                "elementType": "all",
                "stylers": [
                    {
                        "visibility": "simplified"
                    }
                ]
            },
            {
                "featureType": "poi",
                "elementType": "all",
                "stylers": [
                    {
                        "visibility": "off"
                    }
                ]
            },
            {
                "featureType": "poi.business",
                "elementType": "all",
                "stylers": [
                    {
                        "visibility": "on"
                    },
                    {
                        "saturation": "13"
                    }
                ]
            },
            {
                "featureType": "poi.sports_complex",
                "elementType": "all",
                "stylers": [
                    {
                        "visibility": "on"
                    }
                ]
            },
            {
                "featureType": "road",
                "elementType": "all",
                "stylers": [
                    {
                        "saturation": "-100"
                    },
                    {
                        "lightness": "8"
                    },
                    {
                        "gamma": "2.15"
                    },
                    {
                        "hue": "#ff0000"
                    },
                    {
                        "visibility": "simplified"
                    }
                ]
            },
            {
                "featureType": "road.highway",
                "elementType": "all",
                "stylers": [
                    {
                        "visibility": "simplified"
                    }
                ]
            },
            {
                "featureType": "road.arterial",
                "elementType": "labels.icon",
                "stylers": [
                    {
                        "visibility": "off"
                    }
                ]
            },
            {
                "featureType": "transit",
                "elementType": "all",
                "stylers": [
                    {
                        "visibility": "off"
                    }
                ]
            },
            {
                "featureType": "water",
                "elementType": "all",
                "stylers": [
                    {
                        "visibility": "on"
                    },
                    {
                        "color": "#acbcc9"
                    }
                ]
            }
        ];

        var styledMap = new google.maps.StyledMapType(styles, {name: "Styled Map"});

        var context = this;
        /* Map options */
        this.mapOptions = {
            mapTypeControl: false,
            center: {
                lat: 46,
                lng: 1.5
            },
            zoom: 6,
            mapTypeControlOptions: {
                mapTypeIds: [google.maps.MapTypeId.ROADMAP, 'map_style']
            }
        };

        if (this.urlParams.lat && this.urlParams.lng)
        {
          const lat = parseFloat(this.urlParams.lat);
          const lng = parseFloat(this.urlParams.lng);

          if (!isNaN(lat) && !isNaN(lng))
          {
            this.mapOptions.center.lat = lat;
            this.mapOptions.center.lng = lng;
            this.mapOptions.zoom = parseInt(this.el.data("map-highlight-zoom"), 10);
          }
        }

        /* Icon */
        this.icon = {
            url: `${this.assetsDir}/img/skin/marker-dot.png`,
            anchor: new google.maps.Point(14, 40),
            scaledSize: new google.maps.Size(28, 40)
        };

        /* Map */
        this.map = new google.maps.Map(document.getElementById('casino-locator-map'), this.mapOptions);
        //Associate the styled map with the MapTypeId and set it to display.
        this.map.mapTypes.set('map_style', styledMap);
        this.map.setMapTypeId('map_style');


        google.maps.event.addListenerOnce(this.map, 'idle', function () {
            context.initGooglePlaceAutocomplete();//
            findNearestCasinoForm.init();
        });
    }


    /* ********** Reset default position of map (zoom, pan...) ********** */

    resetMapPosition() {
        var location = new google.maps.LatLng(this.mapOptions.center.lat, this.mapOptions.center.lng);
        this.map.setZoom(this.mapOptions.zoom);
        this.map.panTo(location);

        // clear geoloc marker
        if (this.geolocMarker) {
            this.geolocMarker.setMap(null);
        }

        // clear searched markers
        this.clearSearchedMarkers();
    }


    /* ********** Display Markers on map ********** */

    placeMarkers() {//
        var context = this;
        var infoWindowContent = [];
        for (var i = 0; i < this.tabData.length; i++) {
            var c = context.tabData[i]; // casino obj
            infoWindowContent[i] = context.getInfoWindowDetails(c);

            var lat = c.latitude;
            var lng = c.longitude;
            var location = new google.maps.LatLng(lat, lng);

            var filtres = this.getFiltersCasinoFeatures(c);
            filtres += this.getFiltersGames(c);

            var marker = new google.maps.Marker({ // add marker
                position: location,
                icon: this.icon,
                map: this.map,
                filters: filtres,
                title: c.name
            });

            console.log('marker',marker);

            marker.id = c.id;

            this.tabMarkers.push(marker);

            google.maps.event.addListener(marker, 'click', (function (marker, i) {

                return function () {

                    if (context.tabInfoWindow.length > 0) context.closeAllInfoWindow();

                    var infoWindow = new google.maps.InfoWindow();

                    context.tabInfoWindow.push(infoWindow);

                    // ready
                    google.maps.event.addListener(infoWindow, 'domready', function () {

                        var iwOuter = $('.gm-style-iw');
                        var iwBackground = iwOuter.prev();
                        iwBackground.children(':nth-child(2)').css({'display': 'none'});
                        iwBackground.children(':nth-child(4)').css({'display': 'none'});

                        iwBackground.children(':nth-child(3)').find('div').children().css({
                            'background-color': '#a57b1b',
                            'z-index': '1'
                        });

                        var iwCloseBtn = iwOuter.next();
                        iwCloseBtn.addClass('infowindow-close');

                    });

                    // Click on close
                    google.maps.event.addListener(infoWindow, 'closeclick', function () {

                    });

                    infoWindow.setContent(infoWindowContent[i]);
                    infoWindow.open(this.map, marker);

                    // Zoom & Pan to center
                    this.map.panTo(marker.getPosition());
                    // this.map.setZoom(15);
                }

            })(marker, i));

        }

    }

    getFiltersCasinoFeatures(data) {
        var filtres = '';
        for (var i = 0; i < data.locator.filters.length; i++) {
            var filter = data.locator.filters[i].type.toLowerCase();
            filtres += ' ' + filter;
        }
        return filtres;
    }

    getFiltersGames(data) {
        var filtres = '';
        for (var k = 0; k < data.games.length; k++) {
            var filter_game = data.games[k].name.toLowerCase().replace(/ /g, '-');
            filtres += ' ' + filter_game;
        }
        return filtres + ' ';
    }

    /* ********** Return infoWindow details (DESKTOP) ********** */

    getInfoWindowDetails(data) {
        // Atouts
        var atoutsHTML = '';

        for (var service in data.services) {
            var serv = data.services[service];

            if (service == "onPlace" || service == "around") {
                for (var i = 0; i < serv.length; i++) {
                    atoutsHTML += '<li>' + serv[i].label + '</li>';
                }
            }
        }

        var filters = this.getFiltersCasinoFeatures(data);
        filters += this.getFiltersGames(data);

        return getTpl({
            imgSrc: data.locator.images.desktop,
            label: data.name,
            address: data.address,
            cp: data.postalCode,
            city: data.city,
            filtres: filters,
            atouts: atoutsHTML,
            url: data.links.casino_home
        }, 'casinolocatorjeu-infowindow');
    }


    /* ********** Debounce ********** */

    debounce(func, wait, immediate = false) {
        var timeout;
        return function () {
            var context = this, args = arguments;
            var later = function () {
                timeout = null;
                if (!immediate) func.apply(context, args);
            };
            var callNow = immediate && !timeout;
            clearTimeout(timeout);
            timeout = setTimeout(later, wait);
            if (callNow) func.apply(context, args);
        };
    }


    /* ********** getCurrentDevice ********** */

    getCurrentDevice() {
        return window.getComputedStyle(document.querySelector("body"), "::before").getPropertyValue("content").replace(/"|'/g, '');
    }


    /* ********** setEvents ********** */
    setEvents() {
        $(window).on("resize.CASINOLOCATOR", this.debounce(this.onWindowResize.bind(this), 150));
    }


    /* ********** onWindowResize ********** */
    /**
     * @deprecated
     */
    onWindowResize() {
        this.device = this.getCurrentDevice();
        // this.mobileFilters();
        // this.initForDevice(true);
    }


    /* ********** filters mobile display ********** */
    /**
     * @deprecated
     */
    mobileFilters() {
        (this.device != 'mobile') ? this.resetFilterBtn.appendTo($('.casino-locator-panel-form-search'))
            : this.resetFilterBtn.appendTo($('.casino-locator-panel'));
    }

    /**
     * Automatically filters results based on filter names
     * @param {Array} filterNames - a list of filter names
     */
    checkFilters(filterNames = []) {

        var filtered = false;

        filterNames.forEach((filter) => {

            this.checkboxs.filter(`*[value="${filter}"]`).prop('checked', true);
            filtered = true;
        });
        if (filtered)
        {
            this.checkboxHandler();
        }
    }
}
export default CASINOLOCATORJEU;
