// CONFIGURATION FOR THE MAP
var mapCONFIG = {
    gIcon: [],
    gIconImages: [],
    initialize: function(){
        // set up pulte icons for the 3 sites + marker
        var mapIcon = new GIcon();
        mapIcon.shadow = "/img/locators/gIcon-shadow.png";
        mapIcon.iconSize = new GSize(22, 28);
        mapIcon.shadowSize = new GSize(37, 28);
        mapIcon.iconAnchor = new GPoint(10, 28);
        mapIcon.infoWindowAnchor = new GPoint(1, 3);
        mapIcon.printShadow = "/img/locators/gIcon-shadow.gif";
        // default icon
        this.gIcon['default'] = new GIcon(mapIcon);
        this.gIcon['default'].image = "/img/locators/gIcon-default.png";
        this.gIcon['default'].printImage = "/img/locators/gIcon-default.gif";
        this.gIcon['default'].mozPrintImage = "/img/locators/gIcon-default.gif";

        // center icon
        this.gIcon['home'] = new GIcon(mapIcon);
        this.gIcon['home'].image = "/img/locators/gIcon-home.png";
        this.gIcon['home'].printImage = "/img/locators/gIcon-home.gif";
        this.gIcon['home'].mozPrintImage = "/img/locators/gIcon-home.gif";
        // on images
        this.gIconImages['default'] = {imageOn: "/img/locators/googleIcon-flagOn.png", imageOff: "/img/locators/googleIcon-flag.png"};
        this.gIconImages['home'] = {imageOn: "/img/locators/googleIcon-flagOn.png", imageOff: "/img/locators/googleIcon-flag.png"};
    }
};

mapCONFIG.initialize();
// end of map configuration ----------------------------------------

if (!VISA) { VISA = {}; }

