/*
	=====================
	= Utility Functions =
	=====================
*/
// Removes all non-word characters and underscores from a string.
String.prototype.removeNonAlphanumeric = function () {
	return this.toString().replace('_','').replace(/\W/g,'');
}

// Makes a string camelCase
String.prototype.toCamelCase = function () {
	return this.toString().replace(/([A-Z]+)/g, function (m, s) {
		return s.substr(0,1).toUpperCase() + s.toLowerCase().substr(1,s.length);
	}).replace(/[\-_\s](.)/g, function (m, s) {
		return s.toUpperCase();
	});
}

// Makes a string "Omniture friendly".  That is, in the format:
// HIS:ThisIsAn:OmnitureFriendly:String
String.prototype.omniturize = function () {
	return this.toString().toCamelCase().removeNonAlphanumeric();
}

// Used in schedule pages to get a two week range from a given date object.
HISTORY.getTwoWeekRange = function (date) {
	var two_weeks, time, min_max;
	two_weeks = 14 * 24 * 60 * 60 * 1000; // Two weeks in milliseconds.
	time = date.getTime();
	min_max = [
		new Date(), // Minimum date
		new Date()  // Maximum date
	];
	min_max[0].setTime(time - two_weeks);
	min_max[1].setTime(time + two_weeks);
	return min_max;
}

// Function that takes two strings as arguments, formats them to be
// Omniture-friendly, and makes two Omniture calls with them.
HISTORY.trackClick = function (a, b) {
	var i, a_array, b_array;
	a_array = a.split(':');
	b_array = b.split(':');
	a = a_array[0]; // Don't modify first element
	b = b_array[0]; // Don't modify first element
	for (i = 1; i < a_array.length; i++) {
		a = a + ':' + a_array[i].omniturize(); // Don't modify first element
	}
	for (i = 1; i < b_array.length; i++) {
		b = b + ':' + b_array[i].omniturize(); // Don't modify first element
	}
	s.tl(this, 'o', a);
	s.tl(this, 'o', b);
}

// Function that takes two strings as arguments, formats them to be
// Omniture-friendly, and makes a single Omniture call with them.
HISTORY.trackClickSingle = function (a) {
	var i, a_array;
	a_array = a.split(':');
	a = a_array[0]; // Don't modify first element
	for (i = 1; i < a_array.length; i++) {
		a = a + ':' + a_array[i].omniturize(); // Don't modify first element
	}
	s.tl(this, 'o', a);
}

// Omniture function which gets bound to the click event for certain
// links that need to be tracked.
HISTORY.linkCode = function (event) {
	if (typeof s_gi != 'undefined') {
		var s = s_gi(s_account);
		s.linkTrackVars = 'events';
		s.linkTrackEvents = event;
		s.events = event;
		s.tl(this, 'o', ' ');
	}
}

// Sends custom 'social networking' events to omniture for gigya bar the various clicks
HISTORY.trackGigyaShareBarClick = function (eventObj) {

        var context = eventObj.context.toString();
		var provider = eventObj.providers.toString();

		var eventsStr = "";

        if(context == 'gigya-bar-top') {
            eventsStr += "event82,";
        } else {
            if(context == 'gigya-bar'){
                eventsStr += "event80,";
            } else {
                eventsStr += "event81,";
            }
        }
        if(provider == 'facebookLike' || provider == 'facebook-like') { // 'facebookLike' is deprecated, remove that check later
            eventsStr += "event67";
        } else {
            if (provider == 'facebook-send') {
                eventsStr += "event68";
            } else {
                if (provider == 'google-plusOne'){
                    eventsStr += "event69";
                } else {
                    if (provider == 'twitter') {
                        eventsStr += "event70";
                    } else {
                        if (provider == 'stumbleupon') {
                             eventsStr += "event71";
                        } else {
                            eventsStr += "event2";
                        }
                    }
                }
            }
        }
        if (s != 'undefined') {
            //alert("s is defined!");
            s.events = eventsStr;
            s.linkTrackEvents = eventsStr;
            s.linkTrackVars ='events';
            s.tl(true,'o','Gigya Share Bar Click');
        } else {
            if((typeof s_gi != 'undefined') && (typeof s_account != 'undefined')) {
                var s_ad_hoc = s_gi(s_account);
                //alert("had to make s_ad_hoc");
                s_ad_hoc.events = eventsStr;
                s_ad_hoc.linkTrackEvents = eventsStr;
                s_ad_hoc.linkTrackVars ='events';
                s_ad_hoc.tl(true,'o','Gigya Share Bar Click');
            }
        }
}

