/**
*	File: hills_ford.js
*
*	Author: Matthew Lindley, GForces Web Management: www.gforces.co.uk
*	Purpose: House most of the custom javascript for the Hills Ford website
*
*/


/**
*	Stuff we always want to do onload
*/

document.observe( 'dom:loaded', function () {

	autoSearchTabs.init();

	modelSearch.init();
	budgetSearch.init();
	lifestyleSearch.init();

});


/****************************************
*	Global stuff
****************************************/
Element.addMethods( 'SELECT', {

	addOption: function ( el, text, value, index ) {
		index = index || $(el).options.length;
		$(el).options[ index ] = new Option( text, value );
		return el;
	},

	empty: function ( el, offset ) {
		offset = parseInt( offset ) || 0;
		while ( el.options.length > offset ) {
			el.options[ el.options.length - 1 ] = null;
		}
		return el;
	},

	populate: function ( el, options ) {
		options.data.each( function ( option ) {
			option = $H( option );
			$(el).addOption( option.get( options.textName ), option.get( options.valueName ) );
		});
	}

});


/****************************************
*	Auto search tabs
****************************************/

var autoSearchTabs = {

	divSearchTabs:		'usedSearchTabs',
	divWrapperClass:	'autoSearch',

	init: function () {

		//  Check the tabs are in the document else bomb out to stop errors if it's hidden for any reason
		if ( !$('usedSearchTabs') ) {
			return;
		}

		/****************************************
		*	Tab setup
		****************************************/

		//  Function which will be executed when the tabs are clicked
		var setupTabs = function ( ev ) {

			Event.stop( ev );		//  Stop link working

			el = ev.element();		//  Reference link

			/**  Hiding and unsetting  **/
			el.siblings().invoke( 'removeClassName', 'active' );	//  Remove "active" class from the other tabs
			$$('div.' + this.divWrapperClass ).invoke( 'hide' );					//  Hide forms

			/**  Showing  **/
			el.addClassName( 'active' );							//  Add "active" class to the current
			$$('div.' + this.divWrapperClass)[ el.previousSiblings().length ].show();		//  Show form by matching the position of the link to the form's enumerable index

		}.bind( this );

		//  Apply function to tabs
		$$('#' + this.divSearchTabs + ' a').invoke( 'observe', 'click', setupTabs );		//  Make the tabs work

	}

}


/****************************************
*	Model search
****************************************/

var modelSearch = {

	divCarImages: 		'carGroups',
	modelSearchMarque: 	'marqueDetailId',
	modelSearchModel: 	'model',

	init: function () {

	    //  Toggle actions for vehicle pictures
		$$('#' + this.divCarImages + ' a').invoke( 'observe', 'click', function ( ev ) {

			Event.stop( ev );		//  Stop link working

			el = ev.element();		//  Reference element
			el.toggleClassName( 'active' );		//  Add/remove active class

			this.filterMarques();

		}.bind( this ) );

		$(this.modelSearchMarque).observe( 'change', this.filterModels.bind( this ) );

	},

	filterMarques: function () {

		//  Empty existing marques and models
		$(this.modelSearchMarque).empty( 1 );
		$(this.modelSearchModel).empty( 1 );
		$('quickSearch').value = '';

		//  Function to process the marques when they come back
		var processMarques = function ( r ) {
			$(this.modelSearchMarque).populate({
				data: r.responseText.evalJSON(),
				textName: 'marque_name',
				valueName: 'id'
			});
		}.bind( this );

		//  Get marques and process them
		new Ajax.Request( baseHref + 'ajax.php', {
			method: 	'post',
			parameters: 'type=modelSearchFilterMarques&carTypes=' + this.getCarTypes(),
			onSuccess: 	processMarques
		});

	},

	filterModels: function () {

		//  Empty existing marques
		$(this.modelSearchModel).empty( 1 );
		$('quickSearch').value = '';

		//  Function to process the marques when they come back
		var processModels = function ( r ) {
			$(this.modelSearchModel).populate({
				data: r.responseText.evalJSON(),
				textName: 'model',
				valueName: 'model'
			});
		}.bind( this );

		//  Get marques and process them
		new Ajax.Request( baseHref + 'ajax.php', {
			method: 	'post',
			parameters: 'type=modelSearchFilterModels&marqueDetailId=' + $F( this.modelSearchMarque ) + '&carTypes=' + this.getCarTypes(),
			onSuccess: 	processModels
		});

	},

	getCarTypes: function () {

		//  Get the rel property of all car image links with the class active
		return $$('#' + this.divCarImages + ' a').findAll( function ( el ) {
			return el.hasClassName( 'active' );
		}).pluck( 'rel' ).join( ',' );

	}

}


