/**
 * Bootstrap.js - Bootstrap for all Javascript functionality
 * 
 * @author  Webstores <info at webstores dot nl>
 *           Copyright (c) Webstores internet totaalbureau <http://www.webstores.nl/>
 */

document.observe('dom:loaded', function() {
	
	// External links
	$$('a[rel="external"]').each(function(el) {
		el.target = '_blank';
	});
	
	// Toggle input values
	$$('.toggle-value').each(function(el) {
		var v = el.value;
		el.observe('focus', function() {
			if(this.value == v) {
				this.value = '';
			}
			this.addClassName('focus');
		});
		el.observe('blur', function() {
			if(this.value == '') {
				this.value = v;
				this.removeClassName('focus');
			}
		});
	});
	
	// IE6 hover
	if(/msie 6/i.test(navigator.userAgent)) {
		$$('#navigation li').each(function(el) {
			el.observe('mouseover', function() {
				this.addClassName('iehover');
			});
			el.observe('mouseout', function() {
				el.removeClassName('iehover');
			});
		});
	}
	
	// Accordions
	$$('.accordion').each(function(el) {
		if (el.parentNode.id != 'dealers-results') {
			new Accordion(el);
		}
	});
	
	// Tabs
	$$('.tabs').each(function(el) {
		if(el.parentNode.id != 'category-spotlight' && el.parentNode.id != 'catalog-header') {
			new Tabs(el);
		}
	});
	
	// Category spotlight tabs
	var csTabs = new Tabs('category-spotlight-tabs', {
		listener: 'mouseover',
		onAfterTabChange: function(tab) {
			$$('#category-thumbs .selected')[0].removeClassName('selected');
			$$('#category-thumbs .category-thumb')[$$('#category-spotlight-tabs li').indexOf(tab.parentNode)].addClassName('selected');
			Cufon.replace('#category-spotlight-tabs a', { fontFamily: 'OfficinaSansStd' });
		}
	});
	
	var csThumbs = $$('.category-thumb');
	if(csThumbs.length && $('category-spotlight-tabs')) {
		var csTimeout = null;
		csThumbs.invoke('observe', 'mouseover', function(e) {
			var index = csThumbs.indexOf(this);
			csTimeout = setTimeout(function() {
				csTabs.setActiveByIndex(index);
			}, 250);
		});
		csThumbs.invoke('observe', 'mouseout', function(e) {
			if(csTimeout) {
				clearTimeout(csTimeout);
				csTimeout = null;
			}
		});
	}
	
	// Product tabs
	var pTabs = new Tabs('product-tabs');
	$$('.related-tabs a').invoke('observe', 'click', function(e) {
		e.stop();
		pTabs.setActiveByHash('#' + this.href.split('#')[1]);
	});
	
	// Dealer search
	if($('dealer-search')) {
		$('dealer-search').observe('submit', function(e) {
			if(this.zip.value != '1234AB' && /^[0-9]{4}[\ ]?[a-zA-Z]{2}$/.test(this.zip.value)) {
				this.zip.removeClassName('wsv-error');
			}
			else {
				e.stop();
				this.zip.addClassName('wsv-error');
			}
		});
	}
	
	// Galleries
	buildGallery('product-gallery', '/medium_3/', '/');
	buildGallery('actie-gallery', '/medium/', '/colorbox/');
	
	// Make table rows clickable and hoverable
	rowClick();
	rowHover();
	
	// Validation
	if($('generated-form')) {
		var validation = new Validation('generated-form');
	}
	if($('subscribe')) {
		var subscribeValidation = new Validation('subscribe');
	}
	if($('vacancy-form')) {
		var vacancyValidation = new Validation('vacancy-form');
	}
	if($('newsletter-form')) {
		var vacancyValidation = new Validation('newsletter-form');
	}
	
	// Initialize Shadowbox
	if(typeof Shadowbox != 'undefined') {
		Shadowbox.init({
			overlayOpacity: 0.8
		});
	}
});


/**
 * Make table rows clickable
 */
function rowClick() {
	$$('.tclick').each(function(table) {
		$A(table.rows).each(function(row) {
			var anchor = $(row).down('a');
			if(anchor) {
				row.observe('click', function() {
					window.location.href = anchor.href;
				});
				row.title = anchor.title;
			}
		});
	});
};


/**
 * Give table rows a hover state
 */
