/*
    Dependency:
        /js/lib/jquery-1.6.4.min.js
        /js/lib/jquery.cookie.js
        /js/lib/jquery.stickyPanel.min.js
 */

/******************************************************************
 * NAMESPACE: B2
 * Namespace for Bundle 2.0 web application.
 ******************************************************************/
if (typeof B2 == "undefined") {
	var B2 = {};
}


/******************************************************************
 * NAMESPACE: B2.Core
 * Container for core state/behavior that is global to Bundle 2.0.
 * The init() method will be invoked on each page.
 ******************************************************************/
B2.Core = function() {
	return {
		/******************************************************************
		 * Encapsulates present user data.
		 ******************************************************************/
		User: function() {
			// constants
			var COOKIE_GREETING_NAME = "GreetingName";
			var COOKIE_ANCHOR_CITY_NAME = "AnchorCityName";
			var COOKIE_ANCHOR_CITY_SLUG = "AnchorCitySlug";
			var COOKIE_ANCHOR_ZIP = "AnchorZip";
			// sentinel -- only request anchor city once
			var ANCHOR_SETTING_ACTIVE = false;

			return {
				getGreetingName: function() {
					var name = $.cookie(COOKIE_GREETING_NAME);
					if (name=="undefined") {
						name = null;
					}
					return name;
				},
				setGreetingName: function(name) {
					// NOTE: don't do this! greeting name cookie should only be set by bundle.net upon login
					// $.cookie("GreetingName", name);
				},
				// helper function that assigns location and refreshes ui
				_updateLocation: function(slug, name) {
					B2.Core.User.setAnchorCity(name, slug);
					B2.Core.updateCityContext();
					B2.Core.User.ANCHOR_SETTING_ACTIVE = false;
				},
				getAnchorCity: function() {
					if ($.cookie(COOKIE_ANCHOR_CITY_NAME) && $.cookie(COOKIE_ANCHOR_CITY_SLUG)) {
						return {
							name: $.cookie(COOKIE_ANCHOR_CITY_NAME),
							slug: $.cookie(COOKIE_ANCHOR_CITY_SLUG)
						}
					}
					else {
						if (!ANCHOR_SETTING_ACTIVE) {
							// sentinel
							ANCHOR_SETTING_ACTIVE = true;

							// callback for ajax inner method call
							postalCodeCallback = function(postalCode) {
								// from postal code retrieved by ip, re-update the location context
								$.cookie(COOKIE_ANCHOR_ZIP, postalCode, { path:'/' });
								// attempt to locate closest city, first attempt local server callback
								B2.Tracking.trackEvent('global', 'LocationAnchorAuto', 'Request', true)
								$.ajax({
									url: "/services/location-search/",
									type: "POST",
									data: {"location": postalCode},
									timeout: 1500,
									success: function(response) {
										if (response.length > 0) {
											slug = response[0]['slug'];
											name = response[0]['name'];
											B2.Core.User._updateLocation(slug, name);
										} else {
											B2.Core.User._updateLocation(postalCode, postalCode)
										}
									},
									error: function (response, status, error) {
										B2.Tracking.trackEvent('global', 'LocationAnchorAuto', 'ResponseServer' + status, true)
										// check if zip is in top kilo
										$.ajax({
											url: "/assets/js/src/geolocation/zip-city-kilo.json",
											dataType: 'json',
											success: function(data) {
												city_id = data['zipCityId'][postalCode];
												if (typeof(city_id) != "undefined") {
													city = data['cityIdDetail'][city_id]
													if (typeof(city) != "undefined") {
														B2.Core.User._updateLocation(city[0], city[1]);
														return true;
													}
												}
												B2.Core.User._updateLocation(postalCode, postalCode);
											},
											error: function(response, status, error) {
												B2.Core.User._updateLocation(postalCode, postalCode);
											}
										});
									}
								});
							}
							// async request for ip based anchor city if available. set name, slug to zip code
							B2.GeoLocation.IpService.requestPostalCode(postalCodeCallback);
						}
						return null;
					}
				},
				setAnchorCity: function(name, slug) {
					$.cookie(COOKIE_ANCHOR_CITY_NAME, name, { path:'/' });
					$.cookie(COOKIE_ANCHOR_CITY_SLUG, slug, { path:'/' });
				},

				isLoggedIn: function() {
					// NOTE: not really checking whether the user is logged in
					return (this.getGreetingName() != null);
				}
			}
		}(),

		Util: {
			/** 
			 *   jqInput - jQuery Object, eg: $("#fooBar")
			 *   defaultText - Prefill string or null/false if value="abc" param is already filled
			 *   fadedClass - css class name for prefilled text.  Use null/false if none
			 */
			buildDefaultPrefill: function(jqInput, defaultText, fadedClass) {
				if (!defaultText)
					defaultText = jqInput.val();
				if (jqInput.val() == "") {
					if (fadedClass)
						jqInput.addClass(fadedClass);
					jqInput.val(defaultText);
				}
				jqInput.focus(function(){
					if ($(this).val() == defaultText) {
						$(this).val("");
						if (fadedClass)
							$(this).removeClass(fadedClass);
					}
				});
				jqInput.blur(function(){
					if ($(this).val() == "") {
						if (fadedClass)
							$(this).addClass(fadedClass);
						$(this).val(defaultText);
					}
				});
				return;
			}
		},

		init: function() {
			this.updateGreetingBar();
			var anchorCity = this.updateCityContext();
			this.updateMsnBar();
			$("#location-show-more, #location-change").click(function(e) {
				e.preventDefault();
				$("#location-more").slideToggle();
			});
			
			$("#location-search-form").submit(function(e) {
				B2.Tracking.trackEvent('global', 'LocationAnchorManual', 'Search', true)
				e.preventDefault();
				var loca = "";
				loca = $("#id_location").attr("value");
				// provide visual feedback to user
				$("#location-status").html("Searching locations...");
				$("#location-status").hide().fadeIn("fast");

				// post request to /location-search/ handler
				$.ajax({
					url: "/services/location-search/",
					type: "POST",
					data: {"location": loca},
					success: function(response) {
						if (response.length > 0) {
							slug = response[0]['slug'];
							name = response[0]['name'];
							zip = response[0]['zip'];
							B2.Core.User.setAnchorCity(name, slug);
							B2.Core.updateCityContext();
							if (typeof(zip) != "undefined") {
								$.cookie(B2.Core.User.COOKIE_ANCHOR_ZIP, zip, { path:'/' });
							}
							$("#location-status").hide("fast")
							$("#location-more").slideToggle("slow");
						} else {
							$("#location-status").html("For location: <em>" + loca + "</em> &ndash; no information found, please refine your search.");
							$("#location-status").hide().fadeIn("slow");
						}
					},
					error: function (response, status) {
						B2.Tracking.trackEvent('global', 'LocationAnchorManual', 'ResponseServer'+status, true)
						$("#location-status").html("ERROR: " + response);
						$("#location-status").hide().fadeIn("fast");
					}
				});
			});

			// set global search form defaults
			this.Util.buildDefaultPrefill(
					$('#site-search input[type=text][name=q]'),
					DEFAULT_SEARCH_TERM,
					'search-prompt-text'
			);
			this.Util.buildDefaultPrefill(
					$('#site-search input[type=text][name=loc]'),
					DEFAULT_SEARCH_LOCATION,
					'search-prompt-text'
			);
			this.Util.buildDefaultPrefill(
					$('#location-search input[type=text][name=location]'),
					DEFAULT_SEARCH_LOCATION,
					'faded'
			);

			// track global events
			$('a#location-change').live('click', function(e){
				B2.Tracking.trackEvent('global', 'locations - expand from change', '');
			});
			$('a#location-show-more').live('click', function(e){
				B2.Tracking.trackEvent('global', 'locations - expand', '');
			});
			$('#location-more a').live('click', function(e){
				B2.Tracking.trackEvent('global', 'locations - city', $(this)[0].text);
			});

			// track homepage events -- TODO: move me to a homepage init() function!
			$('#site-hero a.more').live('click', function(e){
				B2.Tracking.trackEvent('homepage', 'carousel - more', $(this).attr('href'));
			});
			$('#site-hero .jcarousel-next').live('click', function(e){
				B2.Tracking.trackEvent('homepage', 'carousel - next', '');
			});
			$('#site-hero .jcarousel-prev').live('click', function(e){
				B2.Tracking.trackEvent('homepage', 'carousel - prev', '');
			});
			$('#site-search input[type=submit]').live('click', function(e){
				B2.Tracking.trackEvent('global', 'site search', $(this).siblings('input[name=q]').val());
			});
			$('.featured-list a.city-link').live('click', function(e){
				B2.Tracking.trackEvent('homepage', 'featured link', $(this)[0].text);
			});
			
			$('#site-nav-bar .center-column ul li a, #site-nav-bar a.my-city-link').click(function(e){
				B2.Tracking.trackEvent('global', 'header tab - click', ($(this)[0].text) ? $(this)[0].text : 'HOME ICON');
			});
			
			$('#left-rail ul li').not('disabled').hover(
				function(e){ $(this).addClass('hover'); }, 
				function(e){ $(this).removeClass('hover'); }
			);
			
			$('#left-rail ul li').append('<div class="anchor"></div>');
			
			$('.floater').stickyPanel({ topPadding: 5, afterDetachCSSClass: "floating", savePanelSpace: true });
		},

		// greeting bar removed from ui, commenting out
		updateGreetingBar: function() {
			if (this.User.isLoggedIn()) {
				/*
				B2.Logger.log('B2.Core.updateGreetingBar: user logged in as [' + this.User.getGreetingName() + ']');
				$("#greeting-logged-out").hide();
				var name = this.User.getGreetingName();
				if (name != null) {
					$("#greeting-member-name").text(name);
				}
				$("#greeting-logged-in").show();
				*/

				// to support legacy stuff on mm landing
				$('.loggedOut').hide();
				$('.loggedIn').show();
			}
			else {
				/*
				B2.Logger.log('B2.Core.updateGreetingBar: user NOT logged in');
				$("#greeting-logged-in").hide();
				$("#greeting-logged-out").show();
				*/

				// to support legacy stuff on mm landing
				$('.loggedIn').hide();
				$('.loggedOut').show();
			}
		},
		

		updateMsnBar: function(){
			B2.Logger.log('B2.Core.UpdateMsnBar: init');
			var msnCookie = $.cookie("fromMSN");
			var domain = document.domain.split(".");
			var referrerDomain = document.referrer;    

			domain = (domain && domain.length > 1) ? domain[domain.length-2] + "." + domain[domain.length-1] : "bundle.com";  

			var referrerIsMsn = (window.location.href.toLowerCase().indexOf("frommsn=true") > 0);
			if((referrerDomain.match("msn.com") || referrerDomain.match("msnmoney.com")) && !referrerDomain.match("rad.msn.com")) {
				referrerIsMsn = true;
			}

			if (referrerIsMsn) {
				$.cookie("fromMSN", "true", {
					domain: domain,
					secure: false,
					expires: 1,
					path: "/"
				});
			}

			if(msnCookie == "true" || referrerIsMsn) 
			{
				B2.Logger.log('B2.Core.UpdateMsnBar: referer is from MSN');
				$("<div>").load("/msgmodal/msnbar/", function() {
					$("body").addClass("msn-bar");
				}).insertBefore($("#site-wrap"));
			}
		},

		updateCityContext: function() {
			var city = this.User.getAnchorCity();
			if (city == null) { city = { name:'NEW YORK,NY', slug:'new-york-ny'}; }
			if (city != null) {
				$('#my-city-name').text(city.name);
				$('.my-city-link').attr('href','/spending/city/' + city.slug + '/');
				$('a.city-link').each(function() {
					var url = $(this).attr('href');
					url += '&loc=' + encodeURI(city.name); 
					$(this).attr('href', url);
					B2.Logger.log(url);
				});
				
				$('input[type=text].city-field').each(function() { $(this).val(city.name); });
			}
			return city;
		},

		showImageTooltip: function(element, url, width, height) {
			var tooltip = $( '#image-tooltip-wrapper' );
			tooltip.css({
				'background': 'url("' + url + '") no-repeat',
				'width': width + 'px',
				'height': height + 'px'
			});
			var offset = element.offset();
			var tx = element.width() / 2 - tooltip.width() / 2;
			tx += offset.left;
			tooltip.css( { 'left':tx + "px", "top":( offset.top - tooltip.height() ) + "px" } );
			tooltip.hide().fadeIn();
			element.mouseout( function( eventArgs ) { tooltip.hide(); } )
		},

		showTextTooltip: function(element, text) {
			var tooltip = $( '#tooltip-wrapper' );
			$( '#tooltip-body' ).html( text );
			var offset = element.offset();
			var tx = element.width() / 2 - tooltip.width() / 2;
			tx += offset.left;
			tooltip.css( { 'left':tx + "px", "top":( offset.top - tooltip.height() ) + "px" } );
			tooltip.hide().fadeIn();
			element.mouseout( function( eventArgs ) { tooltip.hide(); } )
		},

		hideTooltip: function() {
			var tooltip = $( '#tooltip-wrapper' );
			tooltip.hide();
		}
	};
}();

