/// <reference path="jquery-1.4.1.min-vsdoc.js" />


// CONTENTS ====================================================================
/*
	1.0 Util
		1.1 Config
		1.2 window.log
	2.0 Frame
		2.1 Frame.Default
		2.2 Frame.Utitlity
		2.3 Frame.Background
		2.4 Frame.Content
		2.5 Frame.Flash
	3.0 Product
		3.1 Product.List
		3.2 Product.Filter
	4.0 News
		4.1 News.Filter
	5.0 Media
		5.1 Media.ColorBox
		5.2 Media.Image
		5.3 Media.Video
		5.3 Media.Form
	6.0 Tracking
		6.1 Tracking.GoogleAnalytics
	
*/

// 1.0 Util ======================================================================
Config = {
	newUser:true,
	bodyNode:$('body'),
	defaultHeight: 470,
	backgroundImageWidth: 8105,
	backgroundSectionWidth: 1157,
	backgroundDisplacement: 60,
	sections: ['', 'about-robert-harris', 'products', 'news', 'competitions', 'education', 'UNDEFINED'],
	navigationNode: $('#header ul.nav'),
	contentId: '#content',
	contentNode: $('#content'),
	contentHolderId: '#content > div.holder',
	jsonAlias:'/jsonProductFilter',
	selectionHolderId:'#selection',
	productOverviewId: '#product-overview',
	productHolderId:'#product-list',
	filterHolderId:'#filters',
	summaryHolderId:'#summary',
	flashNavFile: '/flash/seagull-3.swf',
	flashNavId: 'nav-flash',
	flashNavWidth: 110,
	flashNavHeight: 75,
	flashTopId: 'flash-top',
	flashTopObjectId: 'flash-top-object',
	flashTopHeight: 110,
	flashTopWidth: 765,
	flashRightId: 'flash-right',
	flashRightObjectId: 'flash-right-object',
	flashRightHeight: 560,
	flashRightWidth: 125,
	flashSoundId: 'flash-sound',
	flashSoundHeight: 25,
	flashSoundWidth: 100,
	flashSoundFilePath: '/flash/SoundButton.swf',
	footerNode: $('#footer'),
	colorBoxImage: 'cbox-image',
	colorBoxVideo: 'cbox-video',
	colorBoxForm: 'cbox-form'
}

// usage: log('inside coolFunc',this,arguments);
// paulirish.com/2009/log-a-lightweight-wrapper-for-consolelog/
window.log = function(){
	log.history = log.history || []; // store logs to an array for reference
	log.history.push(arguments);
	if(this.console){
		console.log( Array.prototype.slice.call(arguments) );
	}
};

