var Toyota = window.Toyota || {};

// Custom validator function
$.validator.addMethod('notInThePast', function() {
	var month = $('#month').fieldValue()[0];
	var year = $('#year').fieldValue()[0];
	if (year && month) {
		year = parseInt(year, 10);
		month = parseInt(month, 10);
		if (Toyota.monthCalc.inThePast(year, month)) {
			return false;
		}
	}
	return true;
}, 'Please pick a date not in the past');

/*
Our single point of truth concerning which feels are required is a hidden input
field on the page with name="mandatoryFields". The jQuery validation logic 
checks this field, which is a comma separated list of values. Other functions
are provided to add and remove fields from the list.
*/
Toyota.mandatory = (function() {
	var _input = false;
	function getInput() {
		// Lazy load
		if (!_input) {
			_input = $('input[name="mandatoryFields"]').get(0);
		}
		return _input;
	}
	return {
		'includes': function(name) {
			var tokens = getInput().value.split(',');
			return $.grep(tokens, function(item) {
				return item == name;
			}).length > 0;
		},
		'add': function(name) {
			Toyota.mandatory.remove(name);
			var input = getInput();
			var tokens = $.grep(input.value.split(','), function(item) {
				return !!item;
			});
			tokens[tokens.length] = name;
			input.value = tokens.join(',');
		},
		'remove': function(name) {
			//alert($('input[name="mandatoryFields"]').attr("value")+' '+name);
			var input = getInput();
			if(input.value) {
				input.value = $.grep(input.value.split(','), function(item) {
					return item && item != name;
				}).join(',');
			}
		},
		'makeTest': function(name) {
			// Returns a function that checks if 'name' is required or not
			return function() {
				return Toyota.mandatory.includes(name);
			}
		}
	}
})();

/*
Set up fields that are required depending on whether or not they are included in
mandatoryFields input box like this:

$('#someform').validate({
	...
	rules: {
		dealerChoice: {
			required: Toyota.mandatory.makeTest('dealerChoice')
		},
	...
	}
})
*/

Toyota.showPurchaseDateError = function() {
	$('label[class="error"][for="year"][generated="true"]').hide();
	$('label#validDate').show();
}
Toyota.hidePurchaseDateError = function() {
	$('label[class="error"][for="year"][generated="true"]').hide();
	$('label#validDate').hide();
}


