﻿google.load("maps", "2.x");

function TUIloadGoogleMap(elementId, options) {
    var element = jQuery('#' + elementId);
    if (element.parent().is(':hidden')) {
        element.parent().show();
    }
    element.googleMap(options);
}

(function(jQuery) {
    jQuery.fn.googleMap = function(options) {
        options = jQuery.extend({
            text_objectLink: 'Read more about {0} »',
            text_zoomLink: 'Zoom in on the map »',
            text_headerClick: 'Resize the map',
            text_moveUp: 'Up a level',
            text_mapHeading: 'Map of {0}',
            text_worldMap: 'World map',
            text_headingSmallMap: 'Map',
            text_rightPanelHeading: 'Popular countries',
            text_chooseCountry: 'Choose country',
            maximized: true,
            onHeaderClick: null,
            headerClick: "toggle",
            showHeader: true, // Lazarev
            calloutId: "google-callout-container",
            mapId: "google-map",
            maxWidth: "655px",
            maxHeight: "655px", // Lazarev
            minWidth: "230px",
            minHeight: "340px",
            rightPanelId: "google-right-panel",
            getMarkersUrl: "/Functions/GoogleMap/MapService.asmx/GetMarkers",
            getMarkerTextUrl: "/Functions/GoogleMap/MapService.asmx/GetMarkerText",
            simpleMode: false,
            defaultZoomLevel: 4,
            enableRightPanel: true, // Lazarev
            margin: "0px"
        }, options);

        return new jQuery.gmap(this, options);
    },

	jQuery.gmap = function(element, options) {
	    // string templates
	    var template_callout = '<div id="{0}-{1}" class="calloutBox"><div class="top"><h3 /></div><div class="center" /><div class="bottom" /><div id="{0}-{1}{2}" class="closeButton" /></div>';
	    var template_mapPanel = '<div id="{0}-{1}" class="mapContainer" />';
	    var template_zoomLink = '<li><img src="/Functions/GoogleMap/Images/Markers/zoom.gif" alt="{0}"> Увеличить на карте</li>';
	    var template_infoArea = '<div class="calloutText fc"><img src="{0}" /><span/><ul>{1}<li><a href="{2}"><img src="/Functions/GoogleMap/Images/Markers/info.gif" alt="{3}"> Узнать больше</a></li></ul></div>';
	    var template_rightMenuObjectCountry = '<li><a href="{2}"><img class="flag" src="{0}" />{1}</a></li>';
	    var template_rightPanel = '<div id="{0}-{1}" class="rightPanel" />';
	    var template_mapHeader = '<div class="countrySelector"><select /></div>';

	    // fields
	    var self = this;
	    var defaultMapData = { p: options.defaultPageLink, lat: "38", lng: "20", zoomLevel: options.defaultZoomLevel };
	    var markerIconFolder;
	    var map;
	    var markerManager;
	    var currentObject;
	    var parentObjectId;
	    var baseMarkers;

	    var mapPanel = jQuery(String.format(template_mapPanel, element.attr('id'), options.mapId)).css({ float: 'left', width: '100%', height: '100%' });

	    var rightPanel = jQuery(String.format(template_rightPanel, element.attr('id'), options.rightPanelId)).css({ height: '100%', overflow: 'hidden', position: 'absolute' });
	    var callout = jQuery(String.format(template_callout, element.attr('id'), options.calloutId, "_close")).css({ display: 'none' });
	    callout.find(String.format("#{0}-{1}{2}", element.attr('id'), options.calloutId, "_close")).click(function() { callout.hide(); });

	    var calloutTimeout;
	    jQuery(callout).mouseleave(function() {
	        jQuery(this).hide();
	    });

	    jQuery(callout).mouseenter(function() {
	        if (calloutTimeout) {
	            clearTimeout(calloutTimeout);
	        }
	    });

	    jQuery("span[id$='MapTab'].ajax__tab_tab").click(function() {
	        self.initMap(currentObject);
	        self.setupMarkers(baseMarkers);
	        // ie fix
	        self.initialize();
	    });

	    var headerPanel = element.siblings('#' + String.format("{0}_headerPanel", element.attr('id')));
	    if (options.showHeader) {
	        var headerActionLink = headerPanel.children('.expandLink').html(options.text_headerClick);
	        if (!options.maximized && options.onHeaderClick != null) {
	            headerActionLink.click(options.onHeaderClick);
	        } else {
	            headerActionLink.click(function() {
	                switch (options.headerClick) {
	                    case "toggle": self.toggle(); break;
	                    case "close": self.close(); break;
	                    case "resize": options.maximized = !options.maximized; self.initialize(); break;
	                    default: self.toggle(); break;
	                }
	            });
	        }
	    } else {
	        headerPanel.hide();
	    }

	    jQuery.extend(this, {

	        initialize: function() {
	            element.empty();
	            callout.hide();

	            // if (options.maximized) { element.css({ width: options.maxWidth, height: options.maxHeight, position: 'relative' }); } // Lazarev
	            if (options.maximized) {
	                element.css({ width: options.maxWidth, height: options.maxHeight, position: 'relative', margin: options.margin });
	            } else { element.css({ width: options.minWidth, height: options.minHeight, position: 'relative', margin: options.margin }); }

	            mapPanel.appendTo(element);

	            if (options.maximized) {
	                if (!options.simpleMode && options.enableRightPanel) {
	                    rightPanel.appendTo(element);
	                }
	                element.find().each(function() {
	                    alert(jQuery(this).html() + "|" + jQuery(this).position().left);
	                });
	                callout.appendTo(element);
	            }

	            jQuery.ajax(options.getMarkersUrl, {
                    type: 'POST',
                    dataType: 'JSON',
                    contentType: 'application/json; charset=utf-8',
	                data: '{currentObject:"' + defaultMapData.p + '"}',
	                success: function(returnValue) {
	                    currentObject = returnValue.d.currentObject;
	                    parentObjectId = returnValue.d.parentObjectId;
	                    self.initMap(currentObject);
	                    markerIconFolder = returnValue.d.markerIconFolder;
	                    if (options.maximized) {
	                        if (!options.simpleMode && options.enableRightPanel) {
	                            self.initializeCountrySelector(returnValue);
	                        }
	                        callout.appendTo(map.getPane(G_MAP_FLOAT_PANE));
	                    }
	                    self.setupMarkers(returnValue.d);
	                    baseMarkers = returnValue.d;
	                },
	                error: function(returnValue) {
	                    self.initMap(defaultMapData);
	                }
	            });
	            //alert(" initialize: function()");
	        },


	        toggle: function() {
	            element.slideToggle(500);
	        },

	        close: function() {
	            element.parent().hide();
	        },

	        moveToObject: function(objectId) {
	            jQuery.ajax(options.getMarkersUrl, {
                    type: 'POST',
                    dataType: 'JSON',
                    contentType: 'application/json; charset=utf-8',
	                data: '{currentObject:"' + objectId + '"}',
	                success: function(returnValue) {
	                    currentObject = returnValue.d.currentObject;
	                    parentObjectId = returnValue.d.parentObjectId;
	                    if (options.maximized) {
	                        callout.hide();
	                    }
	                    map.setMapType(G_NORMAL_MAP);
	                    map.setCenter(new GLatLng(returnValue.d.currentObject.lat, returnValue.d.currentObject.lng), returnValue.d.currentObject.zoomLevel);
	                    self.setupMarkers(returnValue.d);
	                },
	                error: function(returnValue) {
	                    self.initMap(defaultMapData);
	                }
	            });
	        },

	        initMap: function(objectData) {
	            var mapElem = document.getElementById(mapPanel.attr('id'));
	            map = new GMap2(mapElem);
	            map.setMapType(G_NORMAL_MAP);
                var initialPosition;
                try {
	                initialPosition = new GLatLng(objectData.lat, objectData.lng);
	                map.setCenter(initialPosition, objectData.zoomLevel);
                }
                catch (err) {
                }
	            markerManager = new MarkerManager(map, { trackMarkers: true });
	            if (options.maximized) {
	                map.addControl(new GLargeMapControl3D());
	                map.addControl(new GMenuMapTypeControl(), new GControlPosition(G_ANCHOR_TOP_RIGHT, new GSize(10, 10)));
	            } else {
	                map.disableDragging();
	            }
	            //alert("initMap: function(objectData)");
	        },

	        getMarkerIcon: function(marker) {
	            if (options.maximized) {
	                switch (marker.markerType) {
	                    //case "City": return { icon: markerIconFolder + "city.png", shadow: markerIconFolder + "city-shadow.png", hover: markerIconFolder + "city-hover.png", w: 22, h: 37, x: 11, y: 36 };                                                                   
	                    case "Country": return { icon: marker.icon, shadow: markerIconFolder + "country-shadow.png", hover: marker.hoverIcon, w: 30, h: 30, x: 15, y: 28 };
	                    case "Hotel": return { icon: markerIconFolder + "hotel.png", shadow: "", hover: markerIconFolder + "hotel-hover.png", w: 38, h: 33, x: 14, y: 32 };
	                    case "Resort": return { icon: markerIconFolder + "resort.png", shadow: "", hover: markerIconFolder + "resort-hover.png", w: 38, h: 33, x: 14, y: 32 };
	                    default: return { icon: markerIconFolder + "resort.png", shadow: "", hover: markerIconFolder + "resort-hover.png", w: 38, h: 33, x: 14, y: 30 };
	                }
	            }
	            else {
	                switch (marker.markerType) {
	                    //case "City": return { icon: markerIconFolder + "small-city.png", shadow: "", hover: "", w: 13, h: 20, x: 6, y: 20 };                                                                                                                                                                         
	                    case "Country": return { icon: marker.icon, shadow: "", hover: "", w: 30, h: 30, x: 15, y: 28 };
	                    case "Hotel": return { icon: markerIconFolder + "small-hotel.png", shadow: "", hover: "", w: 23, h: 20, x: 8, y: 20 };
	                    case "Resort": return { icon: markerIconFolder + "small-resort.png", shadow: "", hover: "", w: 23, h: 20, x: 8, y: 20 };
	                    default: return { icon: markerIconFolder + "small-resort.png", shadow: "", hover: "", w: 23, h: 23, x: 7, y: 15 };
	                }
	            }
	        },

	        getMarkerOptions: function(marker, markerIcon, labelText) {
	            if (options.maximized) {
	                switch (marker.markerType) {
	                    //case "City": return { "icon": markerIcon, "clickable": true, "labelText": labelText, "title": marker.name, "labelOffset": new GSize(labelText.toString().length > 1 ? -8 : -4, -32) };                                                                                                                                                                     
	                    case "Country": return { "icon": markerIcon, "clickable": true, "title": marker.name };
	                    case "Hotel": return { "icon": markerIcon, "clickable": true, "labelText": labelText, "title": marker.name, "labelOffset": new GSize(labelText.toString().length > 1 ? -7 : -4, -24) };
	                    case "Resort": return { "icon": markerIcon, "clickable": true, "labelText": labelText, "title": marker.name, "labelOffset": new GSize(labelText.toString().length > 1 ? -7 : -4, -24) };
	                    default: return { "icon": markerIcon, "clickable": true, "labelText": labelText, "title": marker.name, "labelOffset": new GSize(labelText.toString().length > 1 ? -7 : -4, -20) };
	                }
	            } else {
	                return { "icon": markerIcon, "clickable": true, "title": marker.name };
	            }
	        },

	        createMarker: function(point, marker, labelText) {
	            var iconData = self.getMarkerIcon(marker);
	            var markerIcon = new GIcon(G_DEFAULT_ICON, iconData.icon);
	            markerIcon.iconSize = new GSize(iconData.w, iconData.h);
	            markerIcon.iconAnchor = new GPoint(iconData.x, iconData.y);
	            markerIcon.shadow = options.maximized ? iconData.shadow : null;
	            markerIcon.imageMap = [0, 0, iconData.w, 0, iconData.w, iconData.h, 0, iconData.h];
	            var marker = new LabeledMarker(point, self.getMarkerOptions(marker, markerIcon, labelText));
	            return marker;
	        },

	        setupMarkers: function(markerData) {
	            var markers = [];
	            markerManager.clearMarkers();

	            var gMarkers = [];
	            var markerCounter = 0;
	            for (var counter = 0; counter < markerData.markers.length; counter++) {
	                if (markerData.markers[counter].lat != '' && markerData.markers[counter].lng != '') {
	                    markers[markerCounter] = markerData.markers[counter];
	                    var point;

	                    point = new GLatLng(markers[markerCounter].lat, markers[markerCounter].lng);

	                    markers[markerCounter].marker = self.createMarker(point, markers[markerCounter], counter + 1);
	                    gMarkers[markerCounter] = markers[markerCounter].marker;
	                    markerCounter++;
	                }
	            }
	            markerManager.addMarkers(gMarkers, 0, 17);
	            markerManager.refresh();

	            jQuery(markers).each(function(i, marker) {
	                if (options.maximized) {
	                    GEvent.addListener(marker.marker, "mouseover", function() {
	                        self.displayPoint(marker);
	                    });
	                    GEvent.addListener(marker.marker, "mouseout", function() {
	                        calloutTimeout = setTimeout("jQuery('.calloutBox').hide();", 1500);
	                    });
	                } else {
	                    GEvent.addListener(marker.marker, "click", function() {
	                        location.href = marker.link;
	                    });
	                }

	                var markerIcon = self.getMarkerIcon(marker);
	                GEvent.addListener(marker.marker, "mouseover", function() {
	                    if (options.maximized) {
	                        marker.marker.setImage(markerIcon.hover);
	                    }
	                });
	                GEvent.addListener(marker.marker, "mouseout", function() {
	                    if (options.maximized) {
	                        marker.marker.setImage(markerIcon.icon);
	                    }
	                });
	            });

	            if (options.maximized && !options.simpleMode && options.enableRightPanel) {
	                self.initializeRightPanel(markerData);
	            }
	            self.setupHeaderHeading();
	        },

	        setupHeaderHeading: function(e) {
	            if (options.showHeader) {
	                var headerText = '';
	                if (currentObject.markerType == "Unknown") {
	                    headerText = options.text_worldMap;
	                } else if (options.maximized) {
	                    headerText = String.format(options.text_mapHeading, currentObject.name);
	                }
	                else {
	                    headerText = options.text_headingSmallMap;
	                }
	                headerPanel.children('h2.headerHeading').html(headerText);
	            }
	        },

	        initializeCountrySelector: function(markers) {
                return;
	            var selector = jQuery(template_mapHeader);
	            var selectorOptions = selector.find("select:first");
	            selectorOptions.empty();
	            var template_selectorOption = '<option {0} value="{1}"><img src="{3}" />{2}</option>';
	            jQuery(String.format('<option value="0">{0}</option>', options.text_chooseCountry)).appendTo(selectorOptions);
	            jQuery(markers.markers).each(function(i, country) {
	                var sel = '';
	                if (country.objectId == currentObject.objectId) {
	                    sel = 'selected';
	                }
	                var listItem = jQuery(String.format(template_selectorOption, sel, country.objectId, country.name, country.icon));
	                listItem.appendTo(selectorOptions);
	            });
	            selectorOptions.get(0).onchange = function(e) {
	                var selected = jQuery("option:selected", selectorOptions);
	                for (var i = 0; i < markers.markers.length; i++) {
	                    if (markers.markers[i].objectId == selected.val()) {
	                        self.goToCountry(markers.markers[i]);
	                    }
	                }
	            };
	            //selector.insertAfter(element); 
	            selector.insertBefore(element); // Lazarev; moving dropdownlist above googlemap.
	            element.parent().find(".countrySelector select:first").selectList();
	        },

	        goToCountry: function(marker) {
	            if (currentObject.p != defaultMapData.p) {
	                self.setupMarkers(baseMarkers);
	            }
	            map.setZoom(options.defaultZoomLevel);
	            self.displayPoint(marker);
	        },

	        initializeRightPanel: function(markerData) {
	            var markerList = jQuery('<ul class="markerlist" />');
	            var rightPanelMarkers = markerData.rightPanelMarkers;

	            jQuery(rightPanelMarkers).each(function(i, marker) {
	                marker.marker = self.createMarker(new GLatLng(marker.lat, marker.lng), marker, '');
	                var listItem = jQuery(String.format(template_rightMenuObjectCountry, marker.icon, marker.name, marker.link)).click(function() {
	                    //self.goToCountry(marker);
	                }).appendTo(markerList);
	            });

	            rightPanel.empty();
	            jQuery('<div class="heading">' + options.text_rightPanelHeading + '</div>').appendTo(rightPanel);
	            markerList.appendTo(rightPanel);
	        },

	        displayPoint: function(marker) {
	            if (marker.marker == null) {
	                return;
	            }
	            var markerOffset = map.fromLatLngToDivPixel(marker.marker.getLatLng());

	            if (options.maximized) {
	                // Popup left position to make it feat in map window
	                var markerLeftToContainer = map.fromLatLngToContainerPixel(marker.marker.getLatLng()).x;
	                var mapAreaWidth = jQuery(".GoogleMapBlock .GoogleMap").width() - jQuery(".GoogleMapBlock .rightPanel").width();
	                var calloutLeft = markerOffset.x - callout.width() / 2;
	                if (markerLeftToContainer < callout.width() / 2 + 10) {
	                    calloutLeft = calloutLeft + callout.width() / 2 + 10 - markerLeftToContainer;
	                }
	                if (markerLeftToContainer > mapAreaWidth - callout.width() / 2) {
	                    calloutLeft = calloutLeft - (markerLeftToContainer - (mapAreaWidth - callout.width() / 2));
	                }

	                // Popup bottom position to make it feat in map window
	                var mapAreaHeight = jQuery(".GoogleMapBlock .GoogleMap").height() - jQuery(".GoogleMapBlock .countrySelector").height();
	                var markerTopToContainer = map.fromLatLngToContainerPixel(marker.marker.getLatLng()).y;
	                var calloutBottom = -markerOffset.y + 10 - callout.height() - 4;
	                if (markerTopToContainer + callout.height() > mapAreaHeight - 10) calloutBottom = -markerOffset.y + 15;


	                //markerOffset.x = markerOffset.x + 60;              


	                // Set text values
	                var zoomLinkHtml = '';
	                if (marker.markerType != "Hotel") {
	                    zoomLinkHtml = String.format(template_zoomLink, options.text_zoomLink);
	                }

	                var infoArea;
	                if (options.simpleMode) {
	                    infoArea = callout.children(".center").html(String.format(template_infoArea, marker.image, "", marker.link, String.format(options.text_objectLink, marker.name)));
	                } else {
	                    infoArea = callout.children(".center").html(String.format(template_infoArea, marker.image, zoomLinkHtml, marker.link, String.format(options.text_objectLink, marker.name)));
	                    if (marker.markerType != "Hotel") {
	                        infoArea.find("ul li:first").click(function() { self.moveToObject(marker.p); });
	                    }
	                }

	                // Ajax call
	                self.setMarkerText(marker.p, infoArea.find('div.calloutText span'));

	                callout.find(".top h3").html(marker.name);

	                callout.hide();

	                var moveEnd = GEvent.addListener(map, "moveend", function() {
	                    //callout.fadeIn().css({ bottom: calloutBottom, left: calloutLeft });
	                    //GEvent.removeListener(moveEnd);
	                    //clearTimeout(calloutTimeout);
	                });

	                var move = GEvent.addListener(map, "move", function() {
	                    //callout.fadeIn().css({ bottom: calloutBottom, left: calloutLeft });
	                    //GEvent.removeListener(moveEnd);
	                    //clearTimeout(calloutTimeout);
	                    callout.css("display", "none");
	                });

	            }

	            //map.panTo(map.fromDivPixelToLatLng(markerOffset)); //don't move map on flag selected

	            if (options.maximized && callout.is(":hidden")) {
	                callout.fadeIn().css({ bottom: calloutBottom, left: calloutLeft });
	                clearTimeout(calloutTimeout);
	            }
	        },

	        setMarkerText: function(markerId, domObject) {
	            jQuery.ajax(options.getMarkerTextUrl, {
                    type: 'POST',
                    dataType: 'JSON',
                    contentType: 'application/json; charset=utf-8',
	                data: '{currentObject:"' + markerId + '"}',
	                success: function(returnValue) {
	                    domObject.html(returnValue.d);
	                },
                    error: function(msg) {
                        ;
                    }
	            });
	        }

	    });

	    self.initialize();
	}

})(jQuery);