// Given an argument in seconds, creates a string in the basic "hh:mm:ss"
// format, but applies some logic to including leading zeros and so on.
HISTORY.secondsToHms = function (d) {
	var h, m, s;
	d = Number(d);
	h = Math.floor(d / 3600);
	m = Math.floor(d % 3600 / 60);
	s = Math.floor(d % 3600 % 60);
	return ((h > 0 ? h + ":" : "") + (m > 0 ? (h > 0 && m < 10 ? "0" : "") + m + ":" : "0:") + (s < 10 ? "0" : "") + s);
}

// Wrapper around console.log so browsers with no console don't throw errors.
HISTORY.log = function (s) {
    if (!window.console)
        console = {log: function() {}};

	if (typeof console === "object") {
		console.log(s);
	}
}

/*
	===========
	= Cookies =
	===========
*/
HISTORY.cookies = {
	timeoutDays : 30, // Duration of the cookie in days.

	// Cookie setter.
	set : function (name, value) {
		var expirationDate = new Date();
		expirationDate.setDate(expirationDate.getDate() + this.timeoutDays);
		document.cookie = name + "=" + escape(value) + ";expires=" + expirationDate.toGMTString();
	},

	// Cookie getter.
	get : function (name) {
		var start, end;
		if (document.cookie.length > 0) {
			start = document.cookie.indexOf(name + "=");
			if (start != -1) {
				start = start + name.length + 1;
				end = document.cookie.indexOf(";",start);
				if (end == -1) {
					end = document.cookie.length;
				}
				return unescape(document.cookie.substring(start,end));
			}
		}
		return false;
	},

    setTimeOutDays : function (days) {
        this.timeoutDays = days;
    }
};