function rowHover() {
	$$('.thover').each(function(table) {
		$A(table.rows).each(function(row) {
			if($(row).select('th').length <= 1) {
				row.observe('mouseover', function() {
					this.addClassName('hover');
				});
				row.observe('mouseout', function() {
					this.removeClassName('hover');
				});
			}
		});
	});
};


/**
 * Image gallery factory method
 * 
 * @param {String} id The ID of the element
 * @param {String} mDir The medium image directory
 * @param {String} oDir The original image directory
 */
function buildGallery(id, mDir, oDir) {
	if($(id)) {
		var galleryCarousel = new Carousel('gallery-thumbs-scroller', $$('#gallery-thumbs-scroller .thumb'), $$('#gallery-thumbs a.carousel-control'), {
			duration: 0.5
		});
		
		$$('#gallery-thumbs .thumb').invoke('observe', 'click', function(e) {
			e.stop();
			
			//$('main-image').observe('load', function() {});
			
			$$('#gallery-thumbs-content .selected')[0].removeClassName('selected');
			this.addClassName('selected');
			
			$('main-image').src = this.href;
			$('main-image-link').href = this.href.replace(mDir, oDir);
			$('main-image-link').title = this.title;
			$('gallery-caption').innerHTML = this.title;
			
			Shadowbox.setup($('main-image-link'));
		});
	}
}


/**
 * Tabs.js - Tab that content!
 * 
 * @author Webstores <info at webstores dot nl>
 *         Copyright (c) Webstores internet totaalbureau <http://www.webstores.nl/>
 * 
 * @param {String} el The ID of the element containing the tabs
 * @param {Object} options Optional parameters
 */
function Tabs(id, options) {
	this.containerId = id;
	this.container = null;
	this.options = options;
	this.activeTab = null;
	this.timeout = null;
	
	this.listener = 'click';
	this.selectedClass = 'selected';
	this.onBeforeTabChange = 'undefined';
	this.onAfterTabChange = 'undefined';
	
	this.init();
};

Tabs.prototype = {
	init: function() {
		this.container = $(this.containerId);
		if(this.container) {
			if(typeof this.options != 'undefined') {
				for(prop in this.options) {
					this[prop] = this.options[prop];
				}
			}
			
			var self = this;
			var hash = window.location.hash.split('#')[1];
			
			this.container.select('a').each(function(el) {
				var id = el.href.split('#')[1];
				
				if($(el.parentNode).hasClassName(self.selectedClass)) {
					self.activeTab = el;
				}
				else if(hash != '' && hash == id) {
					self.setActive(el);
				}
				else {
					$(id).hide();
				}
				
				switch(self.listener) {
					case 'click':
						el.observe(self.listener, function(e) {
							e.stop();
							self.setActive(this);
						});
					break;
					case 'mouseover':
						el.observe(self.listener, function(e) {
							self.timeout = setTimeout(function() {
								self.setActive(el);
							}, 250);
						});
						
						el.observe('mouseout', function(e) {
							if(self.timeout) {
								clearTimeout(self.timeout);
								self.timeout = null;
							}
						});
						
						el.observe('click', function(e) {
							e.stop();
						});
					break;
				}
			});
		}
	},
	setActive: function(tab) {
		if(tab != this.activeTab) {
			if(typeof this.onBeforeTabChange == 'function') {
				this.onBeforeTabChange(tab);
			}
			
			var id = tab.href.split('#')[1];
			var activeId = this.activeTab.href.split('#')[1];
			
			$(activeId).hide();
			this.activeTab.parentNode.removeClassName(this.selectedClass);
			$(id).show();
			tab.parentNode.addClassName(this.selectedClass);
			this.activeTab = tab;
			
			if(typeof this.onAfterTabChange == 'function') {
				this.onAfterTabChange(tab);
			}
		}
	},
	setActiveByHash: function(hash) {
		var anchor = this.container.down('a[href$="' + hash + '"]');
		this.setActive(anchor);
	},
	setActiveByIndex: function(index) {
		this.setActive(this.container.down('li', index).down('a'));
	}
};


/**
 * Accordion, collapse/expand items
 * 
 * @author  Webstores <info at webstores dot nl>
 *           Copyright (c) Webstores internet totaalbureau <http://www.webstores.nl/>
 * 
 * @param {Mixed} el The ID of or reference to the accordion element
 * @param {Object} options Optional parameters
 */