Toyota.setupDealerContact = function() {
	/* Many forms include a section for asking a dealer to contact you 
	(if you intend to buy a car within the next six months). This function
	sets up the relevant form behaviour.
	*/	
	
	// Set the year options to this year and this year+1
	Toyota.populateYearSelect('#year');
	
	/* initially hide the "do you want a dealer to contact you" and the contact details and select deler, 
	also reset the month year to be blank and uncheck the more than 18 months */
	Toyota.hideContactMe();
	Toyota.hideSelectDealer();
	Toyota.resetDate();
	Toyota.uncheck18months();
	
	/*
	We use custom events to manage the complex business logic behind the form.
		purchaseDate-inThePast
		purchaseDate-withinSixMonths
		purchaseDate-inMoreThanSixMonths
		
		purchaseDate-18month-checked
		purchaseDate-18month-unchecked
		
		dealerContact-yes
		dealerContact-no
	*/
	$(document).bind('purchaseDate-inThePast', function() {
		// This is an error
		//Toyota.hideContactMe();
		//Toyota.hideSelectDealer();
		//Toyota.showPurchaseDateError();
		Toyota.uncheck18months();
	});
	$(document).bind('purchaseDate-withinSixMonths', function() {
		// OK, ask obout dealer contact
		Toyota.showContactMe();
		//Toyota.hideSelectDealer();
		Toyota.uncheck18months();
		//Toyota.hidePurchaseDateError();
	});
	$(document).bind('purchaseDate-inMoreThanSixMonths', function() {
		// OK, no need for dealer contact
		//Toyota.hideContactMe();
		//Toyota.hideSelectDealer();
		Toyota.uncheck18months();
		//Toyota.hidePurchaseDateError();
	});
	
	$(document).bind('purchaseDate-18month-checked', function() {
		// OK, no need for dealer contact
		//Toyota.hideContactMe();

		//Toyota.hideSelectDealer();
		Toyota.resetDate();
		//Toyota.hidePurchaseDateError();
	});
	$(document).bind('purchaseDate-18month-unchecked', function() {
		Toyota.resetDate();
	});
	
	$(document).bind('dealerContact-yes', function() {
		// Display the dealer block
		$('#postcode2').attr("value", "");
		$('#dealerSuburb2').attr("value", "");
		$('#dealerName2').attr("value", "");
		$('.dealerSearch-Results .error').hide();
		$('.ajaxlist').hide();
		Toyota.showSelectDealer();
		
	});
	$(document).bind('dealerContact-no', function() {
		// Hide the dealer block
		Toyota.hideSelectDealer();
	});

	// Now we set up the browser events that cause our custom events to fire
	$("#purchaseWhen").click(function() {
		// Using click instead of change because in IE change doesn't fire until
		// the focus moves away from the element. click appears to be keyboard 
		// accessible as well.
		if ($("#purchaseWhen").attr('checked')) {
			$(document).trigger('purchaseDate-18month-checked');
			Toyota.mandatory.add('purchaseWhen');
			Toyota.mandatory.remove('year');
			Toyota.mandatory.remove('month');
		} else {
			$(document).trigger('purchaseDate-18month-unchecked');
			Toyota.mandatory.remove('purchaseWhen');
			Toyota.mandatory.add('year');
			Toyota.mandatory.add('month');
		}
	});
	
	$("#year").change(function() {
			$('#purchaseWhen').attr('checked', false);					   
	});
	
	
	$("#month").change(function() {
			$('#purchaseWhen').attr('checked', false);					   					   
	});
	
	// Date selection events
	function shallWeFireDateEvent() {
		// Date selection event only fires if dropdowns are both NOT default
		var month = $('#month').fieldValue()[0];
		var year = $('#year').fieldValue()[0];
		if (year && month) {
			year = parseInt(year, 10);
			month = parseInt(month, 10);
			if (Toyota.monthCalc.withinNextSixMonths(year, month)) {
				$(document).trigger('purchaseDate-withinSixMonths');
			} else if (Toyota.monthCalc.inThePast(year, month)) {
				$(document).trigger('purchaseDate-inThePast');
			} else {
				$(document).trigger('purchaseDate-inMoreThanSixMonths');
			}
		} else {
			// month or year are now default, call the generic reset event
			$(document).trigger('purchaseDate-inMoreThanSixMonths');
		}
	}
	$('#month').change(shallWeFireDateEvent);
	$('#year').change(shallWeFireDateEvent);
	
	function dealerContactYesNo() {
		var value = $('input[name="dealerContact"]').fieldValue()[0];
		if (value == 'true') {
			$(document).trigger('dealerContact-yes');
		} else {
			$(document).trigger('dealerContact-no');
		}
	}
	$('input[name="dealerContact"]').click(dealerContactYesNo);
}

Toyota.populateYearSelect = function(el) {
	// Sets the options in a select box to the current year + numYears
	$(el).empty(); // Empty the select box
	var select = $(el).get(0);
	
	var fromDate = new Date();
	var toDate = new Date();
	toDate.setMonth( toDate.getMonth() + 18 );
	
	var ear = (new Date()).getFullYear();
	if(select.options){
		// First option should be 'Year'
		select.options[0] = new Option('Year', '');
		for (var y = fromDate.getFullYear(); y <= toDate.getFullYear(); y++) {
			// IE doesn't let you add options using DOM appendChild
			select.options[select.options.length] = new Option(y, y);
		}
	}
};


/* The "Would you like a dealer to contact you?" block (div.dealerContact) */
Toyota.hideContactMe = function() {
	
	// Reset to "no"
	$('#dealerContactYes').attr('checked', false);
	$('#dealerContactNo').attr('checked', true);
	
	// hide the container
	$("div.dealerContact").hide();
	
	// No longer mandatory
	Toyota.mandatory.remove('dealerContact');
	$('#dealerContact').attr('isVisible', 0);
}
Toyota.showContactMe = function() {
	// Show the container
	$("div.dealerContact").show();
	
	// add mandatory
	Toyota.mandatory.add('dealerContact');
	$('#dealerContact').attr('isVisible', 1);
}