/*
	==================
	= jQuery Plugins =
	==================
	Make sure $ is protected.
*/
(function($){
	/*
		labelHide
		---------
		Loops through a result set and for each result, takes the value of any
		associated label, applies it as the value of the result, and hides the label.
	*/
	$.fn.labelHide = function (value) {
		this.each(function () {

			var obj, id, label;
			obj = $(this);
			id = obj.attr("id");
			label = $("label[for='"+id+"']");

			if (id.length > 0 && label.length > 0) {
				if (value) {
					obj.val(label.text());
				}
				label.hide();
			}
		});
		return this;
	}

	/*
		Clear Defaults
		--------------
		This function loops through a result set and for each result,
		it clears the default value onfocus and restores the default
		if the value is empty onblur.
	*/
	$.fn.clearDefault = function (str_default) {
		return this.each(function () {

			var obj = $(this),
				obj_val = obj.val();

			if (obj_val.length === 0) {

				obj.val(str_default);

				obj.focus(function () {
					if (obj.val() == str_default) {
						obj.val("");
					}
				});

				obj.blur(function () {
					if (obj.val() == "") {
						obj.val(str_default);
					}
				});
			}
		});
	}

	/*
		Submit Replace
		--------------
		When applied to a form, this plugin will find any submit
		button and replace it with an anchor.
	*/
	$.fn.submitReplace = function (klass) {
		 this.each(function () {
		 	var form, btn;
			form = $(this);
			btn  = form.find(':submit');

			btn.hide().after('<a href="#">'+btn.val()+'</a>');

			if (klass.length) {
				btn.next().addClass(klass);
			}

			btn.next().click(function (e) {
				e.preventDefault();
				form.submit();
			});

		});
		return this;
	}

	/*
		Match Columns
		-------------
		This function loops through a result set and for each result,
		it matches the height of the longest result.
	*/
	$.fn.matchColumns = function () {
		var height_tar = 0;

		this.each(function () {
			height_obj = $(this).outerHeight();
			height_tar = Math.max(height_tar, height_obj);
		});

		this.each(function () {
			var pad_top = parseInt($(this).css("padding-top"));
			var pad_bot = parseInt($(this).css("padding-bottom"));
			var bor_top = parseInt($(this).css("border-top-width"));
			var bor_bot = parseInt($(this).css("border-bottom-width"));

			var offset = pad_top + pad_bot + bor_top + bor_bot;

			// fix for ie6
			if ($.browser.msie && $.browser.version == 6) {
				$(this).css({"height": (height_tar - offset) + "px"});
			}
			else {
				$(this).css({"min-height": (height_tar - offset) + "px"});
			}
		});
		return this;
	}

	/*
		Alternate
		---------
		Iterates through a set of given objects and applies 'odd' or 'even'
		class to each element
	*/
	$.fn.alternate = function () {
		var i = 0;
		this.each(function () {
			(i % 2 == 0) ? $(this).addClass('odd') : $(this).addClass('even');
			i++;
		});
		return this;
	}

	/*
		Font Resizer
		------------
	*/
	$.fn.fontResizer = function () {
		return this.each(function () {
			var fontSizeSet = false;
			var resizerCookie = HISTORY.cookies.get('resizer');

			// Validate cookied value against array...
			for (var i = 0; i < HISTORY.font_sizes.length; i++) {
				if (HISTORY.font_sizes[i] == resizerCookie) {
					HISTORY.body.addClass(resizerCookie);
					fontSizeSet = true;
				}
			}

			if (!fontSizeSet) {
				HISTORY.body.addClass(HISTORY.font_sizes[0]);
			}

			$(this).click(function (e) {
				e.preventDefault();
				for (var i = 0; i < HISTORY.font_sizes.length; i++) {
					if (HISTORY.body.hasClass(HISTORY.font_sizes[i])) {
						var next = (i + 1 > HISTORY.font_sizes.length - 1) ? 0 : i + 1;
						HISTORY.body.removeClass(HISTORY.font_sizes[i]).addClass(HISTORY.font_sizes[next]);
						HISTORY.cookies.set('resizer',HISTORY.font_sizes[next]);
						break;
					}
				}
			});
		});
	}

	/*
		Switchers
		---------
	*/
	$.fn.switchers = function () {
		return this.each(function () {
			var link_a, link_b, list_a, list_b;

			link_a = $('.category-head p a:eq(0)',this);
			link_b = $('.category-head p a:eq(1)',this);
			list_a = $('ul:eq(0)',this);
			list_b = $('ul:eq(1)',this);

			link_a.addClass('selected');
			list_b.hide();

			link_a.click(function (e) {

				e.preventDefault();

				list_b.fadeOut('fast', function () {
					link_b.removeClass('selected');

					list_a.fadeIn('fast', function () {
						link_a.addClass('selected');
					});
				});

			});

			link_b.click(function (e) {

				e.preventDefault();
				link_a.removeClass('selected');

				list_a.fadeOut('fast',function () {
					link_a.removeClass('selected');

					list_b.fadeIn('fast',function () {
						link_b.addClass('selected');
					});
				});

			});
		});
	}

	/*
		UL Select List
		--------------
		This function loops through a result set and for each result,
		creates a fake element similar to a select box.  Only applies
		to <ul>s with links in the <li>s.
	*/
	$.fn.ulSelectList = function () {
		this.each(function () {

			if ($.browser.msie && $.browser.version < 8) { // IE6/7 get a select box instead of the fancy fake dropdown.
				var obj, select;

				obj = $(this);
				obj.hide().after('<select></select>');
				select = obj.next();

				// Make copies of the links inside the new select element.
				$('a',obj).each(function () {
					obj = $(this);
					if (obj.parent().hasClass('selected')) {
						select.append('<option selected="selected" value="selected">'+obj.text()+'</option>');
					}
					else {
						select.append('<option value="'+obj.attr('href')+'">'+obj.text()+'</option>');
					}
				});

				// On change, the select options redirect the user as if they
				// had clicked a link in the fake select.
				select.change(function () {
					if ($(this).val() != 'selected') {
						window.location = $(this).val();
					}
				});
			} else {

				// Initial setup of the fake select.
				var ul = $(this);
				ul.wrap('<div class="fake-select inactive"></div>');
				var div = ul.parent();
				div.append('<a class="trigger" href="#"></a>');
				$('li.selected',ul).siblings().hide();

				// The trigger toggles the reveal/collapse functions.
				$('a.trigger',div).click(function (e) {
					e.preventDefault();
					if (div.hasClass('inactive')) {
						reveal();
					}
					else {
						collapse();
					}
				});

				// When you click on the selected item, which is hard-coded
				// into the template, do not do anything - simply collapse
				// the fake select box.
				$('li.selected a',ul).click(function (e) {
					e.preventDefault();
					if (div.hasClass('inactive')) {
						reveal();
					}
					else {
						collapse();
					}
				});

				// Set a timer so that when you mouseout of the fake select,
				// it will wait 2 seconds and then collapse itself.
				var timer = false;
				div.hover(function () {
					if (timer) {
						clearTimeout(timer);
					}
				},function () {
					if (div.hasClass('active'))	{
						timer = setTimeout(collapse,1000);
					}
				});

				// Reveals the fake select options.
				function reveal() {
					div.removeClass('inactive').addClass('active');
					$('li',ul).slideDown(100);
				}

				// Collapses the fake select options.
				function collapse() {
					div.removeClass('active').addClass('inactive');
					$('li:not(.selected)',ul).slideUp(100);
				}
			} // else
		}); // each
		return this;
	}

	/*
		Browser offset fix
		------------------
		Intended to fix background centering issue. On browser resize, detects for odd number
		pixels (most browsers). If so, applies css offset for the given property.
	*/
	$.fn.browserOffsetFix = function (property, offset) {
		var obj, ver, ie6, ie7, ff3, saf4, prop_val;
		obj  = $(this);
		ver  = $.browser.version;
		ie6  = ($.browser.msie && ver < 7);
		ie7  = ($.browser.msie && ver == 7);
		ff3  = ($.browser.mozilla && ver.split('.')[2] == 0);
		saf4 = ($.browser.safari && ver.split('.')[0] >= 528);
		prop_val = Number(obj.css(property).replace('px',''));

		// init fix on browser load
		propertyFix();

		// fix on resize
		$(window).resize(propertyFix);

		function propertyFix() {
			// Determine if the viewport has an odd width.
			var odd_width = $(window).width() % 2 ? true : false;
			// Add the offset to the given property in these cases.
			if ((ie6 && odd_width) || (ie7 && odd_width) || (saf4 && odd_width)) {
				obj.css(property, prop_val + offset + "px");
			}
			// Subtract the offset from the given property in these cases.
			else if (ff3 && odd_width) {
				obj.css(property, prop_val - offset + "px");
			}
			// Otherwise, restore original value.
			else {
				obj.css(property, prop_val + "px");
			}
		} // propertyFix()
	} // browserOffsetFix()

	/*
		Open New Modular Windows
		------------------------
	*/
	$.fn.newWindow = function (width, height, scrollbars, name) {
		this.each(function () {
			name   = (name == null) ? "main" : name;
			width  = (width == null) ? "490" : width;
			height = (height == null) ? "600" : height;
			scrollbars = (scrollbars == null) ? 0 : scrollbars;

			$(this).click(function (e) {
				e.preventDefault();
				window.open($(this).attr('href'), name, 'width=' + width + ',height=' + height + ',scrollbars=' + scrollbars + ',resizeable=1,menubar=0');
			});
		});
		return this;
	}

})(jQuery);