// 2.0 Frame =====================================================================
Frame = {

	// 2.1 Frame.Default =============================================================
	Default: (
		function () {

			// Set defaults
			function Init(type) {
				if (type == null) {
					type = '';
				}

				switch (type) {
					case 'ajax':
						Frame.Content.SetContent(Config.contentNode);
						Frame.Utility.SetLink(Config.contentNode);
						Frame.Content.OpacityOnHover(Config.contentNode.find('ul.range-list a.image'));
						Frame.Content.EqualizeList(Config.contentNode.find('ul.feature-list'), 2);
						Frame.Content.BackToTop();
						Product.List.Init();
						News.Filter.Init();
						Media.Video.ColorBox(Config.contentNode);
						Media.Image.ColorBox(Config.contentNode);
						Media.Form.ColorBox(Config.contentNode);
						Tracking.GoogleAnalytics.Download(Config.contentNode);
						Tracking.GoogleAnalytics.External(Config.contentNode);
						break;
					default:
						Frame.Utility.UrlHasChanged();
						Frame.Content.SetContent(Config.contentNode);
						Frame.Utility.SetLink(Config.bodyNode);
						Frame.Content.OpacityOnHover(Config.contentNode.find('ul.range-list a.image'));
						Frame.Content.EqualizeList(Config.contentNode.find('ul.feature-list'), 2);
						Frame.Content.BackToTop();
						Frame.Flash.Insert(
							Config.flashNavFile,
							Config.flashNavId,
							Config.flashNavWidth,
							Config.flashNavHeight
						);
						Frame.Flash.IsInContent(Frame.Utility.GetPathName(window.location.href));
						Frame.Flash.Sound();
						Product.List.Init();
						News.Filter.Init();
						Media.Video.ColorBox(Config.bodyNode);
						Media.Image.ColorBox(Config.bodyNode);
						Media.Form.ColorBox(Config.bodyNode);
						Tracking.GoogleAnalytics.Download(Config.bodyNode);
						Tracking.GoogleAnalytics.External(Config.bodyNode);
						break;
				}
			}

			return {
				Init: Init
			}
		}
	)(),

	// 2.2 Frame.Utility =============================================================
	Utility: (
		function () {

			var linkCache = {

		}

		// Url Has Changed
		function UrlHasChanged() {
			$(window).bind(
					'hashchange',
					function (e) {
						var link = e.fragment;
						if (link == '') link = window.location.pathname;
						Frame.Background.Rotate(link);
						if (Config.newUser === false) {
							Frame.Content.AnimateOut(link);
							Tracking.GoogleAnalytics.TrackAsPageView(link);
						} else {
							if (HasHashUrl(window.location.hash)) {
								Frame.Content.AnimateOut(link);
							} else {
								Frame.Flash.IsInContent(Frame.Utility.GetPathName(window.location.href));
							}
							Config.newUser = false;
						}
					}
				);
			$(window).trigger('hashchange');
		}

		// has hash url in path
		function HasHashUrl(path) {
			var hasHash = false;
			if (path.match('#/') != null) hasHash = true;
			return hasHash;
		}

		// is link a file/image from the media folder
		function IsMedia(link) {
			var isMedia = link.indexOf('/media/') == 0;
			return isMedia;
		}

		// is link a relative path (local link)
		function IsRelativePath(link) {
			var isRelativePath = link.slice(0, 2) == '#/' || link.slice(0, 1) == '/' ? true : false;
			return isRelativePath;
		}

		// is link a local or external url
		function IsSameDomain(link) {
			var isSameDomain = link.match(window.location.hostname) != null ? true : false;
			return isSameDomain;
		}

		// is elm a colorbox link
		function IsColorBox(elm) {
			var isColorbox;
			elm.hasClass(Config.colorBoxImage) ||
				elm.hasClass(Config.colorBoxVideo) ||
				elm.hasClass(Config.colorBoxForm) ? isColorbox = true : isColorbox = false;
			return isColorbox;
		}

		// Set Link actions
		function SetLink(elm) {
			if (elm == undefined) {
				elm = $('body');
			}

			// Go thru all filtered links and hash it
			elm.find('a').each(function () {
				var a = $(this);
				var link = a.attr('href');
				var linkSplit;
				var linkNew;

				if ((IsRelativePath(link) || IsSameDomain(link)) && !IsMedia(link) && !IsColorBox(a) && !a.is('[rel*=external]')) {
					var path = GetPathName(link);
					linkSplit = path.split("/");
					linkSplit[0] = '#';
					newUrl = linkSplit.join("/")
					a.attr('href', newUrl);
				}
			});

			elm.find('a[rel*=external]').click(function () {
				var link = $(this).attr('href');
				window.open(link);
				return false;
			});
		}

		// Get Section Name from url path
		function GetSectionName(link) {
			var path = GetPathName(link);
			var section = path.split('/')[1].split('?')[0];
			return section;
		}

		// Get the path from the url
		function GetPathName(path) {
			var url = path;
			if (path.match(window.location.host) != null) path = path.split(window.location.host)[1];
			if (path.match(window.location.hostname) != null) path = path.split(window.location.hostname)[1];
			if (path.match('#/') != null) path = '/' + path.split('#/')[1];
			return path;
		}

		// Get Section Number from Config
		function GetSectionTotal() {
			var total = Config.sections.length;
			return total;
		}

		// Get Section Index from Config
		function GetSectionIndex(sectionName) {
			if (!Array.indexOf) {
				Array.prototype.indexOf = function (obj) {
					for (var i = 0; i < this.length; i++) {
						if (this[i] == obj) {
							return i;
						}
					}
					return -1;
				}
			}
			var num = Config.sections.indexOf(sectionName);
			if (num == -1)
				num = 0;
			return num;
		}

		return {
			GetPathName: GetPathName,
			GetSectionIndex: GetSectionIndex,
			GetSectionName: GetSectionName,
			GetSectionTotal: GetSectionTotal,
			SetLink: SetLink,
			UrlHasChanged: UrlHasChanged
		}
	}
	)(),

	// 2.3 Frame.Background ==========================================================
	Background: (
		function () {

			// Rotate Background Position
			function Rotate(path) {
				var total = Frame.Utility.GetSectionTotal();
				var index = Frame.Utility.GetSectionIndex(Frame.Utility.GetSectionName(path));
				var windowWidth = $(window).width();
				var sectionWidth = Config.backgroundSectionWidth;
				var position = Math.round(((windowWidth - sectionWidth) / 2) - (index * sectionWidth) + Config.backgroundDisplacement);
				$("#background").animate({ backgroundPosition: position + 'px 0' }, 500);
			}

			return {
				Rotate: Rotate
			}
		}
	)(),

	// 2.4 Frame.Content =============================================================
	Content: (
		function () {

			function SetContent(contentNode) {

				var holderNode = contentNode.children('.holder');
				contentNode.addClass('scrolling');
				var holderPadding = holderNode.outerHeight() - holderNode.height();
				var defaultHeight = Config.defaultHeight - holderPadding;

				holderNode.height(defaultHeight);
			}

			// Ajax internal content
			function AjaxContent(link) {
				$.ajax({
					url: link,
					dataTypeString: 'html',
					success: function (data, status, xhr) {
						var titleText = $(data).siblings('title').text();
						Config.contentNode.html($(data).find(Config.contentHolderId));
						AnimateIn(link, titleText);
					},
					error: function (xhr, status, errorThrown) {
						var errorMessage = '';
						switch (xhr.status) {
							case 401:
								errorMessage = 'That was a bad request. ';
								break;
							case 402:
								errorMessage = 'The page appears to be missing. ';
								break;
							case 403:
								errorMessage = 'You do not have the right permissions to view this page. ';
								break;
							case 404:
								errorMessage = 'Usually it means that we are not able to find the page you are looking for. Try checking the URL in your browsers address bar to see if it is been misspelled. ';
								break;
							case 408:
								errorMessage = 'The page has timed out and the server has been unable to deliver. ';
								break;
							case 500:
								errorMessage = 'Usually that there was an error on the server while processing a request, not necessarily related to something you did.';
								break;
						}
						var titleText = xhr.status + ' Error';
						var errorContent = $('<div/>').addClass('holder');
						var errorHeading = $('<div/>').attr({ 'id': 'heading' }).append($('<h1/>').text('Error: ' + xhr.status));
						var errorBody = $('<div class="body-text"/>');
						errorBody.append($('<h2>What does that mean</h2>'));
						errorBody.append($('<p/>').text(errorMessage));
						errorBody.append($('<h2>What next?</h2>' +
							'<p>You could try:</p>' +
							'<ul>' +
							'	<li>' +
							'		<a href="javascript:history.go(-1)">Going back to the last page you were on</a> and either navigating from there, or retrying the action that led you to this page.' +
							'	</li>' +
							'	<li>Go to the homepage of <a href="/" title="Home">Robert Harris</a> to look for the information you want</li>' +
							'	<li>Use the "Back" button on your browser to return to your previous web page</li>' +
							'</ul>'
						));

						$(Config.contentId).html(errorContent.append(errorHeading).append(errorBody));
						AnimateIn(link, titleText);
					}
				});
			}

			// Loading Content
			function LoadingContent(show) {
				var holder = $('div#loading');

				if (holder.length == 0) {
					var loading = $('<div id="loading"><span id="loading-swf"/></div>');
					var flashvars = {};
					var params = { "wmode": "transparent" };
					var attributes = {};
					$(Config.contentId).parent().append(loading);
					swfobject.embedSWF("/flash/loading-large.swf", "loading-swf", "550", "350", "9.0.0", "expressInstall.swf", flashvars, params, attributes);
					holder = $('div#loading');
				}
				if (show == true) {
					holder.css({ 'display': 'block' });
				} else {
					holder.css({ 'display': 'none' });
				}
			}

			// Fade Out Content
			function AnimateOut(link) {
				LoadingContent(true);
				HideContent();
				SetNavigation(link);
				$(Config.contentId).animate(
					{ opacity: 0 },
					500,
					function () {
						AjaxContent(link);
					}
				);
			}

			// Fade In Content
			function AnimateIn(link, title) {
				if (title == '') {
					title = $('h1').text();
				}
				Frame.Default.Init('ajax');
				LoadingContent(false);
				Frame.Flash.IsInContent(link);
				$(Config.contentId).animate(
					{ opacity: 1 },
					500,
					function () {
						ShowContent();
						if (jQuery.browser.msie) this.style.removeAttribute('filter');
						document.title = '';
						document.title = title;
					}
				);
			}

			// Hide content - adding class to hide images that don't animate
			function HideContent() {
				Product.List.HideOverview();
				Config.contentNode.addClass('hidden');
			}

			// Show content - adding class to show images that don't animate
			function ShowContent() {
				Config.contentNode.removeClass('hidden');
			}

			// Change the opacity on rollover
			function OpacityOnHover(elm, amount) {
				if (amount == null) {
					amount = '.5';
				}

				elm.hover(
					function () {
						$(this).fadeTo(250, amount);
					}, function () {
						$(this).fadeTo(250, 1);
					}
				)
			}

			// Equalise list items
			function EqualizeList(elm, colNum) {
				var num = 0;
				elm.children(':nth-child(' + colNum + 'n)').each(function () {
					var maxHeight = 0;
					var item = $(this);
					var start = num - 1;
					var end = num + colNum;
					if (num == 0) {
						elm.children(':lt(' + end + ')').each(function () {
							if (maxHeight < $(this).height()) maxHeight = $(this).height();
						});
					} else {
						elm.children(':lt(' + end + '):gt(' + start + ')').each(function () {
							if (maxHeight < $(this).height()) maxHeight = $(this).height();
						});
					}
					if (num == 0) {
						elm.children(':lt(' + end + ')').each(function () {
							$(this).height(maxHeight);
						});
					} else {
						elm.children(':lt(' + end + '):gt(' + start + ')').each(function () {
							$(this).height(maxHeight);
						});
					}
					num = num + colNum;
				});
			}

			// Back to top
			function BackToTop() {
				var topLink = '<p id="top-link"><a href="#">Back to top</a></p>';
				if ($(Config.contentId).find('#main').height() > 440) {
					$(Config.contentHolderId).append(topLink);
				}
				$('p#top-link').find('a').click(function () {
					$(Config.contentHolderId).scrollTop(0);
					return false;
				});
			}

			function SetNavigation(path) {
				Config.navigationNode.find('a.selected').removeClass('selected');
				Config.navigationNode.find('a[href=#/' + path.split('/')[1] + ']').addClass('selected');
			}

			return {
				AjaxContent: AjaxContent,
				AnimateIn: AnimateIn,
				AnimateOut: AnimateOut,
				EqualizeList: EqualizeList,
				OpacityOnHover: OpacityOnHover,
				SetContent: SetContent,
				BackToTop: BackToTop,
				SetNavigation: SetNavigation
			}
		}
	)(),

	// 2.5 Frame.Flash ==============================================================
	Flash: (
		function () {

			function Insert(filePath, targetId, width, height) {
				var flashvars = {};
				var params = { "wmode": "transparent" };
				var attributes = {};
				swfobject.embedSWF(filePath, targetId, width, height, "9.0.0", "expressInstall.swf", flashvars, params, attributes);
			}

			function Sound() {
				/*
				if (Config.flashSoundFilePath != '') {
				Config.footerNode.append($('<div id="' + Config.flashSoundId + '"/>'));
				Insert(
				Config.flashSoundFilePath,
				Config.flashSoundId,
				Config.flashSoundWidth,
				Config.flashSoundHeight
				);
				}
				*/
			}

			function IsInContent(path) {
				// see if path has a match
				var contentNode = Config.contentNode;
				var match = false;
				var numberOfPages = contentFlash.pages.length;
				var flashTopPath = undefined;
				var flashRightPath = undefined;
				var flashPathLength = 0;
				if (numberOfPages > 0) {

					$.each(contentFlash.pages, function (i, page) {
						if (page['niceUrl'] == path) {
							flashTopPath = page['topFlash'];
							flashRightPath = page['rightFlash'];
							return false;
						} else if (path.indexOf(page['niceUrl']) == 0 && page['niceUrl'].length > flashPathLength) {
							flashTopPath = page['topFlash'];
							flashRightPath = page['rightFlash'];
							flashPathLength = page['niceUrl'].length;
						}
					});

					if (flashTopPath != undefined) {
						contentNode.append($('<div id="' + Config.flashTopId + '"><span id="' + Config.flashTopObjectId + '"/></div>'));
						Insert(
							flashTopPath,
							Config.flashTopObjectId,
							Config.flashTopWidth,
							Config.flashTopHeight
						);
					}

					if (flashRightPath != undefined) {
						contentNode.append($('<div id="' + Config.flashRightId + '"><span id="' + Config.flashRightObjectId + '"/></div>'));
						Insert(
							flashRightPath,
							Config.flashRightObjectId,
							Config.flashRightWidth,
							Config.flashRightHeight
						);
					}

				}
			}

			return {
				Insert: Insert,
				Sound: Sound,
				IsInContent: IsInContent
			}
		}
	)()
}

