	// marker icons
		var icon = new Array();
		var icon_size = new google.maps.Size(28, 36);
		icon['shopping'] = new google.maps.MarkerImage("http://www.couponhq.com/i/targets.gif", icon_size, new google.maps.Point(0,0));
		icon['beauty'] = new google.maps.MarkerImage("http://www.couponhq.com/i/targets.gif", icon_size, new google.maps.Point(33,0));
		icon['food'] = new google.maps.MarkerImage("http://www.couponhq.com/i/targets.gif", icon_size, new google.maps.Point(69,0));
		icon['travel'] = new google.maps.MarkerImage("http://www.couponhq.com/i/targets.gif", icon_size, new google.maps.Point(102,0));	
	
		icon['events'] = new google.maps.MarkerImage("http://www.couponhq.com/i/targets.gif", icon_size, new google.maps.Point(135,0));		
		icon['pets'] = new google.maps.MarkerImage("http://www.couponhq.com/i/targets.gif", icon_size, new google.maps.Point(175,0));
		icon['activity'] = new google.maps.MarkerImage("http://www.couponhq.com/i/targets.gif", icon_size, new google.maps.Point(205,0));
		icon['auto'] = new google.maps.MarkerImage("http://www.couponhq.com/i/targets.gif", icon_size, new google.maps.Point(241,0));

		icon['services'] = new google.maps.MarkerImage("http://www.couponhq.com/i/targets.gif", icon_size, new google.maps.Point(275,0));
		icon['classes'] = new google.maps.MarkerImage("http://www.couponhq.com/i/targets.gif", icon_size, new google.maps.Point(310,0));
		icon['hotel'] = new google.maps.MarkerImage("http://www.couponhq.com/i/targets.gif", icon_size, new google.maps.Point(343,0));		
		icon['other'] = new google.maps.MarkerImage("http://www.couponhq.com/i/targets.gif", icon_size, new google.maps.Point(375,0));
		icon['subscriptions'] = new google.maps.MarkerImage("http://www.couponhq.com/i/targets.gif", icon_size, new google.maps.Point(375,0));
		icon[''] = new google.maps.MarkerImage("http://www.couponhq.com/i/targets.gif", icon_size, new google.maps.Point(375,0));
		

		function addZoomListener(){
			google.maps.event.addListener(map, 'zoom_changed', updateMarkersAndResults);
		}

		function updateMarkersAndResults(){
				n_lat=map.getCenter().lat();
				n_lng=map.getCenter().lng();

				var bounds = map.getBounds();
				ne_lat = bounds.getNorthEast().lat();
				ne_lng = bounds.getNorthEast().lng();
				sw_lat = bounds.getSouthWest().lat();
				sw_lng = bounds.getSouthWest().lng();

				// we only call if we are OUT of bounds from previous search.
				// that is to say, only when any of the corners exceed the currentMaxBounds
				if (!max_bounds.contains(bounds.getNorthEast()) || !max_bounds.contains(bounds.getSouthWest())){
					max_bounds.extend(bounds.getNorthEast()); // now we extend it
					max_bounds.extend(bounds.getSouthWest()); // 

					$('#loading').show('slow');
					$.get('/deals.cgi?op=u&ne_lat='+ne_lat+'&ne_lng='+ne_lng+'&sw_lat='+sw_lat+'&sw_lng='+sw_lng, function(data){ 
						eval (data); 
						setMarkers(map, deals, 1);
						updateCategoryList();
						$('#loading').hide('slow');
						updateNearbyCityList(nearby_cities);
						showOnlyMarkers(current_category);		
						$('#location_nav').show();$('#location_free').hide();
					} );
				}

				// update the values for the email subscription form as well
				$('#lat').val(map.getCenter().lat());
				$('#lng').val(map.getCenter().lng());
				$('#ne_lat').val(bounds.getNorthEast().lat());
				$('#ne_lng').val(bounds.getNorthEast().lng());
				$('#sw_lat').val(bounds.getSouthWest().lat());
				$('#sw_lng').val(bounds.getSouthWest().lng());
				$('#subs_zoom').val(map.getZoom());

				
		}
		function updateNearbyCityList(nearby){
			var location_nav_html = '';
			for (var i = 0; i < nearby.length; i++) {
				var city = nearby[i];		
				location_nav_html+= '<li><a href="/'+city[0]+'" onclick="codeAddress(\''+city[1]+ '.' + city[2] + '\'); return false;">'+city[1]+'</a> </li>';
			}	
			$('div#location_nav').html('<ul>' + location_nav_html + '</ul>');

		}
		function updateCategoryList(){

		// for all the markers visible, what are their categories?
				// do not show anything that is not visible. 
				// first we remove every single category. Yes, this should really be a diff job.. but
			$('.category_selection').hide();
			$('#sel_all').show();   // this is always shown though.

			// result box controls. maybe a little too much though. IN production, switch this off
			$('.offer').hide();	// 1st make all invisible.			

			var bounds = map.getBounds();
			var category_count = new Array();

			for(var key in marker_dict){
				if ( bounds.contains(marker_dict[key].getPosition()) ){

						var cat_set = marker_dict[key].mycategory.split(", "); // some have multiple categories
						var cat_list = "";
						// count the number of offers per category
						for(var i in cat_set){
							if(category_count[cat_set[i]]){ 
								category_count[cat_set[i]] += 1;
							}else{ category_count[cat_set[i]] = 1;} 
							cat_list += cat_set[i] + ' ';
						}
						
						var offer = marker_dict[key];
						// result box control
						// must be in bounds AND in category. Then we show
						if (offer.mycategory.indexOf(current_category) != -1 || current_category=='all'){
							$('#did_'+offer.deal_id).show();
						}
				}
			}	
			
			// update the html for the counts
			for(var key in category_count){
				$('#count_'+key).html(category_count[key]);  // update the # of items in the category 
				$('#sel_'+key).show();	// show the categories selectors that need to be shown
			}			
			
		}

		// shows only the category specified
		function showOnlyMarkers(category){

			current_category = category;			// update global current category
			// deal results boxes control
			// 1st make all invisible
			$('.offer').hide();			
			for(var key in marker_dict){
				// marker control
				if (marker_dict[key].mycategory.indexOf(category) != -1){
					marker_dict[key].setVisible(true);
					// result box control
					if ( map && map.getBounds() && map.getBounds().contains(marker_dict[key].getPosition()) ){
						$('#did_'+marker_dict[key].deal_id).show();
					}					
				}else{
					marker_dict[key].setVisible(false);
				}
			}	
			
			// category list contols

//			$('.category_selection').css('background-color', '#ffffff'); 	// whiten all categories
//			$('.category_selection').hover(.css('background-color', '#ccc'); 	
			$('#sel_'+category).addClass('selectedcat');		// set the targeted one				
		}
						
		function setMarkers(map, locations, nofit, firstcall) {
			var new_results = "";
			nofit = 1;//we are not ever going to fit..
			var bounds = new google.maps.LatLngBounds();
			for (var i = 0; i < locations.length; i++) {
				var place = locations[i];
			
			
				// we only add new markers IF it does not already exist
				// essentially overloading our marker dict reference holder 
				// to handle a simple presense test
				if (marker_dict[place[3] + '-' + place[4]] ){ continue; }

				
				var  percent_saving_formatted = '';
				if (place[8] > 0){
					percent_saving_formatted = Math.round( (place[8] - place[7])/place[8]*100 );
					percent_saving_formatted += '%';
				}
				var myLatLng = new google.maps.LatLng(place[3], place[4]);
				var marker = new google.maps.Marker({
					position: myLatLng,
					map: map,
					mycategory: "all, " + place[2],
					category: place[2],
					title: place[5],
					link: '/d/'+place[0],
					image_url: '/img/'+place[0]+'.png',
					price: place[7],
					original_price: place[8],
					currency: place[6],

					percent_saving: percent_saving_formatted,
					
					site: place[1],
					deal_id: place[0], 
					icon: icon[place[2]]			
				});				

				if (map){
					google.maps.event.addListener(marker, "click", function(){
						infowindow.setContent("<div style='width: 210px'>" + this.title + "<br><a href='" + this.link + "'>More Details</a></div>" );
						infowindow.open(map, this);
					});

					marker_dict[place[3] + '-' + place[4]] = marker;  // put marker ref into our dictionary
			
					// figure out our bounds for this set of markers
					bounds.extend(myLatLng);
				}
	
				// we add into the html of the page all the deals. 
				var offer = marker;
				new_results += '<div id="did_'+offer.deal_id+'" class="offer all '+ offer.mycategory +' "><div class=offer_inner><a href="'+ offer.link +'"><div class="image"><img src="'+offer.image_url+'"></div></a><div class=desc><a href="'+ offer.link +'">'+offer.title+'</a> <span class="buyaction"><a href="'+offer.link+'">by '+offer.site+'</a></span></div>'+
				'<a  class="icon1" id="c_'+offer.category+'" href="'+ offer.link +'">&nbsp;</a><strike><strong>'+ offer.currency +' '+offer.original_price+'</strong></strike> - '+offer.percent_saving+' <br><span class=offer_price>'+ offer.currency +' '+offer.price+'</span></div></div>';
				
			}
			$('#results').append(new_results);
			if(!map){return;}
			
			// we only fit when requested. A reload based on zoom changes or drags does not need fitting
			if (!nofit){
				map.fitBounds(bounds);
			}
			// ensure we do not have too small a viewport
			if (bounds.getNorthEast().equals(bounds.getSouthWest())) {
				var extendPoint1 = new google.maps.LatLng(bounds.getNorthEast().lat() + 0.01, bounds.getNorthEast().lng() + 0.01);
				var extendPoint2 = new google.maps.LatLng(bounds.getNorthEast().lat() - 0.01, bounds.getNorthEast().lng() - 0.01);
				bounds.extend(extendPoint1);
				bounds.extend(extendPoint2);
				//map.fitBounds(bounds);
			}
			if (!firstcall){
				showOnlyMarkers(current_category);
			}

		}
		

		
		
	// if user enters a specific address.
	function codeAddress(direct_address) {

		var address = direct_address || document.getElementById("address").value;
//		if (!direct_address) { $('#location_nav').toggle();$('#location_free').toggle(); }
//		if (!direct_address) { $('#location_free').toggle(); }		
		if(!geocoder){			geocoder = new google.maps.Geocoder();}
		geocoder.geocode( { 'address': address}, function(results, status) {
		  if (status == google.maps.GeocoderStatus.OK) {
			// rename the current title
			$('span#current_location').html(results[0].formatted_address);

			// we have the lat lng
			lat = results[0].geometry.location.lat();
			lng = results[0].geometry.location.lng();
			
			document.title = results[0].formatted_address;
			// note: for now, only the map interface uses this
			// the other list & grid just does a url

//			if(map){

				// reset the map to new location
				map.setCenter(results[0].geometry.location);
				var bounds = map.getBounds();
				updateMarkersAndResults();
				// update the email subscription form as well
				$('#lat').val(map.getCenter().lat());
				$('#lng').val(map.getCenter().lng());
				$('#ne_lat').val(bounds.getNorthEast().lat());
				$('#ne_lng').val(bounds.getNorthEast().lng());
				$('#sw_lat').val(bounds.getSouthWest().lat());
				$('#sw_lng').val(bounds.getSouthWest().lng());
				$('#subs_zoom').val(map.getZoom());
				$('#subs_location').val(address);	

//			}else{
				// no map (e.g. this is a 
//				$('#lat').val(lat);
//				$('#lng').val(lng);
//			}
			// update the loc cookie
			setCookie('loc', results[0].formatted_address + '|||' + lat + '|' + lng, 365);
				
		  } else {
				alert("Geocode was not successful for the following reason: " + status);
			}
		});
	}
		// UTILITY FUNCTIONS
		function setCookie(name,value,days) {
			if (days) {
				var date = new Date();
				date.setTime(date.getTime()+(days*24*60*60*1000));
				var expires = "; expires="+date.toGMTString();
			}
			else var expires = "";
			document.cookie = name+"="+value+expires+"; path=/";
		}

		function getCookie (name) {    
		var dcookie = document.cookie; 
		var cname = name + "=";    
		var clen = dcookie.length;    
		var cbegin = 0;
				while (cbegin < clen) {        
				var vbegin = cbegin + cname.length;
					if (dcookie.substring(cbegin, vbegin) == cname) { 
					var vend = dcookie.indexOf (";", vbegin);
						if (vend == -1) vend = clen;
						return unescape(dcookie.substring(vbegin, vend));
					 }
				cbegin = dcookie.indexOf(" ", cbegin) + 1;
				if (cbegin == 0) break;        
				}    
		return null;    
		}		
		
		
		$(document).ready(function()
		{
			$(".defaultText").focus(function(srcc)
			{
				if ($(this).val() == $(this)[0].title)
				{
					$(this).removeClass("defaultTextActive");
					$(this).val("");
				}
			});
			
			$(".defaultText").blur(function()
			{
				if ($(this).val() == "")
				{
					$(this).addClass("defaultTextActive");
					$(this).val($(this)[0].title);
				}
			});
			
			$(".defaultText").blur();        
		});
		
		
	
		
		
		
		
		
		
		
		
		
		
		