/*
	==================
	= Document Ready =
	==================
*/
jQuery(function($){

    HISTORY.body = $('body');

	// Makes sure new-window links open in new windows.
	$('a.new-window').live('click', function(e) {
		if (e.button === 0) { // Left button.
			e.preventDefault();
			window.open(this.href);
		}
	});

	// Bind click events to "Share This" links for Omniture tracking.
	$('span.at15t').live('click', function(e){
		if (e.button === 0) { // Left button.
			HISTORY.linkCode('event2');  //changed to event2 for shared virally on 2/17/11
		}
	});

	$('#search-form input.label-hide').labelHide(false);
	$('#content input.label-hide').labelHide(true);
	$('#search-field').clearDefault('Search');

	$('div.media-wrap > div.viewer, div.media-wrap > div.controller').matchColumns();

	$('ul.content-controls a.font-sizer').fontResizer();
	$('ul.content-controls a.cite-this').clickModals(445);
	$('a.newsletter-signup-link, a.contact-link').newWindow(600,500,1);
	$('.mod.switcher').switchers();

	$('ul.simple-thumb').each(function () {
		$('li',this).alternate();
	});

	// Functionality specific to "search" pages.
	if (HISTORY.body.hasClass('search')) {
		$('div.content-header > div.results > ul').ulSelectList();
	}

	// Functionality specific to "generic" pages (landing, text, etc).
	if (HISTORY.body.hasClass('generic')) {
		$('ul.simple-thumb li a, ul.bull-red li a').hoverModals(290);
		$('#generic-text .nav-generic a').each(function () {
			//if (!window.location.toString().indexOf(this.href)) {
            if (window.location.toString()== this.href) {
				$(this).parent().addClass('selected');
			}
		});
	}

	// Apply auto-complete behavior to search fields globally.
	$('form input[name="search-field"]').each(function () {
		var obj = $(this);
		obj.autocomplete(HISTORY.context_path + '/search/ajax', {
			extraParams : {
				'search-field' : function () {
					return obj.val();
				}
			},
			scroll      : false,
			selectFirst : false,
			width       : (obj.attr('id') == 'keywords') ? 245 : 203
		});
	});

});