var Accordion = function(el, options) {
	this.el = el;
	this.accordion = null;
	this.hash = '';
	
	// Option defaults
	this.togglerCls = 'toggler';
	this.collapsedCls = 'collapsed';
	this.collapseOnInit = true;
	this.onBeforeExpand = null;
	this.onAfterExpand = null;
	this.onBeforeCollapse = null;
	this.onAfterCollapse = null;
	this.onBeforeToggle = null;
	this.onAfterToggle = null;
	
	if(typeof options != 'undefined') {
		for(prop in options) {
			this[prop] = options[prop];
		}
	}
	
	this.initialize();
};

Accordion.prototype = {
	initialize: function() {
		this.accordion = $(this.el);
		
		if(this.accordion) {
			var self = this;
			var togglers = this.accordion.select('.' + this.togglerCls);
			
			this.hash = window.location.hash.split('#')[1];
			
			togglers.each(function(el) {
				if(self.collapseOnInit) {
					var id = el.href.split('#')[1];
						
					if(self.hash != '' && id == self.hash) {
						self.expand(id);
					}
					else {
						self.collapse(id);
					}
				}
				
				el.observe('click', function(e) {
					Event.stop(e);
					self.toggle(this.href.split('#')[1]);
				});
			});
		}
	},
	isCollapsed: function(id) {
		return $(id).hasClassName(this.collapsedCls);
	},
	expand: function(id) {
		if(typeof this.onBeforeExpand == 'function') {
			this.onBeforeExpand(id);
		}
		
		$(id).removeClassName(this.collapsedCls);
		
		if(typeof this.onAfterExpand == 'function') {
			this.onAfterExpand(id);
		}
	},
	collapse: function(id) {
		if(typeof this.onBeforeCollapse == 'function') {
			this.onBeforeCollapse(id);
		}
		
		$(id).addClassName(this.collapsedCls);
		
		if(typeof this.onAfterCollapse == 'function') {
			this.onAfterCollapse(id);
		}
	},
	toggle: function(id) {
		if(typeof this.onBeforeToggle == 'function') {
			this.onBeforeToggle(id);
		}
		
		this.isCollapsed(id) ? this.expand(id) : this.collapse(id);
		
		if(typeof this.onAfterToggle == 'function') {
			this.onAfterToggle(id);
		}
	}
};


/**
 * DealerSearchForm
 * 
 * @param {Object} form The dealer search form
 * @param {Object} map The Google Maps object
 */
var DealerSearchForm = function(form, map) {
	this.form = form;
	this.map = map;
	this.geocoder = null;
	this.defaultMarkerImage = null;
	this.currentMarkers = null;
	
	this.initialize();
};

