jQuery(function ($) {
    if (!GBrowserIsCompatible()) {
        alert("Your browser isn't compatible with this page. Please get modern browser. ")
    }
    // hash that keeps references to all markers
    var searchResultsMarkers = {}, markers = {}, properties = {};
    var markerCluster, markerClusterViewable;
    var results_fragment;
    var isExtWindowOpen = false;
    var hasShifted = false; //whether we've shifted the map or not
    var inViewableArea = false;
    var maxZoomLevel = 11;
    var centerLat = "";
    var centerLng = "";
    var setBounds = true;
    var viewableCallOnce = false;

    // Load the needed google maps components. Move this to the HTMNL
    $('<script src="/js/extinfowindow.js" type="text/javascript"></script>').appendTo("head");
    //$('<script src="/js/markerclusterer_packed.js" type="text/javascript"></script>').appendTo("head");
    var map_defaults = {
        lat: 39.421,
        lng: -75.855,
        zoom: 6,
        maxZoomLevel: maxZoomLevel
    }
    // var map_previous_values = map_defaults;

    // Initialize the map

    var map = new GMap2($("#map-canvas").get(0));

    map.setCenter(new GLatLng(map_defaults.lat, map_defaults.lng), map_defaults.zoom);
    //map.setUIToDefault();

    map.removeMapType(G_HYBRID_MAP);
    map.removeMapType(G_SATELLITE_MAP);
    map.removeMapType(G_PHYSICAL_MAP);

    GEvent.addListener(map, 'extinfowindowclose', function () { isExtWindowOpen = false; });

    //var mgrOptions = { maxZoom: 15, trackMarkers: true };
    //var mgr = new MarkerManager(map, mgrOptions);


    // A TextualZoomControl is a GControl that displays textual "Zoom In"
    // and "Zoom Out" buttons (as opposed to the iconic buttons used in
    // Google Maps).

    // We define the function first
    function TextualZoomControl() {
    }

    // To "subclass" the GControl, we set the prototype object to
    // an instance of the GControl object
    TextualZoomControl.prototype = new GControl();

    // Creates a one DIV for each of the buttons and places them in a container
    // DIV which is returned as our control element. We add the control to
    // to the map container and return the element for the map class to
    // position properly.
    TextualZoomControl.prototype.initialize = function (map) {
        var container = document.createElement("div");

        var zoomInDiv = document.createElement("div");
        //this.setButtonStyle_(zoomInDiv);
        container.appendChild(zoomInDiv);
        //zoomInDiv.appendChild(document.createTextNode("Zoom In"));
        zoomInDiv.innerHTML = '<img src="/css/images/zoom_in.png" />';
        GEvent.addDomListener(zoomInDiv, "click", function () {
            map.zoomIn();
        });

        var zoomOutDiv = document.createElement("div");
        //this.setButtonStyle_(zoomOutDiv);
        container.appendChild(zoomOutDiv);
        zoomOutDiv.innerHTML = '<img src="/css/images/zoom_out.png" />';
        //zoomOutDiv.appendChild(document.createTextNode("Zoom Out"));
        GEvent.addDomListener(zoomOutDiv, "click", function () {
            if (map.getZoom() > 6) {
                map.zoomOut();
            }
        });

        map.getContainer().appendChild(container);
        return container;
    }

    // By default, the control will appear in the top left corner of the
    // map with 7 pixels of padding.
    TextualZoomControl.prototype.getDefaultPosition = function () {
        return new GControlPosition(G_ANCHOR_TOP_LEFT, new GSize(7, 7));
    }

    // Sets the proper CSS for the given button element.
    TextualZoomControl.prototype.setButtonStyle_ = function (button) {
        button.style.textDecoration = "underline";
        button.style.color = "#0000cc";
        button.style.backgroundColor = "white";
        button.style.font = "small Arial";
        button.style.border = "1px solid black";
        button.style.padding = "2px";
        button.style.marginBottom = "3px";
        button.style.textAlign = "center";
        button.style.width = "6em";
        button.style.cursor = "pointer";
    }

    map.addControl(new TextualZoomControl());

    map.disableScrollWheelZoom(); // Since the map is pretty high scroll wheel zooming is making page scrolling hard

    // Position boxes above the map.
    var site_right_boundary = $('.shell').offset().left + $('.shell').width();
    $('.box-results').css('left', (site_right_boundary - $('.box-results').width()) + 'px');
    $('.map-intro').css('left', (site_right_boundary - $('.map-intro').width()) + 'px');

    //$('.start-your-search').css('left', $('.shell').offset().left + $('.start-your-search').position().left);
    function create_marker(property, isDefaultImage) {
        var icon = new GIcon(G_DEFAULT_ICON);
        if (isDefaultImage) {
            icon.image = "/css/images/map-flag.png";
            icon.iconSize = new GSize(26, 26);
        }
        else {
            icon.image = "/css/images/map-dot.png";
            icon.iconSize = new GSize(16, 16);
        }
        icon.shadow = "";
        icon.infoWindowAnchor = new GPoint(15, 10);

        var point = new GLatLng(property.lat, property.lng);
        var marker = new GMarker(point, { icon: icon });

        marker.bubble_html =
                '<div class="map-tooltip-action">' +
        //' <a href="' + property.link + '" class="left">View Community</a>' +
                    '<a href="' + property.save_link + '" class="btn-save right">SAVE</a>' +
                    '<div class="map-tooltip-t">&nbsp;</div>' +
                '</div>' +
                '<div class="map-tooltip-cnt">' +
                '<p class="map-tooltip-image"><a href="' + property.link + '"><img src="' + property.image + '" alt="" /></a></p>' +
                '<h5 class="map-tooltip-title"><a href="' + property.link + '">' + property.title + '</a></h5>' +
                '<p class="map-tooltip-subtitle">' + property.city + ', ' + property.state + '</p>' +
                '<div class="map-tooltip-desc">' + property.description + '</div>' +
                '</div><!-- /map-tooltip-cnt -->' +
                '<div class="map-tooltip-b">&nbsp;</div>';

        GEvent.addListener(marker, "click", function () {
            isExtWindowOpen = true;
            this.openExtInfoWindow(
                map,
                "map-tooltip",
                this.bubble_html,
                { beakOffset: 10 }
            );
        });


        return marker;
    }

    function create_multiple_marker(propertyList) {
        var icon = new GIcon(G_DEFAULT_ICON);

        icon.image = "/css/images/map-flag.png";
        icon.iconSize = new GSize(26, 26);

        icon.shadow = "";
        icon.infoWindowAnchor = new GPoint(15, 10);

        var point;
        var marker;

        var bubble_html = ''
            + '<div class="map-tooltip-cluster">'
	            + '<div class="map-tooltip-cluster-t">&nbsp;</div>'
	            + '<div class="map-tooltip-cluster-cnt">'
		            + '<h4>Communities</h4>'
		            + '<div class="map-tooltip-cluster-communities-holder">'
		            + '<div class="cl"></div>';

        var propertyArray = propertyList.split('_');
        for (var i = 0; i < propertyArray.length; i++) {
            //for (var propertyId in propertyList) {

            var property = properties[propertyArray[i]];

            if (typeof property != "undefined") {
                if (typeof searchResultsMarkers[property.id] == "undefined") {
                    icon.image = "/css/images/map-dot.png";
                    icon.iconSize = new GSize(16, 16);
                } else {
                    icon.image = "/css/images/map-flag.png";
                    icon.iconSize = new GSize(26, 26);
                }

                if (marker == undefined) {
                    point = new GLatLng(property.lat, property.lng);
                    marker = new GMarker(point, { icon: icon });
                }

                bubble_html +=

			    '<div class="map-tooltip-cluster-communities">'
				    + '<div class="map-tooltip-cluster-action">'
                        + '<a href="' + property.save_link + '" class="btn-save right">SAVE</a>'
				    + '</div>'
				    + '<div class="map-tooltip-cluster-community">'
					    + '<h5>'
						    + '<a href="' + property.link + '">' + property.title + '</a>'
					    + '</h5>'
					    + '<div class="map-tooltip-cluster-desc">'
                           + property.description
					    + '</div>'
				    + '</div>'
			    + '</div><!-- /map-tooltip-cluster-communities -->'
                + '<div class="cl"></div>';
                /*
                '<div class="map-tooltip-action">' +
                //' <a href="' + property.link + '" class="left">View Community</a>' +
                '<a href="' + property.save_link + '" class="btn-save right">asdf</a>' +
                '<div class="map-tooltip-t">&nbsp;</div>' +
                '</div>' +
                '<div class="map-tooltip-cnt">' +
                '<p class="map-tooltip-image"><a href="' + property.link + '"><img src="' + property.image + '" alt="" /></a></p>' +
                '<h5 class="map-tooltip-title"><a href="' + property.link + '">' + property.title + '</a></h5>' +
                '<p class="map-tooltip-subtitle">' + property.city + ', ' + property.state + '</p>' +
                '<div class="map-tooltip-desc">' + property.description + '</div>' +
                '</div><!-- /map-tooltip-cnt -->' +
                '<div class="map-tooltip-b">&nbsp;</div>';
                */
            }
        }

        marker.bubble_html = bubble_html + '</div></div></div>';


        //  for (var propertyId in propertyList) {

        GEvent.addListener(marker, "click", function () {
            isExtWindowOpen = true;
            this.openExtInfoWindow(
                map,
                "map-tooltip",
                this.bubble_html,
                { beakOffset: 10 }
            );
        });

        //}

        return marker;
    }

    function create_property_html_fragment(property, isDefaultImage) {
        var img = "/css/images/map-flag.png";
        if (!isDefaultImage) {
            img = "/css/images/map-dot.png";
        }
        var result_row = $('<li id="prop_' + property.id + '">' +
            '<div class="result-entry" data-lat="' + property.lat + '" data-lng="' + property.lng + '">' +
            '   <span class="flag" style="background: url(' + img + ') 0 0 no-repeat">&nbsp;</span>' +
        //'   <h5><a href="' + property.link + '">' + property.title + '</a></h5>' +
            '   <h5>' + property.title + '</h5>' +
            '   <p class="meta">' + property.city + ' | ' + property.price + '</p>' +
            (property.coming_soon ? '<p class="coming-soon">COMING SOON</p>' : '') +
            '</div>' +
        '</li>');

        result_row.click(function () {
            var prop_id = $(this).attr('id').replace(/prop_/, '');
            GEvent.trigger(markers[prop_id], "click");
        });

        return result_row;
    }

    function create_multiple_property_html_fragment(propertyList) {
        var img = "/css/images/map-flag.png";
        var result_row = "";

        for (var i = 0; i < propertyList.length; i++) {
            result_row += $('<li id="prop_' + property.id + '">' +
            '<div class="result-entry" data-lat="' + property.lat + '" data-lng="' + property.lng + '">' +
            '   <span class="flag" style="background: url(' + img + ') 0 0 no-repeat">&nbsp;</span>' +
            //'   <h5><a href="' + property.link + '">' + property.title + '</a></h5>' +
            '   <h5>' + property.title + '</h5>' +
            '   <p class="meta">' + property.city + ' | ' + property.price + '</p>' +
            (property.coming_soon ? '<p class="coming-soon">COMING SOON</p>' : '') +
            '</div>' +
            '</li>');

            result_row.click(function () {
                var prop_id = $(this).attr('id').replace(/prop_/, '');
                GEvent.trigger(markers[prop_id], "click");
            });
        }

        return result_row;
    }

    // Handle search form submit
    $("form#locations-search").submit(function (event) {

        viewableCallOnce = false;
        hasShifted = false;
        inViewableArea = false;

        //$('#locations-search').submit(function () {
        //event.preventDefault();
        // UI stuff
        $('html,body').animate({ scrollTop: $("#locations-search").offset().top });

        $('.map-intro, .map-overlay').hide();
        $('.map-details').show();
        $('.map-inner-2').removeClass("map-inner-2");
        $('.loading').show();
        $('.no-results').hide();
        $('.results-info').hide();

        var search_field = $(this).find('#community-search');
        var should_revert_blink_title = false;
        if (search_field.val() == search_field.attr('title')) {
            should_revert_blink_title = true;
            search_field.val('');
        }
        var data = $(this).serializeArray();
        if (should_revert_blink_title) {
            search_field.val(search_field.attr('title'));
        }

        $.ajax({
            url: '/Community/CommunitySearchJson', // search parameters from the form will be automatically added
            //url: '/js/example-response-search.js',
            data: data,
            dataType: "json", // jQuery will parse the results in js object
            type: "GET",
            error: function (xhr, ajaxOptions, thrownError) {
                //alert("Sorry, error occured:\n" + xhr.status + " " + thrownError);
            },
            success: function (response) {
                // Clean up old searches data
                map.clearOverlays();
                $('#ajax-results-list').html('');
                inViewableArea = true;

                // use DOM buffer in order to avoid multiple document reflows when appending the lis
                var results_fragment = document.createDocumentFragment();

                searchResultsMarkers = {}, markers = {}, markers_arr = [];
                $('.no-results').hide();
                var distanceFilter = '0';

                var bounds = new GLatLngBounds();
                for (var i = 0; i < response.results.length; i++) {

                    var property = response.results[i];

                    if (typeof property != "undefined") {

                        var point = new GLatLng(property.lat, property.lng);
                        var marker = new GMarker(point);

                        if (setBounds) {
                            bounds.extend(point);
                            bounds.extend(marker.getPoint());
                        }

                        if (typeof markers[property.id] != "undefined") {
                            throw "Duplicate property ID " + property.id + " in resultset";
                        }
                        searchResultsMarkers[property.id] = marker;
                        markers[property.id] = marker;
                        properties[property.id] = property;
                        centerLat = property.centerLat;
                        centerLng = property.centerLng;
                        distanceFilter = property.distance;
                    }
                }

                setBounds = true;

                if (response.results.length != 0) {

                    viewableCallOnce = true;
                    fitSearchResults();

                    $('.box-results').show();
                    $('.results-list').show();
                    $('.sort-by').show();
                    $('.box-results .btn-minimize').show();

                    if (distanceFilter == 30) {
                        var selectDiv = $("#community-distance-filter").parent();
                        selectDiv.find('.btn').text("30 miles");
                    }

                    getCommunitiesInViewableArea();
                }
                else {
                    $('.loading').hide();
                    $('.results-list').hide();
                    $('.box-results .btn-minimize').hide();
                    $('.search-query').html($('input[name=searchText]').val());
                    $('.search-query').show();
                    $('.sort-by').hide();
                    $('.results-box').show();
                    $('.no-results').show();
                    inViewableArea = false;

                    var geocoder = new GClientGeocoder();
                    if (geocoder) {
                        geocoder.getLatLng(
                        $('input[name=searchText]').val(),
                        function (point) {
                            if (!point) {
                                //alert(address + " not found");
                            } else {
                                map.setCenter(point);
                                //var marker = new GMarker(point, {draggable: true});  
                                //map.addOverlay(marker);
                            }
                        });
                    };

                }


            }
        });


        // get/set seo data for state/city/market 
        $.ajax({
            url: '/Community/CommunitySearchSeoJson',
            data: data,
            dataType: "json",
            type: "GET",
            error: function (xhr, ajaxOptions, thrownError) {
                //alert("Sorry, error occured:\n" + xhr.status + " " + thrownError);
            },
            success: function (response) {

                if (response != null && response.results) {
                    $("#tab-state-text").html(response.results.stateName + " Info");
                    $("#tab-state-cities-text").html("Cities in " + response.results.stateName);
                    $("#content-state-text").html(response.results.seoStateText);
                    var cityList = "";
                    for (var i = 0; i < response.results.city.length; i++) {
                        cityList += "<li>" + response.results.city[i] + "</li>";
                    }
                    $(".cities-list").html(cityList);

                    var $select = $(".saving-details-area");
                    $select.each(function () {
                        $select.val(response.results.marketId).attr("selected", true);
                        $select.parents('form').find('.select .btn').each(function () {
                            $(this).text($select.find('option').eq($select[0].selectedIndex).text());
                        });
                    });

                    $('#tab-state').removeClass("active").addClass("active");
                    $('#tab-cities').removeClass("active");
                    $('.box-results').show();
                    $('.result-tabs-body .result-tab').show();
                    $('#content-cities-text').hide();
                    $("#content-default-text").hide();
                    $('.result-tabs-head').show();
                    $('#tab-state-info').show();
                    $('#content-state-text').show();
                }
                else {
                    $(".result-tabs-head").hide();
                    $('.box-results').show();
                    $('.result-tabs-body .result-tab').show();
                    $('#content-cities-text').hide();
                    $('#content-state-text').hide();
                    $("#content-default-text").show();
                }
            }
        });



        return false;
    });




    // Click on states should automatically populate search query with the state
    // and trigger search
    $('.box-results-cnt ul.states-list a').click(function () {
        $('input[name=searchText]').val($(this).text());
        $('#locations-search').trigger('submit');
        //setTimeout(getCommunitiesInViewableArea, 500);
        return false;
    });
    var parsed_url = window.location.toString().split('?');

    if (parsed_url.length > 1) {
        GET_params = parsed_url[1].split('&');
        var parsed_GET = {};
        for (var i = 0; i < GET_params.length; i++) {
            var param_pair = GET_params[i].split('=');
            parsed_GET[param_pair[0]] = param_pair[1];
        };
        // Look for location search on page load.
        if (typeof parsed_GET["map-query"] != "undefined") {
            $('input[name=searchText]').val(parsed_GET["map-query"]);
            $('#locations-search').trigger('submit');
        }
        else if (typeof parsed_GET["PriceRangeFilterId"] != "undefined") {
            $('#locations-search').trigger('submit');
        }
    }

    function get_clusterer_styles() {
        return [
                {
                    url: '/css/images/icon_orange.png',
                    height: 34,
                    width: 30,
                    opt_anchor: [5, 14],
                    opt_textColor: 'transparent'
                }
            ];
    }


    $("#locations-search input#btn-community-search").live('change', function () {
        setBounds = true;
        $('input#StateName').val('');
        $('input#MarketId').val('');
    });

    $("#locations-search select#community-distance-filter").live('change', function () {
        setBounds = false;
        $('#locations-search').trigger('submit');
    });

    $("#locations-search select#community-home-type-filter").live('change', function () {
        setBounds = false;
        $('#locations-search').trigger('submit');
    });

    $("#locations-search select#community-price-range-filter").live('change', function () {
        setBounds = false;
        $('#locations-search').trigger('submit');
    });

    $('.sort-by select').change(function () {
        setBounds = false;
        $("#community-sort-by-filter").val($(this).val());
        getCommunitiesInViewableArea();
    });

    function getCommunitiesInViewableArea() {

        $('.loading').show();
        $('.results-info, .no-results').hide();

        // determinate the new map center and request 
        // near by proeprties from the backend
        var map_bounds = map.getBounds();
        var map_south_west_bound = map_bounds.getSouthWest();
        var map_north_east_bound = map_bounds.getNorthEast();
        var center = map.getCenter();

        if (centerLat.length == 0) {
            centerLat = center.lat();
            centerLng = center.lng();
        }

        $.ajax({
            url: '/Community/CommunitySearchViewableAreaJson',
            data: {

                "center_lat": centerLat,
                "center_lng": centerLng,

                "south_west_lat": map_south_west_bound.lat(),
                "south_west_lng": map_south_west_bound.lng(),

                "north_east_lat": map_north_east_bound.lat(),
                "north_east_lng": map_north_east_bound.lng(),

                "filter_home_type": $('#community-home-type-filter').val(),
                "filter_price_range": $("#community-price-range-filter").val(),

                "sortByOptionId": $("#community-sort-by-filter").val()
            },
            dataType: "json",
            type: "GET",
            error: function (xhr, ajaxOptions, thrownError) {
                //alert("Sorry, error occured:\n" + xhr.status + " " + thrownError);
            },
            success: function (response) {

                // update the messages
                map.clearOverlays();
                $('#ajax-results-list').html('');
                $('.search-query').html($('input[name=searchText]').val());
                $('.search-query').show();
                $('.results-count').html(response.results.length);
                $('.results-info-for').show();
                $('.no-results').hide();

                if (response.results.length != 0) {
                    $('.box-results').show();
                    $('.results-list').show();
                    $('.box-results .btn-minimize').show();
                    $('p.results-info').show();
                } else {
                    $('p.no-results').show();
                }

                $('.loading').hide();

                outer_markers_arr = []; //markers = {}, properties = {}
                var same_loc_arr = {};
                var results_fragment = document.createDocumentFragment();
                var results_fragment_in_search = document.createDocumentFragment();
                var results_fragment_in_viewable = document.createDocumentFragment();


                for (var i = 0; i < response.results.length; i++) {
                    var property = response.results[i];
                    var marker;
                    var result_row;

                    if (typeof property != "undefined") {

                        if (property.clusterIds.length == 0) {

                            if (typeof searchResultsMarkers[property.id] == "undefined") {
                                marker = create_marker(property, false);
                                properties[property.id] = property;
                                result_row = create_property_html_fragment(property, false);
                                results_fragment_in_viewable.appendChild(result_row.get(0));
                            }
                            else {
                                marker = create_marker(property, true);
                                result_row = create_property_html_fragment(property, true);
                                results_fragment_in_search.appendChild(result_row.get(0));
                            }

                            markers[property.id] = marker;
                            map.addOverlay(marker);
                        }
                        else {
                            if (same_loc_arr[property.id] == null) {
                                same_loc_arr[property.id] = property.clusterIds;
                            }

                            properties[property.id] = property;

                            if (typeof searchResultsMarkers[property.id] == "undefined") {
                                result_row = create_property_html_fragment(property, false);
                                results_fragment_in_viewable.appendChild(result_row.get(0));
                            }
                            else {
                                result_row = create_property_html_fragment(property, true);
                                results_fragment_in_search.appendChild(result_row.get(0));
                            }
                        }

                        outer_markers_arr.push(marker);
                    }
                }

                results_fragment.appendChild(results_fragment_in_search);
                results_fragment.appendChild(results_fragment_in_viewable);


                for (var propId in same_loc_arr) {
                    var props = same_loc_arr[propId];
                    marker = create_multiple_marker(props);
                    var propertyArray = props.split('_');
                    for (var i = 0; i < propertyArray.length; i++) {
                        var property = properties[propertyArray[i]];
                        if (typeof property != "undefined") {
                            markers[property.id] = marker;
                            map.addOverlay(marker);
                        }
                    }
                }

                $('#ajax-results-list').append(results_fragment);

                $('#ajax-results-list li > div').each(function () {
                    var marker_coords = new GLatLng($(this).data('lat'), $(this).data('lng'));
                    if (!map_bounds.containsLatLng(marker_coords)) {
                        $(this).parent().remove();
                    }
                });

                addScrollbarToResultsBox();
                inViewableArea = false;
                hasShifted = true;
                viewableCallOnce = true;

            }
        });

    }


    //fits the map to the search results
    function fitSearchResults() {
        var bounds = new GLatLngBounds();
        $.each(searchResultsMarkers, function () {
            bounds.extend(this.getLatLng())
        });

        var bZoom = map.getBoundsZoomLevel(bounds);

        if (bZoom > maxZoomLevel)
            bZoom = maxZoomLevel;

        map.setZoom(bZoom);
        map.setCenter(bounds.getCenter());
        if (!hasShifted) {
            map.panBy(new GSize(-250, 0));
        }
    }


    //this adds the scroll bar to the results box
    function addScrollbarToResultsBox() {
        $('.map-details .box-results .results-list .scrollable').jScrollPane({
            verticalDragMinHeight: 25,
            showArrows: true,
            maintainPosition: false
        });
    }

    //this opens and closes the results box when you click on the icon
    $('.box-results .btn-minimize').click(function () {
        $(this).toggleClass('expand');
        $(this).parents('.box-results').find('.box-results-body').slideToggle(function () {
            addScrollbarToResultsBox();

        });
        return false;
    });


    //Shifts the center of the map to the left so it's out of the way of the results box
    function shiftMap() {
        if (hasShifted)
            return;

        map.panBy(new GSize(-250, 0));
    }


    GEvent.addListener(map, "moveend", function () {
        if (map.is_locked) {
            return;
        }

        if (!isExtWindowOpen && !inViewableArea && hasShifted && !viewableCallOnce) {
            getCommunitiesInViewableArea();
        }

    });

    GEvent.addListener(map, "dragstart", function () {
        viewableCallOnce = false;
    });


    $('.map-popup-holder').hover(function () { map.is_locked = true; }, function () { map.is_locked = false; });
})







