var Viaduct = function($) {
	var zoom_icon_path = '/skin/frontend/viaduct/default/img/icons/zoom.gif';
	var lazyload_placeholder = '/skin/frontend/viaduct/default/img/product/placeholder.jpg';

	function init() {
		$(document.body).addClass('js');
		
		pngFix();
		attachSearchBox();
		attachZoom();
		attachProductOptions();
		attachGallery();
		attachSmoothScrolls();
		attachPrettyForms();
		attachLinkDropDowns();
		attachEqualHeights();
		attachProductNavStates();
		attachMetaNavStates();
		attachViaduct100Title();
		attachWidgetMargins();
		attachPlatformClass();
		attachPopups();
		attachProjectMap();
		attachDropDownSubmit();
		attachOutboundLinks();
		attachSearchForm();

		if (!isMobileDevice()) {
			attachGalleryHovers();
			attachScrollingNavigation();
			attachLazyLoad();
		}
	}
	
	function pngFix() {
		if (typeof(jQuery.fn.pngFix) == 'function') {
			$(document).pngFix();
		}	
	}
	
	function attachSearchBox() {
		if ($('#q').attr('value') == '') {
			$('#q').attr('value', $('#q').prev('label').html());
		}
			
		$('#q').focusin(function() {
			if ($(this).attr('value') == $(this).prev('label').html()) {
				$(this).attr('value', '');
			}
		});
		
		$('#q').focusout(function() {
			if ($(this).attr('value') == '') {
				$(this).attr('value', $(this).prev('label').html());
			}
		});	
	}
	
	function attachScrollingNavigation() {
		if ($('nav#main').length < 1 || $('#body').length < 1) {
			return false;
		}

		var moveMenu = function() {
			var bottomOfNavigation = $(this).scrollTop()
						+ $('nav#main').height();
			var bottomOfContainer = $('#body').position().top
						+ $('#body').height();

			if ($(this).scrollTop() < $('#body').position().top) {
				// We've reached the top of the container, so snap menu
				// inside
				$('nav#main').css({
					'top': 0 + 'px',
					'left': 0 + 'px'
				}).removeClass('scrolling');
			} else if (bottomOfNavigation > bottomOfContainer) {
				// We've reached the bottom of the container, so snap menu
				// inside
				$('nav#main').css({
					'top': bottomOfContainer - $('#body').position().top - $('nav').height() + 'px',
					'left': 0 + 'px'
				}).removeClass('scrolling');
			} else {
				$('nav#main').css({
					left: $('#body').position().left + 'px'
				}).addClass('scrolling');
			}
		};

		$(window).scroll(moveMenu);
		$(window).resize(moveMenu);
	}
	
	function attachGalleryHovers() {		
		$('.darken').mouseover(function() {
			if ($(this).find('.darken-hover').length > 0) {
				return false;
			}
			
			$(this).append('<div class="darken-hover"></div>');
			$('.darken-hover').css({
				'width': $(this).width(),
				'height': $(this).height()
			});
			
			$('.darken-hover').mouseout(function() {
				if (!$(this).parent('.darken')
						.hasClass('active')) {
					$(this).remove();
				}
			});
		});
	}
	
	function attachZoom() {
		$('#zoom-icon').remove();
		
		$('.zoom').mouseover(function() {			
			$(this).append('<img src="' + zoom_icon_path + '" alt="zoom" ' +
						'id="zoom-icon">');
		});
		
		$('.zoom').mouseout(function() {
			$('#zoom-icon').remove();
		});
	}
	
	function attachProductOptions() {
		$('.product-option-detail:gt(0)').hide();
		
		$('#product-options a.option').click(function(event) {
			event.preventDefault();
			
			// Remove active classes from other links
			$('#product-options a.active').removeClass('active');

			$(this).addClass('active');

			if (new String($(this).attr('href')).length > 1) {
				$('.product-option-detail').hide();
				$($(this).attr('href')).show();
			}
		});
	}
	
	function attachGallery() {
		if ($('#product-detail').length < 1) {
			return false;
		}
		
		var carouselOptions = {
				scroll: 5,
				visible: 5
		};

		// Only run jCarousel if there are more than six items in
		// the navigation
		if ($('#gallery-carousel').children().length <= 6) {
			$('#gallery-overlay').addClass('no-nav');
		} else {
			$('#gallery-carousel').jcarousel(carouselOptions);
		}

		$('#gallery-overlay').hide();
		$('#gallery-overlay').css({
			top: $('#product-detail').position().top
		});

		$('.gallery-launchers a, .gallery-launcher').click(function(e) {
			e.preventDefault();

			addModalCloser();
			
			$('.close-gallery, #modal-closer').click(function(e) {
				e.preventDefault();

				$('#gallery-overlay').fadeOut(500);
				$('#modal-closer').remove();
				$('#gallery-carousel .active').removeClass('active');
				$('#gallery-carousel .darken-hover').remove();
			});
			
			$('#gallery-zoomable img').attr('src', $(this).attr('href'));
			if ($(this).hasClass('large')) {
			    $('#gallery-zoomable').addClass('zoomable-large');
			} else {
			    $('#gallery-zoomable').removeClass('zoomable-large');
			}

			$('#gallery-overlay').fadeIn(500, function() {
				$('.darken-hover').mouseout();
			});			

			// Add active class to launched image in carousel
			$('#gallery-carousel')
				.find("a[href='"+$(this).attr('href')+"']")
				.addClass('active').mouseover();
				
			// Trigger resize function once to set initial
			// dimensions
			$(window).resize();
		});

		$('#gallery-overlay').zoomGallery({
			imageContainer: '#gallery-zoomable',
			carousel: '#gallery-carousel',
			largeWidth: 1228,
			largeHeight: 832,
			smallWidth: 614,
			smallHeight: 462,
			loadingMessage: 'Loading...'
		});		
	}
	
	function attachSmoothScrolls() {
		$('.smooth-scroll').click(function(e) {
			e.preventDefault();
			
			$('.smooth-scroll-disabled').each(function() {
				$(this).removeClass('smooth-scroll-disabled');
			});
			$(this).addClass('smooth-scroll-disabled');
			
			var target = $(this).attr('href').toString();
			$('.smooth-scroll-container').scrollTo($(target), 800);
		});
	}
	
	function attachLinkDropDowns() {
		$('.link-dropdown button').hide();
		
		$('.link-dropdown').submit(function(e) {
			e.preventDefault();
			
			window.location = $(this).children('select').attr('value');
		});
		
		$('.link-dropdown select').change(function(e) {
			$(this).parent('form').submit();
		});

		// Attach specific case for 'pretty' dropdowns
		$('.link-dropdown .option').click(function(e) {
			e.preventDefault();

			window.location = $(this).attr('rel');
		});
	}
	
	function attachLazyLoad() {
		$('.lazyload img').lazyload({
			placeholder: lazyload_placeholder
		});
	}
	
	function attachPrettyForms() {
		attachPrettyRadioButtons();
		attachPrettyCheckboxes();
		attachPrettyDropDowns();
		attachPrettyLabels();
	}
	
	function attachPrettyRadioButtons() {
		// Replace radio buttons with styled element
		$('.pretty').find("input[type='radio']").each(function() {
			$(this).hide();
			$(this).after('<span class="prettified radio" lang="' + 
						$(this).attr('name') + '"></span>');
		});
		
		$('.radio').click(function() {
			var name = $(this).attr('lang');
			
			// Remove selected state from all other faux radio buttona in group
			$("span[lang='"+name+"']").removeClass('radio-selected');
		
			// Add selected state to currently selected faux radio button
			$(this).addClass('radio-selected');
			
			// Check the relevant hidden radio button behind the scenes
			$(this).prev("input[type='radio']").attr('checked', 'checked');
		});
	}
	
	function attachPrettyCheckboxes() {
		// Replace checkboxes with styled elements
		$('.pretty').find("input[type='checkbox']").each(function() {
			$(this).hide();
			var checkedClass = '';
			if ($(this).attr('checked')) {
				checkedClass = 'checkbox-checked';
			}
			$(this).after('<span class="prettified checkbox ' +
					checkedClass + '"lang="' +
					$(this).attr('name') + '"></span>');
		});
		
		// Toggle checkbox on and off when clicked
		$('.checkbox').click(function() {
			$(this).prev("input[type='checkbox']").click();
			
			if ($(this).prev("input[type='checkbox']").attr('checked')) {
				$(this).addClass('checkbox-checked');
			} else {
				$(this).removeClass('checkbox-checked');
			}
		});
	}
	
	function attachPrettyDropDowns() {
		$('.pretty select').each(function() {
			$(this).hide();
			var options = $(this).find('option');
						
			// Grab the already selected value. Default to first option if
			// nothing selected
			if ($(this).find('option:selected').length > 0) {
				var firstOption = '<h3 class="chosen-option prettified">' + 
					$(this).find('option:selected').text() + '</h3>';
			} else {
				var firstOption = '<h3 class="chosen-option prettified">' 
					+ $(options[0]).text() + '</h3>';
			}

			// If the dropdown has a set CSS width, use that, otherwise
			// fall back to rendered width
			if ($(this).css('width') != 'auto' &&
					$(this).css('width') != 'intrinsic') {
				var dropDownWidth = parseInt(new String($(this)
					.css('width')).replace('px', ''));
			} else {
				var dropDownWidth = $(this).width();
			}

			dropDownWidth += 20;

			// Set minimum width for dropdown to 170
			if (dropDownWidth < 170 && !$(this).hasClass('fixed')) {
				dropDownWidth = 170;
			}
			
			// Build HTML faux dropdown element and add to page
			var htmlFragment = '<div class="dropdown ' + $(this).attr('class') 
					+ '" style="width: ' + dropDownWidth +'px">' 
					+ firstOption + '<ul class="option-container" '
					+ 'style="width: ' + dropDownWidth +'px">';
			for (var i = 0; i < options.length; i++) {
				htmlFragment += '<li class="option" rel="' 
					+ $(options[i]).attr('value') + '">' 
					+ $(options[i]).html() + '</li>';
			}
			
			htmlFragment += '</ul></div><span class="dropdown-spacer></span>';
			
			$(this).after(htmlFragment);
			
			// Set the height of the spacer element to the height of the 
			// dropdown
			$('.dropdown-spacer').css('height', $('.dropdown').height());			
		});
		
		var closeDropDowns = function() {
			$('.option-container').hide();
			$('.dropdown.open .active').removeClass('active');
			$('.dropdown.open').removeClass('open');
			$(document).unbind('click', closeDropDowns);			
		}
		
		// Dropdown opener has been clicked
		$('.pretty .dropdown .chosen-option').click(function(e) {
			// Prevent this event from triggering the document.click event
			e.stopPropagation();
			
			if ($('.dropdown.open').length > 0) {
				// A dropdown is open, so close it
				closeDropDowns();
			} else {
				// Set the active class on the relevant value
				var selectedValue = $(this)
					.parents('.dropdown').prev('select')
					.find('option[selected]').attr('value');
				$(this).parent('.dropdown')
					.find(".option-container li[rel='"+selectedValue+"']")
					.addClass('active');

				// Open the dropdown
				$(this).parent('.dropdown').addClass('open')
					    .find('.option-container').show();
				
				// Cause a click anywhere on the document to trigger the click
				// event on the dropdown, which will close any that are open
				$(document).click(closeDropDowns);
			}
		});
		
		// Option has been selected in dropdown
		$('.pretty .dropdown .option').click(function() {
			var selectedValue = $(this).attr('rel');
			
			// Set the selected value of the real (hidden) dropdown
			$(this).parents('.dropdown').prev('select')
					.find("option[value='"+selectedValue+"']")
					.attr('selected', 'selected');
			
			// Set the text value of the pretty dropdown chosen value to 
			// current
			$(this).parents('.dropdown').find('.chosen-option')
					.text($(this).text());

			// Trigger the onChange event of the 'real' dropdown
			// in case an event is bound to it
			$(this).parents('.dropdown').prev('select').change();
		});
	}
	
	function attachPrettyLabels() {
		$('.pretty label').click(function(e) {
			$(this).parent().find('.prettified:first').click();
		});
	}

	function attachEqualHeights() {
		$('.equalheight .equalheight-item').equalHeights();

		// Groups together equal height elements from 1-3 and sets
		// their height accordingly.
		for (var number = 1; number <= 3; number++) {
			var items = $('.equalheight-'+number+' .equalheight-item');
			var collection = new Array();
			for (var i = 0; i < items.length; i++) {
				collection.push(items[i]);
				if ((i+1) % number == 0) {
					$(collection).equalHeights();
					collection = new Array();
				}
			}
		}
	}

	function attachProductNavStates() {
		if (typeof(PRODUCT_VIEW_VIADUCT_100) != 'undefined') {
			if (PRODUCT_VIEW_VIADUCT_100) {
				$('#nav-viaduct100 a').addClass('active');
			} else {
				$('#nav-our-products a').addClass('active');
			}
		}
	}

	function attachMetaNavStates() {
		// Add nav-highlight-[section-ID] to meta keywords to make
		// it appear as active in the primary nav
		var keywords = $("meta[name='keywords']").attr('content');
		if (!keywords || new String(keywords).length < 1) {
			return false;
		}
		
		var regex = new RegExp('nav-highlight-([a-zA-Z0-9-]+)', 'g');
		var matches = regex.exec(keywords);
		if (matches && typeof(matches[1]) != 'undefined') {
			$('#nav-'+matches[1]).addClass('active');
		}
	}

	function attachViaduct100Title() {
		if (typeof(PAGE_VIADUCT_100_TITLE) != 'undefined') {
			$('#page-title').addClass('viaduct100');
		}

		if (typeof(PRODUCT_VIEW_VIADUCT_100_POSITION) != 'undefined') {
			$('#page-title').prepend(
				'<span class="number"><span>'+
				PRODUCT_VIEW_VIADUCT_100_POSITION +
				'</span></span>'
			);
		}
	}

	function attachWidgetMargins() {
		$('.widget-198').each(function(index, element) {
			if ((index+1) % 3 != 0) {
				$(element).addClass('marginR');
			}
		});

		$('.widget-302:even').addClass('marginR');
	}

	function attachPlatformClass() {
		// The platform detection is unfortunately needed to cater
		// for the different font rendering between Apple and Windows
		var ua = new String(navigator.userAgent).toLowerCase();
		var platform = 'windows';
		if (ua.indexOf('mac os') > 0) {
			platform = 'mac';
		}

		$(document.body).addClass(platform);
	}

	function attachPopups() {
		$("a[rel~='popup']").click(function(e) {
			e.preventDefault();

			var width, height = 500;
			var regex = /w([0-9]+)h([0-9]+)/;
			var dimensions = regex.exec($(this).attr('rel'));

			if (dimensions.length > 2) {
				width = dimensions[1];
				height = dimensions[2];
			}

			window.open(
				$(this).attr('href'),
				'viaduct_popup',
				'status=1, height='+height+', width='+width+
				', resizable=1, scrollbars=1'
			);
		});
	}

	function attachProjectMap() {
		if ($('.project-map').length < 1) {
			return false;
		}

		$('.icon').mouseover(function(e) {
			e.preventDefault();

			$('.rollover, .project-detail, .selected').hide();
			$(this).addClass('active');

			if ($(this).parent().find('.rollover').hasClass('right')) {
				var leftPos = $(this).position().left -
					$(this).parent().find('.rollover').outerWidth() + 33;
			} else {
				var leftPos = $(this).position().left - 3;
			}

			if ($(this).parent().find('.rollover').hasClass('top')) {
				var topPos = $(this).position().top;
			} else {
				var topPos = $(this).position().top -
					$(this).parent().find('.rollover')
					.outerHeight() + 33;
			}

			$(this).parent().find('.rollover').show().css({
				'top': topPos + 'px',
				'left': leftPos + 'px'
			}).addClass('open');
			
			$('.rollover.open, .icon').mouseout(function(e) {
				if ($('.rollover.open').length < 1) {
					return false;
				}
				
				var left = $('.rollover.open').offset().left;
				var top = $('.rollover.open').offset().top;
				var bottom = $('.rollover.open').offset().top
					+ $('.rollover.open').outerHeight();
				var right = $('.rollover.open').offset().left
					+ $('.rollover.open').outerWidth();

				if (e.pageX < left || e.pageX > right ||
					e.pageY < top || e.pageY > bottom) {

					$('.rollover').removeClass('mouseover')
							.removeClass('open')
							.hide();
					$('.icon.active').removeClass('active');
				}
			});
		});

		$('.icon').click(function() {
			if ($(this).parent().find('.rollover a')
				.hasClass('follow')) {
				window.location.href = $(this).parent()
					.find('.rollover a').attr('href');
			} else {
				$(this).parent().find('.rollover a').click();
			}
		});

		$('.show-selected, .project-link, .project-back')
			.click(function(e) {
			e.preventDefault();

			$('.rollover, .selected, .project-detail').hide();
			$('.icon').removeClass('active');
			$('.icon').hide();
			$('#hixbox').remove();

			var link = new String($(this).attr('href'))
				.replace('#', '');
			$('#'+link).show();

			addModalCloser();
		});

		$('.close, #modal-closer').live('click', function(e) {
			e.preventDefault();

			$('.icon').show();
			$('#modal-closer').remove();
			$('.selected, .project-detail').hide();
		});
	}

	function attachDropDownSubmit() {
		$('select.submit-form').change(function() {
			$(this).parents('form').submit();
		})
	}

	function attachOutboundLinks() {
		$("a[rel~='external']").click(function(e) {
			e.preventDefault();
			window.open($(this).attr('href'));
		});
	}

	function attachSearchForm() {
		if ($('.search-form').length < 1) {
			return false;
		}

		var originalSearchText = $('.search-form input').attr('value');
		$('.search-form').submit(function() {
			if ($('.search-form input').attr('value') == originalSearchText) {
				$('.search-form input').addClass('error').width(
					$('.search-form input').width() - 2
				).focus();
				return false;
			}
		});

		$('.search-form input').focusout(function() {
			if ($(this).hasClass('error')) {
				$(this).removeClass('error').width(
					$(this).width() + 2
				);
			}
		})
	}

	function isMobileDevice() {
		// Provides only basic user agent matching on common strings
		var mobileDevices = new Array(
			'iPad',
			'iPhone',
			'android',
			'Symbian',
			'BlackBerry',
			'palm',
			'Windows CE',
			'IEMobile',
			'Smartphone'
		);

		for (i = 0; i < mobileDevices.length; i++) {
			var regex = new RegExp(mobileDevices[i], 'i');
			if (navigator.userAgent.match(regex)) {
				return true;
			}
		}

		return false;
	}

	function addModalCloser() {
		$('#modal-closer').remove();

		// Attach clickable element over the top of entire page
		// to close gallery when clicked
		$('body').prepend('<div id="modal-closer"></div>');

		// Keep overlay to same dimensions as window
		$(window).resize(function() {
			$('#modal-closer').css({
				width: $(window).width() + 'px',
				height: $('body').height() + 'px'
			});
		}).resize();
	}
	
	return {
		init: init
	}
}(jQuery);

jQuery.noConflict();
jQuery(document).ready(function(){
	Viaduct.init();
});