// 3.0 Product =======================================================================
Product = {

	// 3.1 Product.List ==================================================================
	List: (
		function () {

			function Init() {
				var listId = Config.productHolderId;
				var listNode = $(listId);
				var overviewId = Config.productOverviewId;
				var overviewNode = $(overviewId);
				if (listNode.length != 0) {
					if (overviewNode.length == 0) {
						$('#page').prepend(
							$(
							'<div id="' + overviewId.split('#')[1] + '" style="display:none;">' +
							'<a href="" class="image">' +
								'<strong class=""></strong>' +
								'<img height="135" width="102" src="" alt="">' +
							'</a>' +
							'<h2><a href=""></a></h2>' +
							'<dl class="guide">' +
								'<dt>Grind Type</dt><dd rel="type" class="type"></dd>' +
								'<dt>Strength</dt><dd rel="strength" title="" class=""></dd>' +
							'</dl>' +
							'<p class="desc"></p>' +
							'</div>'
							)
						);
						overviewNode = $(overviewId);

					}
					Config.contentNode.children().scroll(
						function () {
							HideOverview(overviewNode)
						}
					);
					Product.Filter.Init();
					ProductClick(listNode);
					ProductHover(overviewNode, listNode);
				}
			}

			function ProductClick(listNode) {
				listNode.find('a').click(function () {
					listNode.removeClass('active');
				})
			}

			function HideOverview(overviewNode) {
				if (overviewNode == null) {
					overviewNode = $(Config.productOverviewId);
				}
				overviewNode.hide();
			}

			function ActivateHover(listNode) {
				if (listNode == null) {
					listNode = $(Config.productHolderId);
				}
				listNode.addClass('active');
			}

			function ProductHover(overviewNode, listNode) {
				listNode.children('li').hover(function () {
					if (listNode.hasClass('active')) {
						var item = $(this);
						overviewNode.css({ 'top': item.offset(false).top - 12, 'left': item.offset(false).left - (12 + $('#page').offset().left) });
						overviewNode.find('dd').show();
						overviewNode.find('a').attr('href', item.find('a.image').attr('href'));

						item.find('a.image > strong').length > 0 ?
							overviewNode.find('a.image > strong').attr('class', 'new small ir').text(item.find('a.image > strong').text()) :
							overviewNode.find('a.image > strong').attr('class', '').text('');

						overviewNode.find('img').attr('src', item.find('img').attr('src'));
						overviewNode.find('h2 a').text(item.find('h2').text());
						overviewNode.find('dd[rel=type]').text(item.find('dd.type').text());
						overviewNode.find('dd[rel=type]').attr('class', item.find('dd.type').attr('class'));

						// Check if Strength exists
						if (item.find('dd.strength').length > 0) {
							overviewNode.find('dd[rel=strength]').text(item.find('dd.strength').text());
							overviewNode.find('dd[rel=strength]').attr('title', item.find('dd.strength').attr('title'));
							overviewNode.find('dd[rel=strength]').attr('class', item.find('dd.strength').attr('class'));
						} else {
							overviewNode.find('dd[rel=strength]').hide();
						}
						overviewNode.find('p').text(item.find('p').text());
						overviewNode.mouseleave(function () { HideOverview(overviewNode); })
						overviewNode.find('a').click(function () {
							listNode.removeClass('active')
						})
						overviewNode.fadeIn(250, function () {
							if (jQuery.browser.msie) this.style.removeAttribute('filter');
						});

					}
				});
			}

			return {
				Init: Init,
				ActivateHover: ActivateHover,
				HideOverview: HideOverview
			}
		}
	)(),

	// 3.2 Product.Filter ================================================================
	Filter: (
		function () {

			function Init() {
				if ($(Config.selectionHolderId).length > 0) {
					var jsonPath = Frame.Utility.GetPathName(window.location.href) + Config.jsonAlias;
					GetProductFilter(jsonPath);
				}
			}

			// get json product filter for this page
			function GetProductFilter(url) {
				$.getJSON(
					url,
					{},
					function (data) {
						CreateProductFilter(data);
					}
				);
			}

			// create and add filter component
			function CreateProductFilter(data) {

				var selectionNode = $(Config.selectionHolderId);
				var listNode = $(Config.productHolderId);
				var holder = $('<div id="' + Config.filterHolderId.split('#')[1] + '"><ul/></div>');
				var numOfGroups = data.groups.length;

				if (numOfGroups > 0) {

					// go thru each group of filters
					$.each(data.groups, function (i, value) {
						var groupNode = $('<li/>').addClass(value["class"]);
						var title = $('<strong/>').text(value["name"]);
						var filters = $('<ul>');

						// go thru each filter in group
						$.each(value["filters"], function (i, value) {
							var name = value["name"];
							var rel = value["rel"];
							var item = $('<li class="' + rel + '"><a href="#"></a></li>');
							item.children('a').attr({ 'rel': rel, 'title': 'Show ' + name }).text(name).append('<span/>');
							filters.append(item);
						});

						groupNode.append(title);
						groupNode.append(filters);
						holder.children('ul').append(groupNode);

					});

					// insert filters
					selectionNode.append(holder);
					var filterNode = $(Config.filterHolderId);

					// insert summary
					CreateProductListSummary(selectionNode, listNode);
					var summaryNode = $(Config.summaryHolderId);

					// add functionality
					HoverStrength(filterNode)
					ClickFilter(selectionNode, filterNode, listNode, summaryNode);

					Product.List.ActivateHover();

				} else {
					// insert summary
					CreateProductListSummary(selectionNode, listNode);
					Product.List.ActivateHover();
				}

			}

			// if the filter is strength and apply unique hovering states
			function HoverStrength(filterNode) {
				filterNode.find('li.strength a').hover(
					function () {
						elm = $(this);
						title = $('<small/>').text(elm.text());
						elm.closest('ul').after(title);
						elm.parent('li').prevAll('li').each(
							function () {
								$(this).children('a').addClass('hover');
							}
						)
					}, function () {
						filterNode.find('ul ~ small').remove();
						filterNode.find('li.strength a.hover').removeClass('hover');
					}
				);
			}

			// add filter
			function AddFilter(elm) {
				ClearGroup(elm);
				elm.addClass('sel');
			}

			// remove filter
			function RemoveFilter(elm) {
				elm.removeClass('sel');
			}

			// add strength filter selection
			function AddStrengthFilter(elm) {
				RemoveStrengthFilter(elm);
				elm.addClass('sel').parent('li').prevAll('li').children('a').addClass('hi');
			}

			// remove strength filter selection
			function RemoveStrengthFilter(elm) {
				elm.closest('ul').find('a.sel,a.hi').removeClass('sel').removeClass('hi');
			}

			// clear filter group
			function ClearGroup(elm) {
				elm.parent('li').siblings('li').children('a').removeClass('sel');
			}

			// update tool tip
			function UpdateToolTip(elm) {
				var removeText = 'Remove ' + elm.text();
				var showText = 'Show ' + elm.text();

				if (elm.attr('title') == showText) {
					elm.attr({ 'title': removeText });
				} else {
					elm.attr({ 'title': showText });
				}
			}

			// filter functionality
			function ClickFilter(selectionNode, filterNode, listNode, summaryNode) {
				filterNode.children('ul').find('a').click(
					function () {
						Product.List.HideOverview();
						var elm = $(this);
						var isStrength = false;
						var isSelected = false;
						if (elm.is('[class=sel]')) isSelected = true;
						if (elm.parents('li.strength').length > 0) isStrength = true;

						if (isStrength && isSelected) {
							RemoveStrengthFilter(elm);
						} else if (isStrength) {
							AddStrengthFilter(elm);
						} else if (isSelected) {
							RemoveFilter(elm);
						} else {
							AddFilter(elm);
						}
						UpdateToolTip(elm);
						UpdateList(filterNode, listNode);
						UpdateProductListSummary(filterNode, listNode, summaryNode);
						return false;
					}
				);
				selectionNode.children('a.clear-filters').click(
					function () {
						Product.List.HideOverview();
						filterNode.find('a.sel').removeClass('sel');
						filterNode.find('a.hi').removeClass('hi');
						UpdateList(filterNode, listNode);
						UpdateProductListSummary(filterNode, listNode, summaryNode);
						return false;
					}
				);
			}

			// create and add filter list summary
			function CreateProductListSummary(selectionNode, listNode) {
				var holder = $('<div id="' + Config.summaryHolderId.split('#')[1] + '"><ul/></div>');
				var numOfProducts = listNode.children('li').length;
				var summaryText = $('<p>Showing <strong>' + numOfProducts + '</strong> products</p>');
				holder.prepend(summaryText);
				selectionNode.append(holder);
				selectionNode.append('<a href="" class="clear-filters">Clear filters</a>');
			}

			// get the current filters that have been selected
			function GetCurrentFilters(filterNode) {
				var filters = filterNode.find('a.sel');
				return filters;
			}

			// update the product list and show only products that are related to the selected filters
			function UpdateList(filterNode, listNode) {
				var filters = GetCurrentFilters(filterNode);
				var num = 0
				listNode.children('li').removeClass('clear').addClass('hide');
				listNode.children('li').each(function () {
					var item = $(this);
					var itemFilters = item.attr('rel').split(" ");
					var show = true;
					item.removeClass('')
					filters.each(function () {
						if (show == true) {
							var filter = $(this);
							for (i = 0; i < itemFilters.length; i++) {
								if (itemFilters[i] == filter.attr('rel')) {
									show = true;
									break;
								} else {
									show = false;
								}
							}
							//item.is('[rel*=' + filter.attr('rel') + ']') ? show = true : show = false;
						}
					});
					if (show == true) item.removeClass('hide');
				});
				listNode.children(':not(.hide)').each(function () {
					if (num % 5 == 0) $(this).addClass('clear');
					num++;
				});
			}

			// update filter summary
			function UpdateProductListSummary(filterNode, listNode, summaryNode) {
				var numOfProducts = listNode.find('li').length - listNode.find('li[class*=hide]').length;
				var filters = GetCurrentFilters(filterNode);
				var numOfFilters = filters.length;
				var listOfFilters = $('<ul/>');
				var summaryText = $('<p>Showing <strong>' + numOfProducts + '</strong> products</p>');

				if (numOfFilters > 0) {
					summaryText.append(' for: ');
					filters.each(function (i) {
						var title = $(this).text();
						var item = $('<li/>').append($('<strong/>').text(title));
						var total = numOfFilters - 1;
						if (i == total) {
							// do nothing
						} else if (i == (total - 1)) {
							item.children('strong').after(' and ');
						} else {
							item.children('strong').after(', ');
						}
						listOfFilters.append(item);
					});

					summaryNode.children().remove();
					summaryNode.append(summaryText).append(listOfFilters);
				} else {
					summaryNode.children().remove();
					summaryNode.append(summaryText);
				}
			}

			return {
				Init: Init
			}
		}
	)()
}


