/**
 * lh.js
 * @author Lewis Howles (Boilerplate)
 *
 * One part default niceties, one part scripting goodness...
 */

var lh = {
	// Initialisation function.
	init : function() {
		(searchQuery.config.form.length || searchQuery.config.resultsFrame.length) && searchQuery.init();
		lh.externalLinks();
		lh.highlighter();
		lh.styleSwitcher();
		lh.placeholder();
		lh.welcome();
		$('#map-canvas').length && lh.maps();

		$('#contact-form').length && lh.validate();

		$('#image-gallery').innerfade({
			speed: 1000,
			timeout: 6000,
			containerheight: '250px'
		});

		$('#mortgage-calculator').length && lh.mortgageCalculator();
	},

	// Set target blank on external links
	externalLinks : function() {
		$('a[rel~="external"]').attr('target', '_blank');
	},

	// Triggers toggleFocus when hovering styled form fields
	highlighter : function() {
		$('form.fancy').delegate('input, select, textarea', 'mouseover focusin mouseout focusout', function(e) {
			// Check whether the event is an 'inward' event
			var isIn = (e.type === 'mouseover' || e.type === 'focusin');

			lh.toggleFocus($(this), isIn);
		});
	},

	// Adds a 'focus' class to parent lis only if a field is hovered,
	// not the li itself.
	toggleFocus : function(hovered, modifier) {
		// Use the result of isIn above to modify toggleClass
		hovered.parent('li').not('.li-submit').toggleClass('focus', modifier);
	},

	// Adds a 'Reader Mode' button (hidden by default.css in IE).
	// Changes the main stylesheet to the 'reader' stylesheet for a
	// nice readable display of the content.
	styleSwitcher : function() {
		var styleSwitcher = $('#style-switcher');

		styleSwitcher
			.data('sheet','global')
			.bind('click', function(){
				// Check the current stylesheet and set an array of
				// values appropriately. Update values if stylesheets
				// are named differently.
				var params = (styleSwitcher.data('sheet') == 'global') ? ['reader','Visual Mode'] : ['global','Reader Mode'];
				$('link[rel=stylesheet]')
					.eq(1) // 0-indexed position of stylesheet. Change this is you had to move global.
					.attr('href', 'css/'+params[0]+'.css');
				styleSwitcher
					.data('sheet',params[0])
					.text(params[1]);
			});
	},

	// If the placeholder attribute is not supported by the user's
	// browser, implement a replacement using the value of the
	// original placeholder attribute, so no additional markup is
	// required.
	placeholder : function() {
		// Use Modernizr to check for support
		if (!Modernizr.input.placeholder) {
			// Set initial values to placeholder
			$("input.text, textarea").each(function(){
				var input = $(this);

				// Check value is empty before overwriting
				(input.val() === "") && input.val(input.attr('placeholder'));
			});

			$("input.text, textarea")
				.focus(function(){
					var input = $(this);

					// Clear the value only if it is identical to the
					// placeholder.
					(input.val() === input.attr('placeholder')) && input.val("");
				})
				.blur(function(){
					var input = $(this);

					// Return the value to placeholder only if the
					// current value is blank.
					(input.val() === "") && input.val(input.attr('placeholder'));
				});
		}
	},

	// Display the current date, and a welcome message appropriate
	// to the current time in the banner area, and animate that,
	// along with the property search, into view in a nice way
	welcome : function(){
		var now = new Date(),
			hour = now.getHours(),
			text;

		// Determine time bands for greetings
		if (hour >= 12 && hour < 17) {
			text = 'Good Afternoon';
		} else if (hour >= 17) {
			text = 'Good Evening';
		} else {
			text = 'Good Morning';
		}

		var welcome = $('#welcome'),
			welcomeHeight = welcome.outerHeight()+1,
			greeting = $('#welcome').find('h2'),
			propertySearch = $('#property-search'),
			propertySearchHeight = propertySearch.outerHeight();

		// Wait 2 seconds, so the user has chance to read the
		// original welcome message, then slide the welcome area
		// out of view, update the values, and slide it back.
		welcome
			.delay(2000)
			.animate({'top' : '-'+welcomeHeight+'px'}, 1200, function() {
				greeting.text(text);
				$(this).animate({'top' : '0'}, 1200);
			});

		// Hide the search box initially (done here as opposed to in
		// the CSS as the height might be slightly different
		// depending on font rendering), then slide it back, in time
		// with the welcome area
		propertySearch
			.css({'top' : '-'+propertySearchHeight+'px'})
			.show()
			.delay(3200)
			.animate({'top' : '0'}, 1200);
	},

	maps : function() {
		// Set a new map and set the lat and long
		var latlng = new google.maps.LatLng(54.71355, -6.2124);

		// Set map options
		var myOptions = {
			zoom: 12,
			center: latlng,
			mapTypeId: google.maps.MapTypeId.ROADMAP
		};

		var map = new google.maps.Map(document.getElementById("map-canvas"), myOptions);

		// Create a new map marker
		var marker = new google.maps.Marker({
			position: latlng,
			map: map,
			title: '22 Fountain Street, Antrim, County Antrim, BT41 1BB, Northern Ireland'
		});

		$('#map-large').colorbox({
			iframe		: true,
			height		: '90%',
			transition	: 'elastic',
			width		: '90%'
		});
	},

	validate : function() {
		$('#contact-form').validate({
			rules: {
				first_name : 'required',

				telephone : {
					phoneUK : true
				},

				from_email : {
					required : true,
					email : true
				},

				from_email_repeat : {
					required : true,
					equalTo : '#from_email'
				},

				query : 'required',

				txtCaptcha : 'required'
			},

			messages: {
				first_name : 'Please provide at least your first name, so we know what to call you',

				from_email : {
					required : 'We need your email address to contact you',
					email : 'The email address you provided doesn&rsquo;t seem to be valid'
				},

				from_email_repeat : {
					required : 'Please confirm your email address, just in case',
					equalTo : 'The email addresses you&rsquo;ve provided don&rsquo;t match'
				},

				query : 'Don&rsquo;t forget to ask us a question, or leave us a comment',

				txtCaptcha : 'Please enter the numbers you see above'
			},

			errorPlacement: function(error, element) {
				var required = element.next('.required');

				if (required.length)
				  error.insertAfter(required);
				else
				  error.insertAfter(element);
			},

			invalidHandler: function(e, validator) {
				var errors = validator.numberOfInvalids(),
					globalError = $('#global-error');

				if (errors) {
					var message = errors == 1
						? 'You missed 1 field. It has been highlighted below.'
						: 'You missed ' + errors + ' fields.  They have been highlighted below.';
					$('#error-message').text(message);
					globalError.show();
				} else {
					globalError.hide();
				}
			}
		});
	},

	mortgageCalculator : function() {
		$('#mortgage-calculator').find('.submit').click(function(e) {
			e.preventDefault();

			var interest = $('#interest-rate').val(),
				term = $('#term').val() * 12,
				interestOnly = $('#interest-only').find('span'),
				repayment = $('#repayment').find('span'),
				remaining = $('#sale-price').val() - $('#deposit').val(),
				ratePerMonth = interest / 1200,
				monthlyRepayment = (remaining * ratePerMonth) / (1 - (1 / Math.pow((1 + ratePerMonth), term))),
				loanValue = monthlyRepayment * term;

			repayment.text(formatCurrency(monthlyRepayment));
			interestOnly.text(formatCurrency((remaining / 100)*(interest / 12)));

			function formatCurrency(num) {
				var number = num.toString().replace(/\£|\,/g,'');

				if (isNaN(number))
					number = "0";
				else
					number = Math.floor(number*100+0.50000000001);

				var sign = (number == (number = Math.abs(number))),
					pence = number % 100;

				number = Math.floor(number / 100).toString();

				if (pence < 10)
					pence = "0" + pence;

				for (var i = 0; i < Math.floor((number.length-(1 + i)) / 3); i++) {
					number = number.substring(0,number.length-(4 * i + 3)) + ',' + number.substring(num.length-(4 * i + 3));
				}

				return (((sign) ? '' : '-') + '£' + number + '.' + pence);
			}
		});
	}
}