VISA.signatureSCV = (function() {

	/* utility functions */
	if (typeof console == 'undefined') {
		console = {
			log: function(msg) { /* alert("log: " + msg); */ },
			warn: function(msg) { /* alert("warn: " + msg); */ }
		};
	}
	
	// template is a jQuery DOM reference
	// obj is a JS object
	// returns new jQ node
	function templatize(obj, $template) {
		$template = $($template); // make sure it is a jQ object
		$template = $template.clone();
		var html = $template.html();
		$.each(obj, function(key, val) {
            html = html.replace(new RegExp("{" + key + "}", "g"), val);
		});
		html = html.replace(/\{[^\}]+\}/g, ""); // remove unmatched items
		return $template.html(html);
	}
	
	// object to show and hide the progress meter, and block out the form elements, while network calls are made
	var progress = {
		count: 0,
		show: function(text) {
			$("#progress").show();
            $("#find").hide();
            this.count++;
		},
		hide: function(text) {
			if (--this.count <= 0) {
				this.count = 0;
				$("#progress").hide();
                $("#find").show();
            }
		}
	}
	
	
	/* paywave code */
	var map;
    var map_mgr;
    var geocoder;
    var all_drawn = false;
    var center_point;
	var origin_marker;
	var current_location;
    var geo_result;
    var existing_markers = [];
    var stores = [];
	var categories = {}; // populated with an Array from the server, but stored as a Hash for easy access
    var maxResultsCnt = 25;

    function error(message) {
		var $error = $("#addresses .error");
		if ($error.length < 1) {
			$error = $("<div>").addClass("error").prependTo("#addresses");
		}
		// make sure error will be seen
		if ($("#mapSonoma").width() > 400) { toggle_map_width(); }
		$error.html(message).show();
	}

	function resize_contents() {
		var height = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight;
		var width = $("#mapSonoma").width(); // doesn't change, needed for map size method
        var merchantHeight = 0;
        var sub = getAbsoluteTop($("#results").get(0)) + merchantHeight - 5;
		height = Math.max(height - sub, 340); // must be at least 340
		height = Math.min(height, 340); // cap the height at 600
		// sometimes on IE the map is not fully initialized and this will fail
		// we can safely ignore this exception
		try {
			$("#mapSonoma").css('width', width + "px");
            $("#mapSonoma").css('height', height + "px");
            map.checkResize();
		} catch(e) {
			// ignore
		}
		$(".resizable").stop().height(height);
		$("#addresses").height(height-20);
	}
	
	function toggle_map_width(event) {
		var height = $("#mapSonoma").height();
		var width = $("#mapSonoma").width();
		var full = $("#results").width();
		var new_width = width < full ? full : 400;
		
		if (width < full) {
			$("#expander").addClass("open").removeClass("hover");
			$("#list").hide();
		}
		if (map) {
            $("#mapSonoma").css('width', new_width + "px");
            $("#mapSonoma").css('height', height + "px");
            map.checkResize();
        }
		$("#mapSonoma").width(new_width);
		$("#expander").css({left: new_width-18});
		if (width >= full) {
			$("#expander").removeClass("open hover");
			$("#list").show();
		}
	}
	
	// application intro animation and initialization
	// these are nested to avoid conflicting animations: they are sequential
	$(document).ready(function() {

        // we are animating multiple items, so this event gets fired multiple times
		// but it only responds once
		$(document).one("init", function() {
            generateListings();
            VISA.ui.tabs('#content', init_gmap);
		});

        $("#results").slideDown("fast", function() {
                $(document).trigger("init");
        });
        
		//init_analytics();
	});

    function generateListings (){
        if(typeof wineries === "undefined" || wineries.length < 1) return;
        stores = $.map(wineries, function(json) {
            return new Store(json);
        });
        //stores.sort(function(a, b) { return a.name > b.name; });
        //stores.sort();
        var ohtml = $('<ul></ul>');
        var half = stores.length / 2;
        $.each(stores, function(i, store){
            if(i >= half) {
                half=stores.length + 2;
                $('#winery-listings').append(ohtml);
                ohtml = $('<ul></ul');
            }
            ohtml.append('<li><a href="' + store.url + '" target="_blank">' + store.name + '</a></li>');
        });

        $('#winery-listings').append(ohtml);
        $('#winery-listings').append('<div class="cleaner">&nbsp</div>');
    }

    function init_gmap() {

        // display the link
        // this link to be displayed on both tabs - Dec 02 2009
        if(!$('#google-map').hasClass("selected")) {
            $('.tabs .pdfLink').show();
            return;
        }
        $('.tabs .pdfLink').show();
        if($("#mapSonoma").hasClass("loaded")) return;
        $('#mapSonoma').addClass("loaded");
        $("#expander").click(toggle_map_width);
        if (GBrowserIsCompatible()) {
            map = new GMap2($("#mapSonoma").get(0));
            map.setCenter(new GLatLng(37.4419, -122.1419), 13);
            var customUI = map.getDefaultUI();
            customUI.controls.largemapcontrol3d  = true;
            customUI.controls.maptypecontrol  = false;
            customUI.controls.menumaptypecontrol = false;
            map.setUI(customUI);
            map_mgr = new MarkerManager(map);

            if(typeof wineries === "undefined" || wineries.length < 1) return;

            // create store object
            all_drawn = false;
            filter_stores();
           
            // set the isclicked to be false
            GEvent.addListener(map, 'extinfowindowbeforeclose', function(){
                var openedWin = map.getExtInfoWindow();
                openedWin.marker_.isClicked = false;
            });
        }
        resize_contents();
    }

    function init_analytics() {
		// add some default parameters to all analytics calls from this page
		VISA.Analytics.addParameters({
			application:     "paywave",
			filter_category: function() { return $("#categories").val() || $("#categories :selected").val(); },
			map_location:    function() { return current_location; },
			map_coordinates: function() { return (center_point ? center_point.Lat + "," + center_point.Lon : ""); },
			map_size:        function() { return $("#mapSonoma").width() + "," + $("#mapSonoma").height(); }
		});
		
		// set up some custom analytics regions of the page
		$("#mapSonoma, #list").addClass("analytics");

		// bind and trigger an initial event beacon
		$("#mapSonoma").bind("applicationLoaded", VISA.Analytics.event).trigger("applicationLoaded");
	}

    function create_marker(point, html, iconType, address, zoom){
        
        var marker;
        marker = new GMarker( point, mapCONFIG.gIcon[iconType]);
        marker.GeoPoint = point;
        marker.isClicked = false;
        marker.hideFlag = false;
        var custZoom = 16;
        if(zoom) custZoom = zoom;
        //marker.imageOff = mapCONFIG.gIconImages[iconType].imageOff
        GEvent.addListener(marker, 'click', function(){
            marker.isClicked = true;
            if(typeof address != "undefined"){
               $("#results .selected").removeClass("selected");
               $(address).addClass("selected");
               var offset = $(address).get(0).offsetTop + 1; // sometimes is -1?
               $("#addresses").stop().scrollTo({ left: 0, top: offset }, 500);
            }
            // close any open tool tip
            map.closeTooltipWindow();
            marker.openExtInfoWindow(
                map,
                "g_win",
                "<div class='contents'>" + html + "</div>",
                {beakOffset: 10}
            );
            window.setTimeout(function(){map.setCenter(point, custZoom);}, 200);
			//marker content size fix for FF & Chrome - 1/9/12
			$('#g_win_contents').css('height','auto');
          });

        GEvent.addListener(marker, 'mouseover', function(){
            if(!marker.isClicked) {
                //marker.setImage(mapCONFIG.gIconImages[iconType].imageOn);
                marker.openTooltipWindow(
                    map,
                    "g_tip",
                    "<div class='contents'>" + html + "</div>",
                    {beakOffset: 10}
                );
            }
        });
        GEvent.addListener(marker, 'mouseout', function(){
            if(!marker.isClicked){
                //marker.setImage(mapCONFIG.gIconImages[iconType].imageOff);
                map.closeTooltipWindow();
            }
        });
        return marker;
    }
    
    function filter_stores() {
		progress.show("filter stores");

		$("#addresses").scrollTo({ left: 0, top: 0 }, 0);
		
		$.each(stores, function(i, store) {
            store.draw();
        });

        if(!all_drawn){
            if(existing_markers.length > 0){
                map_mgr.addMarkers(existing_markers, 0);
            }
            all_drawn = true;
        }
        
        map_mgr.refresh();
        zoomToMarkers(10, 10, stores);


        // add alt color on address area (we are doing it here is because payweve has category filter that will just hide stores
        $("#addresses .address:not(:hidden)").each(function(i){
            if(i%2 == 0){
                $(this).addClass("odd");
            } else {
                $(this).removeClass("odd");
            }
        });
        
        progress.hide("filter/draw stores");
	}
	
	// zoom to the first 20 markers
    function zoomToMarkers (slopPercentage, heightOffsetPct, filtered_stores) {
        if(!filtered_stores || !filtered_stores.length || filtered_stores.length < 1) return;

        var count = 0;
        var thePoint, x, y, minX, maxX, minY, maxY, span;

        $.each(filtered_stores, function(i, store){

                thePoint = store.GeoPoint;
                x = thePoint.lat()*1.0000000000000000; y = thePoint.lng()*1.0000000000000000;
                if (count == 0)
                {
                    minX = x; maxX = x; minY = y; maxY = y;
                }
                else
                {
                    if (x < minX) minX = x;
                    if (x > maxX) maxX = x;
                    if (y < minY) minY = y;
                    if (y > maxY) maxY = y;
                }
                count++;
                if(count > 24) return false;

        });

        if (count == 1)
            map.setCenter(new GLatLng(x,y), map.getZoom());
        else if (count > 1)
        {
            var center = new GLatLng((minX + maxX) / 2, (minY + maxY) / 2);
            span = new GSize(Math.abs(maxX - minX), Math.abs(maxY - minY));
            var slopWid = 0;
            var slopHgt = 0;
            var deltaHgt = 0;

            if (typeof slopPercentage != "undefined")
            {
                slopWid = span.width * slopPercentage / 200;
                slopHgt = span.height * slopPercentage / 200;
                span.width  *= 1 + slopPercentage / 100;
                span.height *= 1 + slopPercentage / 100;
            }

            if (typeof heightOffsetPct != "undefined")
            {
                deltaHgt = span.height * heightOffsetPct / 100;
                center = new GLatLng(center.lat() + deltaHgt, center.lng());
            }
            // needs slop
            var bounds = new GLatLngBounds(new GLatLng(minX-slopHgt, minY-slopWid), new GLatLng(maxX+slopHgt, maxY+slopWid)); // sw, ne
            var zoom = map.getBoundsZoomLevel(bounds);
            map.setCenter(center, zoom);
        }
    }
    
	/*** start Store prototype ***/
	
	function Store(json) {
		$.extend(this, json);

		try {
			this.GeoPoint = new GLatLng(this.latitude, this.longitude);

		} catch(e) {
			console.log("failed to set the distance"); // IE is sometimes failing, not sure why
		}
	}
	
	Store.prototype.draw = function() {
		this.$address = templatize(this, "#templates > .address");
		var $marker = templatize(this, "#templates > .overlay");

        if(this.phoneno == "null" || this.phoneno == null){
            $marker.find(".phone_no").remove();
        }
        // if tandem wine, remove address and driving direction
        if(this.name.indexOf("Tandem Wines") > -1){
            this.$address.find(".directions").remove();
            this.$address.find(".details").remove();
            $marker.find(".directions").remove();
            $marker.find(".details").children().not(":first-child").remove();

        }

        if (this.logo) {
			$marker.find(".logo").append("<a href='" + this.url + "' title='" + this.name + "'><img src='" + this.logo + "' alt='" + this.name + "' /></a>");
		}

        var end_loc = escape([this.address1, this.city, this.state, this.zip].join(","));

        $marker.find(".directions a")
			.attr("href", "http://maps.google.com/maps?saddr=&daddr=" + end_loc);

        var iconType = "default";

		var gmarker = create_marker(this.GeoPoint, $marker.html(), iconType, this.$address, this.zoom);

        existing_markers.push(gmarker);
        this.markerIndex = existing_markers.length - 1;


		var me = this;
		var panel = $marker.find(".panel").get(0);
		// add hover and click events to both the address and the marker
		this.$address
			.hover(function(event) {
				//GEvent.trigger(gmarker, "mouseover");
                me.$address.addClass("hover");

            }, function() {
				//GEvent.trigger(gmarker, "mouseout");
                me.$address.removeClass("hover");
            })
			.bind("click", { merchant: this.name}, function(event) {
				// trigger custom analytics, but only if this item was not already selected
				if (!me.$address.is(".selected")) { VISA.Analytics.event(event); }
			})
			.click(function(event) {
                GEvent.trigger(gmarker, "click");
                if ($(event.target).not("a").length) { // ignore clicks on links, e.g. 'driving directions'
					$("#results .selected").removeClass("selected"); // clear previous selections
					me.$address.addClass("selected");
				} else { // link item, trigger link analytics
					VISA.Analytics.navigation(event);
				}
			});
		
		$("#addresses").append(this.$address);
	}
	
	Store.prototype.isDrawn = function() {
		return (this.$address != null);
	}
	
	Store.prototype.show = function() {
		//if(!all_drawn) return;
        this.$address.show();
        if(existing_markers.length > this.markerIndex ){
            existing_markers[this.markerIndex].hideFlag = false;
            existing_markers[this.markerIndex].show();
        }
	}
	
	Store.prototype.hide = function() {
		//if(!all_drawn) return;
        this.$address.hide();
        if(existing_markers.length > this.markerIndex ){
            existing_markers[this.markerIndex].hideFlag = true;
            existing_markers[this.markerIndex].hide();
        }
	}
	
})();