/****************************************
*	Budget search
****************************************/

var budgetSearch = {

	init: function ( options ) {

		this.options 		= options || {};
		this.options.apr	= this.options.apr || 5;


		/*****  Straight budget search  *****/

		$('formBudgetSearchBudget').observe( 'submit', function ( ev ) {

			//  Check a value is selected
			if ( $F('selectBudget') == '' ) {
				Event.stop( ev );						//  Stop form submission
				alert( 'Please select a budget' );		//  Display error
			}

		});

		/*****  Calculated budget search  *****/

		this.calc = {
			budget:		0,
			interest:	0		//  Not currently used for now, but just in case...
		}

    	this.fields = {
			budget:		$('budgetSearchBudget'),
			deposit: 	$('budgetSearchDeposit'),
			payment: 	$('budgetSearchMonthlyPayments'),
			term:		$('budgetSearchTerm')
		};

		this.submitButton = $('btnOptionSearch');


		//  Disable the submit button by default
		this.disableSubmit();

		//  Monitor changes
		this.getFields().invoke( 'observe', 'change', this.calculate.bind( this ) );

		//  Calculate by default
		this.calculate();

	},


	calculate: function () {

		//  Do nothing if any dropdown has nothing selected
		if ( this.getFields().pluck( 'selectedIndex' ).indexOf( 0 ) > -1 ) {
			this.disableSubmit();
			return;
		}

		//  Budget starts with the deposit
		this.calc.budget = parseInt( $F( this.fields.deposit ) );

		//  Loop years
		$R( 1, $F( this.fields.term ) ).each( function ( num, index ) {

			//  Subtract the annual
			this.calc.budget += ( parseInt( $F( this.fields.payment ) ) * 12 ) / parseFloat( 1 - ( this.options.apr / 100 ) );

		}.bind( this ));

		$(this.fields.budget).value = parseInt( this.calc.budget );

		//  Enable form submission
		this.enableSubmit();

	},


	disableSubmit: function () {
		this.submitButton.disable().setOpacity( 0.2 );
	},


	enableSubmit: function () {
		this.submitButton.enable().setOpacity( 1 );
	},


	getFields: function () {
		return Object.values( this.fields ).findAll( function ( el ) {
		   return ( el.type.toLowerCase() == 'select-one' );
		});
	}

}


/****************************************
*	Lifestyle search
****************************************/

var lifestyleSearch = {

	activeColour: 	'#3296b8',
	inactiveColour: '#767676',

	minSelect: 1,

	init: function () {

		//  Loop checkboxes
		$$('#lifeStyleSearch input[type=checkbox]').each( function ( el ) {

			el.identify();								//  Set an ID
			el.next(0).writeAttribute( 'for', el.id );	//  Link label to the checkbox	(note: element.for = '' ... doesn't work!)

			//  Set text colour on click/change
			el.observe( 'click', function ( ev ) {
				this.changeColour( el );
			}.bind( this ));

			//  Change colour if needs be
			this.changeColour( el );

		}.bind( this ));

		//  Monitor form too
		$('formLifestyleSearch').observe( 'submit', function ( ev ) {

			//  Count number of checked checkboxes
			if ( $$('#lifeStyleSearch input[type=checkbox]').findAll( function ( el ) {
				return el.checked;
			}).length < this.minSelect ) {
				Event.stop( ev );
				alert( 'Please select ' + this.minSelect + ' or more options' );
			}

		}.bind( this ));

	},


	changeColour: function ( el ) {
		el.next(0).setStyle({
			color: ( ( el.checked ) ? this.activeColour : this.inactiveColour )
		});
	}

}


/****************************************
*	Carousels
****************************************/