var searchQuery = {
	// Configuration settings.
	// Update if the names of any elements have changed.
	// Alternatively, extend with $(lh.init({form : $('#new-form-name')}));
	config : {
		sale : {
			"50000" : "&pound;50,000",
			"75000" : "&pound;75,000",
			"100000" : "&pound;100,000",
			"125000" : "&pound;125,000",
			"150000" : "&pound;150,000",
			"175000" : "&pound;175,000",
			"200000" : "&pound;200,000",
			"250000" : "&pound;250,000",
			"300000" : "&pound;300,000",
			"400000" : "&pound;400,000",
			"500000" : "&pound;500,000",
			"750000" : "&pound;750,000",
			"1000000" : "&pound;1,000,000",
			"1500000" : "&pound;1,500,000"
		},

		rent : {
			"250" : "&pound;250",
			"500" : "&pound;500",
			"750" : "&pound;750",
			"1000" : "&pound;1,000",
			"1250" : "&pound;1,250",
			"1500" : "&pound;1,500",
			"2000" : "&pound;2,000"
		},

		form : $('#property-search'),

		text : $('#txtQuickSearch'),

		contactTypeSelect : $('#contract').filter('select'),

		contractTypeRadio : $('#contract-buy'),

		contractTypeHidden : $('#contract').filter($(':hidden')),

		minimumPrice : $('#ddlPayMin'),

		maximumPrice : $('#ddlPayMax'),

		resultsFrame : $('#results-frame')
	},

	// Initialisation function.
	init : function(config) {
		// Extend config with new values.
		(config && typeof(config) == 'object') && $.extend(lh.config, config);

		// Variable declarations from config.
		var form = searchQuery.config.form,
			text = searchQuery.config.text,
			minimumPrice = searchQuery.config.minimumPrice,
			maximumPrice = searchQuery.config.maximumPrice,
			contractTypeSelect = searchQuery.config.contactTypeSelect,
			contractTypeRadio = searchQuery.config.contractTypeRadio,
			contractTypeHidden = searchQuery.config.contractTypeHidden;

		if (form.length) {
			var contracts = [contractTypeSelect, contractTypeRadio, contractTypeHidden];

			// Determine the type of 'contract' field used and react accordingly.
			$.each(contracts, function(index, field) {
				if (field.length) {
					var type = (index == 0) ? "select" : ((index == 1) ? "radios" : "hidden");

					// No need to update prices if there's only one contract type.
					if (type != "hidden") {
						searchQuery.updateCombo(field, type);

						field.change(function() {
							searchQuery.updateCombo(field, type)
						});
					}
				}
			});

			// Clear location box if the value is still placeholder
			// and html5 placeholder is not available.
			form.submit(function() {
				text.val(function(index, value){
					return (value === text.attr('title')) ? '' : value;
				})
			});
		}

		// Update the URL of the search results frame using results
		// from search
		searchQuery.config.resultsFrame.length && searchQuery.getValues();
	},

	// Updates the values in minimum and maximum price select boxes
	// based on whether Buying or Renting is the contract of choice.
	updateCombo : function(contract, type) {
		// Variable declarations from config.
		var	options = '',
			minimumPrice = searchQuery.config.minimumPrice,
			maximumPrice = searchQuery.config.maximumPrice,
			minParent = searchQuery.config.minimumPrice.parent(),
			maxParent = searchQuery.config.maximumPrice.parent(),
			sale = searchQuery.config.sale,
			rent = searchQuery.config.rent,
			values = (type == 'select') ? (values = (contract.val() == 'buying') ? sale : rent) : (values = (contract.filter('input:checked').val() == 'buying') ? sale : rent);

		// To keep values neat & readable, create options here
		$.each(values, function(value, text) {
			options += '<option value="'+value+'">'+text+'</option>';
		});

		var prices = [minimumPrice, maximumPrice];
		$.each(prices, function(key,value){
			// Detach DOM node for faster manipulation.
			value.empty().detach();

			(key == 0) ? value.append('<option value="0">Min Price</option>') : value.append('<option value="0">Max Price</option>');

			value.append(options).val('0');
		});

		// Append back to the DOM
		minParent.append(minimumPrice);
		maxParent.append(maximumPrice);
	},

	// Retrieve the values from the URL submitted by the search form
	// and submit them to the search system. Add any additionally
	// required fields to this list.
	getValues : function() {
		var allVars = $.getUrlVars(),
			chainID = allVars["chainID"],
			txtQuickSearch = allVars["txtQuickSearch"],
			contract = allVars["contract"],
			ddlBedrooms = allVars["ddlBedrooms"],
			ddlPayMin = allVars["ddlPayMin"],
			ddlPayMax = allVars["ddlPayMax"],
			ddlResultsOrder = allVars["ddlResultsOrder"],
			countries = allVars["countries"],
			resultsFrame = searchQuery.config.resultsFrame,
			quickSearchBox = $('#txtQuickSearch');

		txtQuickSearch = (txtQuickSearch.replace(/\+/g,' ').replace(/%2C/g,',') == quickSearchBox.attr('placeholder')) ? '' : txtQuickSearch;

		// Only update values if a search has been performed -
		// ignores pages with set results.
		if ($.type(chainID) != "undefined") {
			resultsFrame.attr('src', function(index, value) {
				return 'http://search.harryclarkeantrim.co.uk/resultslite.aspx?chainID='+chainID+'&Contract='+contract+'&ddlBedrooms='+ddlBedrooms+'&ddlPayMin='+ddlPayMin+'&ddlPayMax='+ddlPayMax+'&txtQuicksearch='+txtQuickSearch+'&ddlResultsOrder='+ddlResultsOrder+'&countries='+countries
			});
		}
	}
}

// Initialise
$(lh.init());