DealerSearchForm.prototype = {
	initialize: function() {
		if(this.form) {
			this.ajaxify();
			
			this.geocoder = new google.maps.Geocoder();
			this.defaultMarkerImage = new google.maps.MarkerImage('/img/marker.png', new google.maps.Size(32, 37), new google.maps.Point(0, 0), new google.maps.Point(16, 30));
			this.currentMarkers = [];
		}
	},
	ajaxify: function() {
		var self = this;
			
		this.form.observe('submit', function(e) {
			Event.stop(e);
			
			var zip = this.zip;
			
			if(zip.value != '1234AB' && /^[0-9]{4}[\ ]?[a-zA-Z]{2}$/.test(zip.value)) {
				zip.removeClassName('wsv-error');
				
				$('dealers-search').addClassName('loading');
				
				self.form.request({
					onSuccess: function(response) {
						self.handleResponse(response.responseText);
					}
				});
			}
			else {
				zip.addClassName('wsv-error');
			}
		});
	},
	handleResponse: function(response) {
		var data = response.evalJSON();
		
		this.buildAccordion(data);
		this.placeMarkers(data);
		this.buildTable(data);
		
		$('dealers-search').removeClassName('loading');
	},
	buildAccordion: function(dealers) {
		var html = [];
		var resultsDiv = new Element('div', { id: 'dealers-results' });
		
		html.push('<h2>Resultaten</h2>\n');
		html.push('<p>Klik op een dealer voor meer informatie, of start een <a id="dealers-results-close" href="#" title="Opnieuw naar dealers zoeken">nieuwe zoekopdracht</a>.</p>\n');
		html.push('<ul class="accordion">\n');
		
		for(var i = 0; i < dealers.length; i++) {
			html.push('<li id="result-' + dealers[i].id + '">\n');
			html.push('<h3><a class="toggler" href="#result-' + dealers[i].id + '" title="' + dealers[i].name + '">' + dealers[i].name + '</a></h3>\n');
			html.push('<table cellspacing="0">\n');
			if(dealers[i].branche != ''){ html.push('<tr><th>Branche:</th><td>' + dealers[i].branche + '</td></tr>\n'); }
			html.push('<tr><th>Bezoekadres:</th><td>' + dealers[i].street + '</td></tr>\n');
			html.push('<tr><th>Postcode:</th><td>' + dealers[i].postalcode + '</td></tr>\n');
			html.push('<tr><th>Plaats:</th><td>' + dealers[i].city + '</td></tr>\n');
			if(dealers[i].telephone != ''){ html.push('<tr><th>Telefoonnr:</th><td>' + dealers[i].telephone + '</td></tr>\n'); }
			if(dealers[i].fax != ''){ html.push('<tr><th>Faxnr:</th><td>' + dealers[i].fax + '</td></tr>\n'); }
			if(dealers[i].email != ''){ html.push('<tr><th>E-mail:</th><td><a href="mailto:' + dealers[i].email + '" title="Stuur een e-mail">' + dealers[i].email + '</a></td></tr>\n'); }
			if(dealers[i].website != ''){ html.push('<tr><th>Internet:</th><td><a href="http://' + dealers[i].website + '/" title="Bezoek de website van ' + dealers[i].name + '" rel="external">' + dealers[i].website + '</a></td></tr>\n'); }
			html.push('</table>\n');
			html.push('</li>\n');
		}
			
		html.push('</ul>\n');
		
		resultsDiv.update(html.join(''));
		
		$('dealers-column').appendChild(resultsDiv);
		$('dealers-results-close').observe('click', function(e) {
			e.stop();
			resultsDiv.remove();
		});
		new Accordion($$('#dealers-results .accordion')[0]);
	},
	addMarker: function(title, lat, lng) {
		this.currentMarkers.push(new google.maps.Marker({ position: new google.maps.LatLng(lat, lng), map: this.map, title: title, icon: this.defaultMarkerImage }));
	},
	placeMarkers: function(dealers) {
		this.clearMarkers();
		
		for(var i = 0; i < dealers.length; i++) {
			this.addMarker(dealers[i].name, parseFloat(dealers[i].lat), parseFloat(dealers[i].long));
		}
		
		this.zoomToZip(this.form.zip.value);
	},
	clearMarkers: function() {
		for(var i = 0; i < this.currentMarkers.length; i++) {
			this.currentMarkers[i].setMap(null);
		}
	},
	buildTable: function(dealers) {
		var html = [];
		
		html.push('<table cellspacing="0">\n');
		html.push('<tr><th>Bedrijfsnaam</th><th>Plaatsnaam</th><th>Branche</th><th>Website</th><th>Afstand</th><th>Route</th></tr>\n');
		
		for (var i = 0; i < dealers.length; i++) {
			html.push('<tr>\n');
			html.push('<td class="company-name">' + dealers[i].name + '</td>\n');
			html.push('<td>' + dealers[i].city + '</td>\n');
			if(dealers[i].branche != '') { html.push('<td>' + dealers[i].branche + '</td>\n'); }
			if(dealers[i].website != '') { html.push('<td><a href="http://' + dealers[i].website + '/" title="Bezoek de website van ' + dealers[i].name + '" rel="external">' + dealers[i].website + '</a></td>\n'); }
			html.push('<td>' + dealers[i].distance + ' km</td>\n');
			html.push('<td class="route"><a class="button" href="http://maps.google.nl/maps?saddr=&daddr=' + dealers[i].street + '+' + dealers[i].postalcode + '+' + dealers[i].city + '" title="Route" rel="external"><span class="button-inner">Route</span></a></td>\n');
			html.push('</tr>\n');
		}
		
		html.push('</table>\n');
		
		$('list-view-inner').update(html.join(''));
		
		$$('#list-view-inner a[rel="external"]').each(function(el) {
			el.target = '_blank';
		});
	},
	zoomToZip: function(zip) {
		if(this.geocoder) {
			var self = this;
			this.geocoder.geocode({ address: zip + ' Nederland' }, function(results, status) {
				if(status == google.maps.GeocoderStatus.OK && results.length > 0 && results.length <= 1) {
					self.map.setCenter(results[0].geometry.location);
					self.map.setZoom(9);
				}
				else {
					self.map.setCenter(new google.maps.LatLng(52.132633,5.291266));
					self.map.setZoom(7);
				}
			});
		}
	}
};