var carousel = {

	/*****  Configurable bits  *****/

	divImagesClass: 'homeJumpImages',	//  Wrapper div of the images
	aLeftClass: 	'homeJumpLeft',		//  <a> tag around the left arrow
	aRightClass: 	'homeJumpRight',	//  <a> tag around the right arrow


	/*****  Don't edit below here! *****/

	isMoving: 		false,
	div:			false,
	divPadding:		10,

	init: function () {

		//  First things first, set the width of the divs containing the images
		//  This could probably be done with invoke but done under each for flexibility
		$$('div.' + this.divImagesClass).each( function ( div ) {

			//  Work out the total width ( width of first image * number of images )
			var totalWidth 	= $(div).down(0).childElements()[1].getWidth() * $(div).down(0).childElements().length;

			//  Set width
			$(div).setStyle({
				width: ( totalWidth + this.divPadding ) + 'px'
			});

		}.bind( this ));



		/*****  Move left  *****/

		$$('a.' + this.aLeftClass ).invoke( 'observe', 'click', function ( ev ) {

			Event.stop( ev );		//  Stop <a> tag working
			el = ev.element();		//  Reference element

			this.setImageDiv( el );

			//  If [at last image]
			if ( this.atFirstImage() ) {
				this.goLast();
			} else {
				this.goPrevious();
			}

		}.bind( this ) );


		/*****  Move right  *****/

		$$('a.' + this.aRightClass ).invoke( 'observe', 'click', function ( ev ) {

			Event.stop( ev );		//  Stop <a> tag working
			el = ev.element();		//  Reference element

			this.setImageDiv( el );		//  Define the image div

			//  If [at last image]
			if ( this.atLastImage() ) {
				this.goFirst();
			} else {
				this.goNext();
			}

		}.bind( this ) );

	},

	atFirstImage: function () {
		return ( this.getOffset() === 0 );
	},

	atLastImage: function () {
		return ( this.getOffset() == -( this.getImageDivWidth() - this.getImagesWidths() ) );
	},

	getImageDivWidth: function () {
		return $( this.imageDiv ).getWidth() - this.divPadding;
	},

	getImagesWidths: function () {
		return $(this.imageDiv).down(0).childElements()[0].getWidth();
	},

	getNumImages: function () {
		return this.getImageDivWidth() / this.getImagesWidths();
	},

	getOffset: function () {
		return parseInt( $( this.imageDiv ).getStyle( 'left' ).replace( /px$/, '' ) );
	},

	/***  Go functions  *****/

	goFirst: function () {
		this.slide( 0, 0.75 );
	},

	goLast: function () {
		this.slide( -( this.getImageDivWidth() - this.getImagesWidths() ), 0.75 );
	},

	goNext: function () {
		this.slide( this.getOffset()-this.getImagesWidths(), 0.5 );
	},

	goPrevious: function () {
		this.slide( this.getOffset()+this.getImagesWidths(), 0.5 );
	},

	/***********************/

	setImageDiv: function ( el ) {
		this.imageDiv = $(el).up(0).siblings().find( function ( tag ) {
			return tag.hasClassName( this.divImagesClass );
		}.bind( this ));
	},

	slide: function ( offset, duration ) {

		if ( this.isMoving ) {
			return;
		}

		this.isMoving = true;

		new Effect.Move( $(this.imageDiv), { x: offset, mode:'absolute', duration:duration,
			afterFinish: function () {
				this.isMoving = false;
			}.bind( this )
		});

	}

}


/**
*	Favourites list
*/
var favouritesList = {

	save: function ( carId ) {

		if ( !/^\d+$/.test( carId ) ) {
			return false;
		}

		new Ajax.Request( baseHref + 'ajax.php', {
			method: 'post',
			parameters: 'type=addToFavourites&id=' + carId,
			onSuccess: function ( t ) {

				r = t.responseText.evalJSON();

				if ( r.error ) {
					alert( r.msg );
					return false;
				}

				v = r.vehicle;		//  Reference vehicle

				var url		= baseHref + v.site_folder + '/used-cars/view/' + v.id + '/' + v.linkHeading;	//  Target URL
				var link 	= new Element( 'a', { href: url } );											//  Create link + url

				if ( typeof v.image_src == 'undefined' ) {
					var image = new Element( 'img', { src: baseHref + 'images/layup/noImage195x146.jpg', width: '54', height: '41' } );
				} else {
					var image = new Element( 'img', { src: baseHref + 'images/global_auto/thumbs/' + v.image_src, width: '54', height: '41' } );
				}


				//  Get first thumb without any <a> tag inside
				$$('div.thumbnail').find( function ( div ) {
					return ( div.cleanWhitespace().empty() );
				})
					.insert( {top:image} )					//  Insert image of car at the start of the link to make it clickable
					.observe( 'click', function ( ev ) {	//  Monitor image onclick for IE
						Event.stop( ev );
						document.location = url;
					});

				alert( r.msg );

			}
		});

	}

}


