﻿Lamco.Mapping = (function() {
    var map;
    var streetView;
    var streetViewClient;
    var markerManager;
    var geocoder;
    var icons = {};
    var enableStreetView = true;
    var infoBubbleInterval;
    var currentPanoramaDataLat;
    var currentPanoramaDataLong;

    var initializeIcons = function() {
        var createIcon = function(imageUrl, key) {
            var icon = new GIcon();

            icon.image = imageUrl;
            icon.iconSize = new GSize(36, 36);
            icon.iconAnchor = new GPoint(1, 1);
            icon.infoWindowAnchor = new GPoint(0, 0);
            icon.imageMap = [
					9, 5,
					33, 9,
					34, 37,
					9, 35];

            icons[key] = icon;
        };

        createIcon('/Images/property.png', 'Listing');
        createIcon('/Images/contractor.png', 'Contractor');
        createIcon('/Images/realestateagent.png', 'RealEstateAgent');
        createIcon('/Images/group.gif', 'Group');
        createIcon('/Images/titlecompany.gif', 'TitleCompany');
        createIcon('/Images/mortgagecompany.gif', 'MortgageCompany');
        createIcon('/Images/realestatelawyer.gif', 'RealEstateLawyer');
        createIcon('/Images/otherservice.gif', 'OtherService');
    };

    var initializeMap = function() {
        map = new GMap2($("#Map")[0]);

        // Continental USA View
        map.setCenter(new GLatLng(38.7185903, -97.9316406), 4);

        map.addControl(new GLargeMapControl());
        map.addControl(new GMapTypeControl());

        map.setMapType(G_NORMAL_MAP);
        map.enableScrollWheelZoom();

        markerManager = new MarkerManager(map);

        $("body").unload(function() { GUnload(); });
    };

    var initializeStreetView = function() {
        streetView = new GStreetviewPanorama($("#StreetView")[0]);

        GEvent.addListener(streetView, "error", disableStreetView);
        $('#StreetView').hide();
        $('#StreetViewContainer').hide();
        $('#StreetViewCloseButton').hide();
        $('#IFrameClose').hide();

        // set up button to close street view when clicked
        $('#StreetViewCloseButton').click(function(event) {
            $('#StreetView').hide();
            $('#StreetViewContainer').hide();
            $('#StreetViewCloseButton').hide();
            $('#IFrameClose').hide();
            $('#Map').show();
            $(this).hide();
        });

        streetViewClient = new GStreetviewClient();
    };

    var disableStreetView = function(errorCode) {
        if (errorCode == 603) {
            // No flash, no street view
            enableStreetView = false;
        }
    };

    return {
        Initialize: function() {
            geocoder = new GClientGeocoder();

            // For location edit controls
            var locationSubmitClickHandler = function(event) {
                var button = $(this);

                button.attr('disabled', 'disabled');

                var hcard = $(this).parents('table');
                var streetAddress = hcard.find('.street-address input').val();
                var city = hcard.find('.locality input').val();
                var state = hcard.find('.region').val();
                var zip = hcard.find('.postal-code input').val();

                event.preventDefault();

                if (streetAddress && city && state && zip
					&& streetAddress.length > 0 && city.length > 0 && state.length > 0 && zip.length > 0) {
                    var address = streetAddress + ' ' + city + ', ' + state + ' ' + zip;

                    geocoder.getLatLng(address,
						function(geocodedPoint) {
						    button.removeAttr('disabled');

						    if (geocodedPoint) {
						        // Good to go, update the hidden fields and submit
						        hcard.find('input[id$=hfLatitude]').val(geocodedPoint.lat());
						        hcard.find('input[id$=hfLongitude]').val(geocodedPoint.lng());

						        __doPostBack(button.attr('name'), '');
						    } else {
						        // Display error, re-attach handler
						        alert('Could not find that address, please check that you have entered it correctly.');
						        button.one('click', locationSubmitClickHandler);
						    }
						});
                }
                else {
                    button.removeAttr('disabled');
                    button.one('click', locationSubmitClickHandler);
                }
            };

            $('.VCardInput input[type=submit]').one('click', locationSubmitClickHandler);
        },
        ShowPopupMultiHcard: function(point, hcardList) {
            // Clear pre-existing to prepare to add new one
            $('#GroupInfoBubble').remove();
            var bubbleContents;

            // Set the header to be the address of the location of grouping
            var addressHeaderDiv = $('<div />');
            addressHeaderDiv.css('font-size', 14);
            addressHeaderDiv.css('font-weight', 'bold');
            addressHeaderDiv.append(hcardList.getElementAt(0).find('.street-address').text());

            // Create contractor section
            var contractorHeader = $('<p>Contractors</p>');
            contractorHeader.addClass('InfoBubbleGroupingHeaders');
            var contractorList = $('<ul />');

            // Create real estate agent section
            var realEstateHeader = $('<p>Real Estate Agents</p>');
            realEstateHeader.addClass('InfoBubbleGroupingHeaders');
            var realEstateAgentList = $('<ul />');

            // Create listing section (technically there shouldn't be more than one)
            var listingHeader = $('<p>Listings</p>');
            listingHeader.addClass('InfoBubbleGroupingHeaders');
            var listingList = $('<ul />');

            // Loop through each hcard and place each one
            // in the proper list (contractor, real estate agent, listing)
            for (var i = 0; i < hcardList.size(); i++) {
                var listItem = $('<li />');
                var listItemText = "";
                var listItemDetailsLink;

                var card = hcardList.getElementAt(i);

                listItemDetailsLink = card.find('.detail-link').clone();
                listItemDetailsLink.css('color', 'blue');

                if (card.hasClass("Listing")) {
                    // Get details link from card 
                    listItem.append(listItemDetailsLink);
                    listingList.append(listItem);
                }
                else {
                    listItemText = card.find('.person-name').html();
                    listItem.append(listItemText);
                    listItem.append(listItemDetailsLink);
                    if (card.hasClass("Contractor")) {
                        contractorList.append(listItem);
                    }
                    else {
                        realEstateAgentList.append(listItem);
                    }
                }
            }
            // Selectively add Contractor , Real Estate Agent, and Listing sections
            // as they might not all contain any items

            bubbleContents = $('<div id="GroupInfoBubble" />').append(addressHeaderDiv);
            bubbleContents.append('<br />');

            if (contractorList.find('li').size() > 0) {
                bubbleContents.append(contractorHeader);
                bubbleContents.append(contractorList);
            }
            if (realEstateAgentList.find('li').size() > 0) {
                bubbleContents.append(realEstateHeader);
                bubbleContents.append(realEstateAgentList);
            }
            if (listingList.find('li').size() > 0) {
                bubbleContents.append(listingHeader);
                bubbleContents.append(listingList);
            }

            map.openInfoWindow(point, bubbleContents[0]);
        },
        ShowPopup: function(point, hcard) {
            // Remove GPanoramaView and re-add so it doesn't keep 
            // referencing the previous location when a new location is provided
            streetView.remove();
            clearInterval(infoBubbleInterval);
            streetView = new GStreetviewPanorama($("#StreetView")[0]);

            GEvent.addListener(streetView, "error", disableStreetView);
            $('#StreetView').hide();
            $('#StreetViewContainer').hide();
            $('#StreetViewCloseButton').hide();
            $('#IFrameClose').hide();

            // set up button to close street view when clicked
            $('#StreetViewCloseButton').click(function(event) {
                $('#StreetView').hide();
                $('#StreetViewContainer').hide();
                $('#StreetViewCloseButton').hide();
                $('#IFrameClose').hide();
                $('#Map').show();
                $(this).hide();
            });

            // Clear pre-existing to prepare to add new one
            $('#InfoBubble').find('.MainText a.StreetView').remove();
            $('#InfoBubble').remove();
            var bubbleContents;

            // cloned hcard contents that will be altered before
            // being added to the bubbleContents
            var temp;

            if (!hcard[0].innerHTML.startsWith('<TABLE')) {
                temp = $('<table />').append(hcard.contents().clone());
            }
            else {
                temp = hcard.contents().clone();
            }

            // Manipulate the original hcard to allow for 
            // a larger image and move text into other columns
            var imageCol = temp.find('.ListItemImage').clone();
            temp.find('.ListItemImage').remove();
            temp.find('.ListItemRow').append(imageCol);
            temp.find('.SearchResultImage').hide();
            temp.find('.InfoBubbleImage').show();

            // Move detail section out of it's row up into the
            // List Item text to prevent gaps in whitespace between the
            // detail link and the listing content
            if (hcard.hasClass("Listing")) {
                var detailSection = temp.find('.DetailsStreetView').clone();
                temp.find('.DetailsStreetView').remove();
                temp.find('.MainText').append(detailSection);
            }
            // Put additional text into main text column
            if ($('.ListItemTextFull').length > 0) {
                var listItemFullText = temp.find('.ListItemTextFull').clone();
                temp.find('.ListItemTextFull').remove();
                temp.find('.MainText').append(listItemFullText.html());
            }

            temp.find('.ListItemText').removeClass('ListItemTextSearch');
            // Increase font size of info bubble header section (Address or person name)
            temp.find('.adr').css('font-size', 14);
            // Pad main image
            temp.find('.ListItemImage').css('padding-left', 10);

            bubbleContents = $('<div id="InfoBubble" />').append(temp);

            if (enableStreetView) {
                $('#Map').show();
                $('#StreetView').hide();
            }
            map.openInfoWindow(point, bubbleContents[0]);

            if (enableStreetView) {
                streetViewClient.getNearestPanoramaLatLng(point,
					function(panoramaData) {
					    var streetViewSection = $('#InfoBubble').find('.MainText');
					    if (panoramaData == null) {

					        streetViewSection.find('a.StreetView').hide();
					        return;
					    }
					    if (panoramaData.code == 200) {
					        streetViewSection.find('a.StreetView').hide();
					        enableStreetView = false;
					        return;
					    }

					    currentPanoramaDataLat = panoramaData.lat();
					    currentPanoramaDataLong = panoramaData.lng();

					    infoBubbleInterval = setInterval(
							function() {

							    if ($('#InfoBubble').length > 0) {
							        var sectionToAppendStreetView = $('#InfoBubble').find('.MainText');
							        if (sectionToAppendStreetView.find('a.StreetView').length == 0) {

							            //var sectionToAppendStreetView = hcard.hasClass("Listing") ? $('#InfoBubble').find('.MainText') : $('#InfoBubble');
							            sectionToAppendStreetView
										.append('<a style="color:blue; font-size:7pt;" class="StreetView" href="#">Street View</a>')
										.find('.StreetView')
										.click(function(event) {
										    $('#Map').hide();
										    $('#StreetView').show();
										    $('#StreetViewCloseButton').show();
										    $('#StreetViewContainer').show();
										    $('#IFrameClose').show();

										    streetView.setLocationAndPOV(Lamco.Mapping.GetCurrentPanoramaLatLong());

										    event.preventDefault();
										});
							            sectionToAppendStreetView.find('a.StreetView').show();
							        }
							        clearInterval(infoBubbleInterval);
							    }
							},
						100)
					});
            }
        },
        GetCurrentPanoramaLatLong: function() {
            return new GLatLng(currentPanoramaDataLat, currentPanoramaDataLong);
        }
        ,

        AddVCardLocations: function() {
            var itemMarkers = [];
            var hashedPoints = new Hash();
            var cityPoints = [];
            var waitMarkerCount = 0;
            var bounds = new GLatLngBounds();

            initializeMap();
            initializeStreetView();
            initializeIcons();

            // Dealing with async geolocation
            var commitMarkers = function() {
                if (waitMarkerCount == 0) {
                    // Min/Max zoom level to display markers
                    markerManager.addMarkers(itemMarkers, 7, 17);

                    cityPoints = $.map(cityPoints, function(item, index) {
                        return new GMarker(new GLatLng(item.lat / item.count, item.lng / item.count), { icon: new GIcon(icons["Group"]) });
                    });

                    markerManager.addMarkers(cityPoints, 1, 6);

                    markerManager.refresh();
                }
            };

            // hash points (the value will be a collection of hcards belonging to the same point)
            $(".vcard").each(function() {
                var hcard = $(this);
                var latitude = hcard.find('.latitude').text();
                var longitude = hcard.find('.longitude').text();

                if (hcard.hasClass('ListItemMain')) {
                    if (hashedPoints[latitude + ' ' + longitude] == undefined) {
                        // Add a new collection list of hcards and add the hcard to that list
                        var emptyHCardCollection = new CCollection();
                        emptyHCardCollection.add(hcard);
                        hashedPoints[latitude + ' ' + longitude] = emptyHCardCollection;
                    }
                    else {
                        // value already exists 
                        // so add hcard to value list
                        var hCardCollection = hashedPoints[latitude + ' ' + longitude];
                        hCardCollection.add(hcard);
                    }
                }
            });

            var hashKeys = hashedPoints.keys();

            for (i in hashKeys) {
                var key = hashKeys[i];
                // guaranteed to have at least one
                // and given that there are potentially
                // multiples, we can use one as reference for
                // the city, lat, long
                var tempHcardList = hashedPoints[key];
                var hcard = tempHcardList.getElementAt(0);
                var latitude = hcard.find('.latitude').text();
                var longitude = hcard.find('.longitude').text();
                var city = hcard.find('.locality').text() + ':' + hcard.find('.region').text();

                var handlePoint = function(point, hcardList) {
                    if (point) {
                        bounds.extend(point);

                        var itemType = hcardList.size() > 1
								? "Group"
								: hcard.hasClass("Listing")
									? "Listing"
									: hcard.hasClass("Contractor")
										? "Contractor"
										: hcard.hasClass("RealEstateAgent")
											? "RealEstateAgent"
											: hcard.hasClass("TitleCompany")
												? "TitleCompany"
												: hcard.hasClass("MortgageCompany")
													? "MortgageCompany"
													: hcard.hasClass("RealEstateLawyer")
														? "RealEstateLawyer"
														: hcard.hasClass("OtherService")
															? "OtherService"
															: "";
                        if (itemType.length > 0) {

                            var marker = new GMarker(point, { icon: new GIcon(icons[itemType]) });

                            // Wire up click event for each hcard item in the hcard list
                            for (var idx = 0; idx < hcardList.size(); idx++) {
                                hcardList.getElementAt(idx)
									.click(function() {
									    map.setCenter(point, map.getZoom());
									    Lamco.Mapping.ShowPopup(point, $(this));
									})
									.css('cursor', 'pointer');
                            }

                            var iconPointClick = function() {
                                Lamco.Mapping.ShowPopup(point, hcardList.getElementAt(0));
                            }

                            var multiItemPointClick = function() {
                                Lamco.Mapping.ShowPopupMultiHcard(point, hcardList);
                            }

                            GEvent.addListener(marker, "click", hcardList.size() > 1 ? multiItemPointClick : iconPointClick);

                            itemMarkers.push(marker);

                            var found = false;
                            $.each(cityPoints, function(index, item) {
                                if (item.city == city) {
                                    cityPoints[index] = { 'city': city, lat: item.lat + new Number(point.lat()), lng: item.lng + new Number(point.lng()), count: item.count + 1 };
                                    found = true;
                                    return false;
                                }
                            });
                            if (!found) {
                                cityPoints.push({ 'city': city, lat: new Number(point.lat()), lng: new Number(point.lng()), count: 1 });
                            }
                        }
                    }
                };

                if (latitude && longitude && latitude != 0 && longitude != 0) {
                    handlePoint(new GLatLng(latitude, longitude), tempHcardList);
                } else {
                    var address =
						hcard.find('.street-address').text() + ' ' +
						city + ', ' +
						hcard.find('.region').text();

                    waitMarkerCount++;

                    geocoder.getLatLng(address,
						function(geocodedPoint) {
						    handlePoint(geocodedPoint, tempHcardList);
						    waitMarkerCount--;
						    commitMarkers();
						});
                }
            }

            commitMarkers();
            if (bounds.isEmpty()) {
                map.setCenter(new GLatLng(38.7185903, -97.9316406), 4);
            }
            else {
                map.setZoom(map.getBoundsZoomLevel(bounds));
                map.zoomOut();
                map.setCenter(bounds.getCenter());
            }
        },

        DisplayListingDetails: function(listingId) {

            var data = '<iframe src="/ListingDetails.aspx?id=' + listingId + '" runat="server" id="modalPopupFrame" class="DetailFrame" />';
            $(data).modal();

            return false;
        },

        DisplayPersonDetails: function(userId) {
            var data = '<iframe src="PersonDetails.aspx?id=' + userId + '" runat="server" id="modalPopupFrame" class="DetailFrame" />';
            $(data).modal();

            return false;
        },

        DisplayPersonDetailsFromListing: function(userId) {
            // This is the containing html element in the parent iframe
            var containingHtml = $("html");

            containingHtml.css('overflow', 'hidden');

            var data = '<iframe src="PersonDetails.aspx?id=' + userId + '" runat="server" id="modalPopupFrameFromListing" class="DetailFrameFromListing" />';

            $(data).modal({
                closeHTML: '<div class="FromListingHeader"><a title="Close">Return to Property Listing</a></div>',
                onClose: function(dialog) {
                    containingHtml.css('overflow', 'auto');
                    $.modal.close();
                }
            });


            return false;
        }
    }
})();