/* Dealer contact is the contact method and the select dealer containers with the tip */
Toyota.hideSelectDealer = function() {
	// Reset to blank
	$('#postcode2').attr('value', '');
	$('#suburb').attr('value', '');
	$('#dealername').attr('value', '');
	// not resetting which dealer to contact them

	// Add flags so validation can easily tell if they are visible or not
	$('#postcode2').attr('isVisible', 0);
	$('#suburb').attr('isVisible', 0);
	$('#dealername').attr('isVisible', 0);

	//Toyota.mandatory.remove('postcode2');
	//Toyota.mandatory.remove('dealerSuburb2');
	//Toyota.mandatory.remove('dealerName2');
	//Toyota.mandatory.remove('dealerChoice');
	
	// hide the containers
	$("div.selectdealer").hide();
	$("p.columnTip").hide();
	$("div.contactMethod").hide();
}

Toyota.showSelectDealer = function() {
	// show the containers
	$("div.selectdealer").show();
	$("p.columnTip").show();
	$("div.contactMethod").show();
	
	// make these fields mandatory
	$('#postcode2').attr('isVisible', 1);
	$('#dealerSuburb2').attr('isVisible', 1);
	$('#dealerName2').attr('isVisible', 1);

	//Toyota.mandatory.add('postcode2');
	//Toyota.mandatory.add('dealerSuburb2');
	//Toyota.mandatory.add('dealerName2');
	//Toyota.mandatory.add('dealerChoice');
}

/* Reset month and year of dropdown */
Toyota.resetDate = function() {
	$("option:first", "select#month").attr("selected", "selected");
	$("option:first", "select#year").attr("selected", "selected");  
}

Toyota.uncheck18months = function() {
	$('#morethan18months').attr('checked', false);
}

Toyota.monthCalc = (function() {
	function monthDiff(year1, month1, year2, month2) {
		// Expects months to be base 0
		return ((year1 * 12) + month1) - ((year2 * 12) + month2);
	}
	return {
		withinNextSixMonths: function(year, month) {
			// For month, 1 = January
			// Returns true if year/month is within 6 months of now, inclusive
			// i.e. if we are in June, anything up to/including December is OK
			month = month - 1; // base 0
			var today = new Date();
			var diff = monthDiff(
				year, month,
				today.getFullYear(), today.getMonth()
			);
			return (diff >= 0) && (diff <= 6);
		},
		inThePast: function(year, month) {
			month = month - 1; // base 0
			var today = new Date();
			var diff = monthDiff(
				year, month,
				today.getFullYear(), today.getMonth()
			);
			return diff < 0; 
		}
	}
})();

// Following code copied from jquery.form.js plugin
jQuery.fn.fieldValue = function(successful) {
    for (var val=[], i=0, max=this.length; i < max; i++) {
        var el = this[i];
        var v = jQuery.fieldValue(el, successful);
        if (v === null || typeof v == 'undefined' || (v.constructor == Array && !v.length))
            continue;
        v.constructor == Array ? jQuery.merge(val, v) : val.push(v);
    }
    return val;
};

jQuery.fieldValue = function(el, successful) {
    var n = el.name, t = el.type, tag = el.tagName.toLowerCase();
    if (typeof successful == 'undefined') successful = true;

    if (successful && (!n || el.disabled || t == 'reset' || t == 'button' ||
        (t == 'checkbox' || t == 'radio') && !el.checked ||
        (t == 'submit' || t == 'image') && el.form && el.form.clk != el ||
        tag == 'select' && el.selectedIndex == -1))
            return null;

    if (tag == 'select') {
        var index = el.selectedIndex;
        if (index < 0) return null;
        var a = [], ops = el.options;
        var one = (t == 'select-one');
        var max = (one ? index+1 : ops.length);
        for(var i=(one ? index : 0); i < max; i++) {
            var op = ops[i];
            if (op.selected) {
                // extra pain for IE...
                var v = jQuery.browser.msie && !(op.attributes['value'].specified) ? op.text : op.value;
                if (one) return v;
                a.push(v);
            }
        }
        return a;
    }
    return el.value;
};