// 4.0 News ==========================================================================
News = {

// 4.1 News.Filter ===================================================================
	Filter: (
		function() {
			
			function Init(elm) {
				if(elm == undefined) {
					elm = Config.contentNode;
				}
				var filter = elm.find('div.filter');
				var num = 1;
				
				filter.each(function() {
					var elm = $(this);
					var strongElm = elm.find('strong');
					var listElm = elm.find('ul');
					var label = $('<label/>').text(strongElm.text());
					var select = ConvertListToSelect(listElm);
					elm.append(label);
					elm.append(select);
					strongElm.remove();
					listElm.remove();
					num++;
				});
			}

			function ConvertListToSelect(elm) {
				var select = $('<select class="text"><option value="#' + window.location.hash.split('#')[1].split('?')[0] + '">All</option></select>');
				elm.children().each(function() {
					var i = $(this);
					var option = $('<option/>');
					var year = window.location.hash.split('year=')[1];
					option.text(i.text());
					option.attr('value',i.children('a').attr('href'));
					if(year == i.text()) option.attr('selected','selected');
					select.append(option);
				});
				select.change(function() {
					window.location = $(this).attr('value');
				})
				return select;
			}

			return {
				Init: Init
			}
		}
	)()
}

// 5.0 Media =========================================================================
Media = {

	// 5.1 Media.Colorbox ================================================================
	ColorBox: (
		function () {
			function FindImageLink(link) {
				return link.closest('li').find('a.image.cbox-image');
			}

			function GetImageNode(link) {
				i = link.children('img');
				if (!i.is('img')) alert('Error: could not find image');
				return i;
			}

			function GetImageTitle(link) {
				return GetImageNode(link).attr('title')
			}

			function GetImageAlt(link) {
				return GetImageNode(link).attr('alt')
			}

			return {
				FindImageLink: FindImageLink,
				GetImageTitle: GetImageTitle,
				GetImageAlt: GetImageAlt
			}
		}
	)(),

	// 5.2 Media.Image ==================================================================
	Image: (
		function () {
			function ColorBox(elm) {
				if (elm == undefined) {
					elm = $('body');
				}
				elm.find('a.' + Config.colorBoxImage).colorbox(
					{
						close: 'Close',
						title: function () {
							var title = $(this).hasClass('image') ? Media.ColorBox.GetImageTitle($(this)) : Media.ColorBox.GetImageTitle(Media.ColorBox.FindImageLink($(this)));
							return title;
						},
						current: '',
						opacity: 0.90,
						innerWidth: 580,
						innerHeight: 415,
						onComplete: function () {
							var caption = $(this).hasClass('image') ? Media.ColorBox.GetImageAlt($(this)) : Media.ColorBox.GetImageAlt(Media.ColorBox.FindImageLink($(this)));
							var title = $(this).hasClass('image') ? Media.ColorBox.GetImageTitle($(this)) : Media.ColorBox.GetImageTitle(Media.ColorBox.FindImageLink($(this)));

							$('#cboxContent').attr('class', '').addClass('cbox-image');
							$('#cboxTitle').prependTo('#cboxContent');
							if (title != caption) $('#cboxContent').append($('<div id="cboxCaption"/>').text(caption));

							var heightOld = $('#cboxContent').height();
							var heightNew = $('#cboxTitle').outerHeight() + $('#cboxLoadedContent').outerHeight() + $('#cboxCaption').outerHeight();
							var topNew = $('#colorbox').offset().top - ((heightNew - heightOld) / 2);

							$('#cboxContent').height(heightNew);
							$('#colorbox').css({ 'top': topNew + 'px' });
							if (jQuery.browser.msie && jQuery.browser.version < 8) $('#cboxCaption').css('font-style', 'normal');
							Tracking.GoogleAnalytics.ColorBox('Image Viewed', title);

						},
						onLoad: function () {
							$('#cboxCaption').remove();
						}
					}
				);
			}

			return {
				ColorBox: ColorBox
			}
		}
	)(),

	// 5.3 Media.Video ==================================================================
	Video: (
		function () {
			function ColorBox(elm) {
				if (elm == undefined) {
					elm = $('body');
				}
				elm.find('a.' + Config.colorBoxVideo).colorbox(
					{
						close: 'Close',
						title: function () {
							var title = $(this).hasClass('image') ? Media.ColorBox.GetImageTitle($(this)) : Media.ColorBox.GetImageTitle(Media.ColorBox.FindImageLink($(this)));
							return title;
						},
						iframe: true,
						opacity: 0.90,
						innerWidth: 500,
						innerHeight: 430,
						onComplete: function () {
							var caption = $(this).hasClass('image') ? Media.ColorBox.GetImageAlt($(this)) : Media.ColorBox.GetImageAlt(Media.ColorBox.FindImageLink($(this)));
							var title = $(this).hasClass('image') ? Media.ColorBox.GetImageTitle($(this)) : Media.ColorBox.GetImageTitle(Media.ColorBox.FindImageLink($(this)));

							$('#cboxContent').attr('class', '').addClass('cbox-video');
							$('#cboxTitle').prependTo('#cboxContent');
							$('#cboxLoadedContent').css({ 'overflow': 'hidden' });

							if (title != caption) $('#cboxContent').append($('<div id="cboxCaption"/>').text(caption));

							var heightOld = $('#cboxContent').height();
							var heightNew = $('#cboxTitle').outerHeight() + $('#cboxLoadedContent').outerHeight() + $('#cboxCaption').outerHeight();
							var topNew = $('#colorbox').offset().top - ((heightNew - heightOld) / 2);

							$('#cboxContent').height(heightNew);
							$('#colorbox').css({ 'top': topNew + 'px' });
							if (jQuery.browser.msie && jQuery.browser.version < 8) $('#cboxCaption').css('font-style', 'normal');
							Tracking.GoogleAnalytics.ColorBox('Video Viewed', title);
						},
						onLoad: function () {
							$('#cboxCaption').remove();
						}
					}
				);
			}

			return {
				ColorBox: ColorBox
			}
		}
	)(),

	// 5.4 Media.Form ===================================================================
	Form: (
		function () {
			function ColorBox(elm) {
				if (elm == undefined) {
					elm = $('body');
				}
				elm.find('a.' + Config.colorBoxForm).colorbox(
					{
						close: 'Close',
						title: false,
						iframe: true,
						opacity: 0.90,
						innerWidth: 660,
						innerHeight: 600,
						onComplete: function () {

							$('#cboxContent').attr('class', '').addClass('cbox-form');
							$('#cboxLoadedContent').css({ 'overflow': 'hidden' });

							var heightOld = $('#cboxContent').height();
							var heightNew = $('#cboxLoadedContent').outerHeight();
							var topNew = $('#colorbox').offset().top - ((heightNew - heightOld) / 2);

							$('#cboxContent').height(heightNew);
							$('#colorbox').css({ 'top': topNew + 'px' })
						},
						onCleanup: function () {
							if ($.browser.msie && $.browser.version == 8) {
								var queryString = '?reload=' + new Date().getTime();
								$('link[rel="stylesheet"]').each(function () {
									this.href = this.href.replace(/\?.*|$/, queryString);
								});
							}
						}
					}
				);
			}

			return {
				ColorBox: ColorBox
			}
		}
	)()

}

