jQuery(function()
{
    'use strict';

    var page = jQuery(document);

    var map     = page.find('.content.map > .google-map');
    var loader = map.find('.loader-box');
    var list    = page.find('.content.locations > ul');
    var filters = page.find('.field.filter select');
    var icon    = 'data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB3aWR0aD0iMzAiIGhlaWdodD0iMzUiIHZpZXdCb3g9IjAgMCAzMCAzNSI+PGRlZnM+PHBhdGggaWQ9ImEiIGQ9Ik0wIDBoMzB2MjhsLTE0Ljk1IDdMMCAyOHoiLz48L2RlZnM+PGcgZmlsbD0ibm9uZSIgZmlsbC1ydWxlPSJldmVub2RkIj48dXNlIGZpbGw9IiNFRDAwMzkiIHhsaW5rOmhyZWY9IiNhIi8+PHBhdGggc3Ryb2tlPSIjRkZGIiBzdHJva2Utd2lkdGg9IjIiIGQ9Ik0xIDFoMjh2MjYuMzY0bC0xMy45NTEgNi41MzJMMSAyNy4zNjJWMXoiLz48cGF0aCBmaWxsPSIjRkZGIiBkPSJNMCAxMGgzMHYySDB6Ii8+PC9nPjwvc3ZnPg==';
    var markers = [];

    if (!map.length || !list.length)
    {
        return;
    }

    var open_map_text = list.data('open-map-text');

    var google_map, google_map_info_window;

    list.on('filter', function(event, city)
    {
        if (google_map.selected_location)
        {
            unselect_location();
        }

        list.find('li').each(function()
        {
            var list_item = jQuery(this);

            list_item.toggle(city == '' || list_item.data('city') == city);
        });

        map.trigger('updatemarkers');
    });

    filters.on('change', function()
    {
        var value = this.value;

        filters.not(this).val(value);

        list.trigger('filter', value);
    });

    var clear_markers = function()
    {
        jQuery(markers).each(function(index)
        {
            markers[index].setMap(null)
        });

        markers = [];
    };

    var initialize_map = function()
    {
        var map_options = {
            mapTypeId: google.maps.MapTypeId.ROADMAP,
            selectedLocation: null,
            center: {
                lat: 56.9826,
                lng: 24.2033
            },
            zoom: 13,
            mapTypeControl: false,
            streetViewControl: false,
            clickableIcons: false,
        };

        google_map = new google.maps.Map(map.get(0), map_options);
        google_map_info_window = new google.maps.InfoWindow();
        google.maps.event.addListener(google_map_info_window, 'closeclick', unselect_location);

        page.on('resizeend', function()
        {
            google.maps.event.trigger(google_map, 'resize');
        });
    };

    var initialize_locations = function()
    {
        list.find('li').each(function(index, dom_node)
        {
            var location_node = jQuery(dom_node);

            var location = {
                position:
                    {
                        lat: parseFloat(location_node.data('latitude')),
                        lng: parseFloat(location_node.data('longitude')),
                    },
                node: location_node
            };

            location.marker = new google.maps.Marker({
                position: location.position,
                map: null,
                location: location,
                icon: {
                    url: icon,
                    scaledSize: new google.maps.Size(32,32) // IE11 needs this to show SVG markers
                },
                optimized: false // IE11 needs this to show SVG markers
            });

            location.marker.addListener('click', function()
            {
                select_location(this.location);
            });

            location_node.data('location', location);

            location_node.on('click', function(e)
            {
                if (/^(medium|full)$/.test(page.data('layout')))
                {
                    location_node.find('a.title').click();
                }
            });

            location_node.find('a').on('click', function(e)
            {
                // when clicking on links inside the list item, prevent the event bubbling up to the container node
                e.stopPropagation();
            });

            location_node.find('a.title, .more a').on('click', function(e)
            {
                e.preventDefault();
                select_location(location);

                if (page.data('layout') == 'compact')
                {
                    jQuery('html, body').animate({ scrollTop: map.offset().top + 'px' });
                }
            });
        });
    };

    map.on('updatemarkers', function()
    {
        clear_markers();

        var bounds = new google.maps.LatLngBounds();
        var visible_nodes = list.find('li:visible');

        visible_nodes.each(function(index, dom_node)
        {
            var location_node = jQuery(dom_node);
            var marker = location_node.data('location').marker;

            marker.setMap(google_map);
            bounds.extend(marker.getPosition());
            markers.push(marker);
        });

        if (visible_nodes.length == 1)
        {
            select_location(visible_nodes.first().data('location'));
        }

        if (bounds.getNorthEast().equals(bounds.getSouthWest()))
        {
            var center = {
                latitude: bounds.getNorthEast().lat(),
                longitude: bounds.getNorthEast().lng()
            };

            bounds.extend(new google.maps.LatLng(center.latitude + 0.01, center.longitude + 0.01));
            bounds.extend(new google.maps.LatLng(center.latitude - 0.01, center.longitude - 0.01));
        }

        google_map.fitBounds(bounds);
    });

    var select_location = function(location)
    {
        if (google_map.selected_location)
        {
            unselect_location();
        }

        google_map.selected_location = location;

        var details_node = jQuery('<div class="location-details">').html(google_map.selected_location.node.html());

        details_node.find('.more a').addClass('button secondary').text(open_map_text);

        google_map_info_window.setContent(details_node[0].outerHTML);
        google_map_info_window.open(google_map, google_map.selected_location.marker);

        google_map.selected_location.node.addClass('selected');
    };

    var unselect_location = function()
    {
        google_map.selected_location.node.removeClass('selected');
        google_map.selected_location = null;

        google_map_info_window.close();
    };

    window.initialize = function()
    {
        if (typeof google == 'undefined')
        {
            return;
        }

        loader.hide();
        initialize_map();
        initialize_locations();
        list.trigger('filter', filters.val());
    }

    var script = document.createElement('script');
    document.getElementsByTagName('head')[0].appendChild(script);
    script.src = '//maps.googleapis.com/maps/api/js?key=' + map.data('google-maps-key') + '&callback=initialize&language=' + document.documentElement.lang;

});