/****************************************
*	Vehicle pager
****************************************/

var vehiclePager = {

	currentIndex: 0,


	init: function ( element, options ) {

		//  Arguments
		this.element 		= $( element );

		this.options 		= options || {};
		this.options.delay 	= options.delay || 4;

		//  Elements to manipulate
		this.numbers	= $$( '#' + this.element.id + ' div.featuredPages a' );
		this.pages 		= $$( '#' + this.element.id + ' div.featuredItem' );

		//  Timer
		this.timer = new PeriodicalExecuter( this.goNext.bind( this ), this.options.delay );

		//  Click events for the numbers
		this.numbers.invoke( 'observe', 'click', this.numberClick.bind( this ) );

	},


	goNext: function () {

		//  Hide current page
		this.hidePage( this.currentIndex );

		//  Go to next page
		this.currentIndex++;

		//  Gone too far?
		if ( this.currentIndex >= this.numbers.length ) {
			this.currentIndex = 0;
		}

		//  Show new page
		this.showPage( this.currentIndex );

	},


	goPage: function ( index ) {

		this.stopTimer();

		return false;

	},


	hidePage: function ( index ) {

		this.numbers[ index ].removeClassName( 'active' );
		this.pages[ index ].hide();

	},


	numberClick: function ( ev ) {

		Event.stop( ev );

		el = ev.element();

		if ( el.tagName.toLowerCase() != 'a' ) {
			el = el.up(0);
		}

		this.stopTimer();

		this.hidePage( this.currentIndex );

		this.currentIndex = el.previousSiblings().length;

		this.showPage( this.currentIndex );

	},


	showPage: function ( index ) {
		this.numbers[ index ].addClassName( 'active' );
		this.pages[ index ].show();
	},


	stopTimer: function () {

		if ( this.timer !== false ) {
			this.timer.stop();
			this.timer = false;
		}

	}

}


/****************************************
*	News pager
****************************************/

var newsPager = {

	currentIndex: 0,

	init: function ( element ) {

		this.pages = $$( '#' + $(element).id + ' div.newsItem' );

		$('newsGoBack').observe( 'click', function ( ev ) {

			Event.stop( ev );

			this.goBack();

		}.bind( this ));


		$('newsGoNext').observe( 'click', function ( ev ) {

			Event.stop( ev );

			this.goNext();

		}.bind( this ));


	},


	goBack: function () {

		this.pages[ this.currentIndex ].hide();

		if ( this.currentIndex == 0 ) {
			this.currentIndex = this.pages.length - 1;
		} else {
			this.currentIndex--;
		}

		this.pages[ this.currentIndex ].show();

		$('newsCurrentItem').update( this.currentIndex + 1 );

	},


	goNext: function () {

		this.pages[ this.currentIndex ].hide();

		if ( this.currentIndex == this.pages.length - 1 ) {
			this.currentIndex = 0;
		} else {
			this.currentIndex++;
		}

		this.pages[ this.currentIndex ].show();

		$('newsCurrentItem').update( this.currentIndex + 1 );

	}
}


/**
*  Vertical stripe
*/
verticalStripe = {

	offset: 0,

	init: function ( table, options ) {

		options 		= options || {}
		this.offset 	= options.offset || this.offset;

		$$( 'tbody tr', table ).each( function ( row ) {

			$( row ).childElements().each( function ( cell, index ) {
				if ( ( index >= this.offset ) && ( index > 0 ) && ( index % 2 == 0 ) ) {
					cell.addClassName( 'trAlt' );
		   		}
			}.bind( this ));

		}.bind( this ));

	}

}