B2.Tracking = function(){
	trackPage = function(){
		if(_gaq){ _gaq.push(['_trackPageview']); }
	}

	trackEvent = function(event, action, label, nonInteractive){
		if(_gaq){
			if (typeof nonInteractive == 'undefined') {
				_gaq.push(['_trackEvent', event, action, label]);
			} else {
				_gaq.push(['_trackEvent', event, action, label, 0, nonInteractive]);
			}
		}
	}

	return {
		trackPage: trackPage,
		trackEvent: trackEvent
	}
}();
/******************************************************************
 * NAMESPACE: Global
 * Logger container.  can be used to log across different browsers
 ******************************************************************/
B2.Logger = {

		log: function(msg) {

			if (typeof (console) != "undefined")
			{
				if (console.log)
				{
					if (typeof (console.log) != "object")
					{
						// Firebug, Webkit Inspector
						console.log.apply(console, arguments);
					}
					else
					{
						// IE8 Developer Tools (has a built in console object)
						var len = arguments.length, i, arg, logMsg = "";

						for (i = 0; i < len; i++)
						{
							// Concat and stringify all args to formulate a single log entry						
							arg = arguments[i];

							if( arg !== undefined )
							{
								try
								{
									// Use IE8's built in JSON object to stringify	
									arg = JSON.stringify(arg)
								}
								catch (e)
								{
									arg = arg.toString();
								}
								logMsg += arg;
							}

						}
						console.log(logMsg);
					}
				}
			}
		},

		clear: function() {
			if (typeof (console) != "undefined")
			{
				if (console.clear && typeof (console.clear) != "object")
				{
					console.clear();
				}
			}
		}
}

String.format = function() {
	var s = arguments[0];
	for (var i = 0; i < arguments.length - 1; i++) {
		var reg = new RegExp("\\{" + i + "\\}", "gm");
		s = s.replace(reg, arguments[i + 1]);
	}

	return s;
}