// 6.0 Tracking ======================================================================
Tracking = {

	// 6.1 Tracking.GoogleAnalytics ======================================================
	GoogleAnalytics: (function () {
		function TrackAsPageView(path) {
			if (typeof _gaq != 'undefined') {
				_gaq.push(['_trackPageview', path]);
			}
		}

		function TrackAsEvent(category, action, label) {
			if (typeof _gaq != 'undefined') {
				_gaq.push(['_trackEvent', category, action, label]);
			}
		}

		function ColorBox(action, label) {
			TrackAsEvent('Colorbox', action, label);
		}

		function Download(target) {
			target.find('a[href$=.zip],a[href$=.pdf],a[href$=.doc],a[href$=.docx],a[href$=.xls],a[href$=.xlsx],a[href$=.ppt],a[href$=.pptx]').click(
				function () {
					var path = $(this).attr('href');
					var type = 'File';
					TrackAsEvent('Download', type, path);
				}
			);
		}

		function External(target) {
			target.find('a[href^=http],a[href^=https],a[href^=mailto]').click(
				function () {
					var path = $(this).attr('href');
					if (path.indexOf('mailto') == 0) {
						TrackAsEvent('External', 'Email', path);
					} else if (path.indexOf(window.location.hostname) == -1) {
						TrackAsEvent('External', 'Site', path);
					}
				}
			);
		}

		return {
			TrackAsPageView: TrackAsPageView,
			TrackAsEvent: TrackAsEvent,
			ColorBox: ColorBox,
			Download: Download,
			External: External
		}
	})()
}
