/**
 * ---------------------------
 * Client: Meijers Autobedrijf
 * URL: http://www.meijersautobedrijf.nl
 * Author: Harmen Janssen, Dutch Internet Works
 *
 * ---------------------------
 */

/**
 * General namespace
 */
var meijers = {
	/**
	 * Initialize all objects
	 */
	init: function () {
		for (var i in this) {
			if (typeof this[i].init === 'function') {
				this[i].init ();
			}
		}
	},
	/**
	 * A little trick to guess wether the preferred font is available on the user's computer
	 */
	guessFontAvailability: {
		init: function () {
			// create an element with the desired font family
			var a = What.Element.create ('span',{},['AAA']);
			a.style.fontFamily = 'Copperplate Gothic Light, monospace';
			a.style.fontSize = '100px';
			a.style.visibility = 'hidden';
			document.body.appendChild (a);
			// create an element which will inherit the default body font family (Helvetica)
			var b = What.Element.create ('span',{},['AAA']);
			b.style.fontFamily = 'monospace';
			b.style.fontSize = '100px';
			b.style.visibility = 'hidden';
			document.body.appendChild (b);
			// add a class to the body if the font is probably not available
			if (a.offsetWidth === b.offsetWidth &&
				a.offsetHeight === b.offsetHeight) {
				document.body.className += ' alt-font';
			}
			a.remove ();
			b.remove ();
		}
	},
	/**
	 * The hierarchical menu.
	 * Some top level elements have submenu's, providing a quick way to select a type of car
	 */
	menu: {
		/* submenu UL padding */
		padding: 5,
		/* collection of currently opened menu's */
		currentOpenMenus: [],
		/**
		 * Initialize the menu
		 */
		init: function () {
			var mainnav = $('navigation');
			if (mainnav) {
				mainnav = $(mainnav.$$('ul')[0]);
				// this module uses event delegation as described by PPK @ http://www.quirksmode.org/blog/archives/2008/04/delegating_the.html
				mainnav.onmouseover = meijers.menu.mover;
				mainnav.onmouseout = meijers.menu.mout;
				// for IE
				mainnav.onfocusin = meijers.menu.mover;
				mainnav.onfocusout = meijers.menu.mout;
				// for standards-compliant browsers
				if (typeof mainnav.addEventListener === 'function') {
					mainnav.addEventListener ('focus', meijers.menu.mover, true);
					mainnav.addEventListener ('blur', meijers.menu.mout, true);
				}
			}
		},
		/**
		 * The mouse-over listener, which is actually also a focus listener
		 */
		mover: function (e) {
			if (!e) {
				e = window.event;
			}
			// fetch the actual event target, and make it a valid element
			var target = What.Event.getTarget (e);
			target = meijers.menu.convertToClosestLI (target);
			if (!target) {
				return false;
			}
			meijers.menu.foldIn (target);
			// find the level of depth of the currently controlled menu
			var level = meijers.menu.findLevel (target);
			var submenus = target.getElementsByTagName ('ul');
			target = $(target);
			// add a className so the CSS style rules for an opened menu apply
			if (submenus.length) {
				target.addClass ('hover');
				meijers.menu.currentOpenMenus.push (submenus[0]);
				if (level === 1) {
					meijers.menu.grow (target.parentNode,submenus[0]);
				}
				if (level === 0) {
					meijers.menu.checkPosition (submenus[0]);
				}
			}
		},
		/**
		 * The mouse-out listener, which is actually also a blur listener
		 */
		mout: function (e) {
			var evt = e || window.event;
			// fetch the actual event target, and make it a valid element
			var target = evt.relatedTarget || evt.toElement;
			if (!target) {
				return false;
			}
			meijers.menu.foldIn (target);
		},
		/**
		 * Hide menu
		 */
		foldIn: function (target) {
			var newCurrentOpenMenus = [];
			for (var i=0,menlen=meijers.menu.currentOpenMenus.length; i<menlen; i++) {
				if (!meijers.menu.containsItem (meijers.menu.currentOpenMenus[i], target)) {
					meijers.menu.currentOpenMenus[i].parentNode.removeClass ('hover');
					meijers.menu.shrink (target.parentNode,meijers.menu.currentOpenMenus[i]);
				} else {
					newCurrentOpenMenus.push (meijers.menu.currentOpenMenus[i]);
				}
			}
			meijers.menu.currentOpenMenus = newCurrentOpenMenus;
		},
		/**
		 * If the submenu is larger than the topmenu, enlarge the topmenu
		 */
		grow: function (parent, submenu) {
			var topheight = parseInt (parent.offsetHeight);
			var subheight = parseInt (submenu.offsetHeight);
			if (subheight > topheight) {
				parent.style.height = subheight + 'px';
			} else {
				// otherwise, make the submenu as high as the topmenu
				submenu.style.height = topheight-(meijers.menu.padding*2) + 'px';
			}
		},
		/**
		 * Normalize the elements' inline style so it can correctly grow again in the future
		 */
		shrink: function (parent, submenu) {
			parent.style.height = submenu.style.height = '';
		},
		/**
		 * Make sure the submenu fits inside the screen.
		 */
		checkPosition: function (menu) {
			var container = $ ('container');
			var defaultoffset = 5;
			if (container) {
				// fetch positions of the container and the menu
				var menu_position = What.Position.getElementPosition (menu);
				var container_position = What.Position.getElementPosition (container);
				var menu_outerright = menu_position [0] + menu.offsetWidth;
				var container_outerright = container_position [0] + container.offsetWidth;

				// if the menu's outer right edge is higher than the container's outer right edge, 
				// bring the menu back with the difference
				if (menu_outerright > container_outerright) {
					menu.style.left = -((menu_outerright - container_outerright) - defaultoffset) + 'px';
				}
			}
		},
		/**
		 * Find the level of the controlled element's submenu
		 */
		findLevel: function (element) {
			var level = 0;
			while (element.parentNode.getAttribute ('id') !== 'navigation') {
				element = element.parentNode;
				if (element.nodeName.toLowerCase() === 'li') {
					level ++;
				}
			}
			return level;
		},
		/**
		 * Not all elements in the menu are significant. 
		 * This method returns the closest list item.
		 */
		convertToClosestLI: function (element) {
			while (element.nodeName.toLowerCase() !== 'li') {
				element = element.parentNode;
				if (!element) {
					return false;
				}
			}
			return element;
		},
		/**
		 * Check if 'parent' contains 'child'
		 */
		containsItem: function (parent, child) {
			while (child.nodeName.toLowerCase() !== 'html') {
				if (child === parent) {
					return true;
				}
				child = child.parentNode;
			}
			return false;
		}
	},
	/**
	 * Search form behavior
	 */
	qfield: {
		init: function () {
			var qfield = $('q-field');
			if (qfield) {
				// remove default value on focus...
				qfield.addEvent ('focus', function () {
					// make the current value the default value
					if (!this.__defaultvalue) {
						this.__defaultvalue = this.value;
					}
					// empty the field if the default value is filled in
					if (this.value === this.__defaultvalue) {
						this.value = '';
					}
					// enlarge the field
					this.style.width = '250px';
				});
				// ...and make it reappear on blur, if no value was inserted
				qfield.addEvent ('blur', function () {
					if (!this.value) {
						this.value = this.__defaultvalue;
					}
					// back to the default width
					this.style.width = '';
				});
			}
		}
	},	
	/**
	 * A hover effect for the picture galleries
	 * @deprecated The animated effect is no more. A Lightbox is now in place (lightbox.js).
	 */
	gallery: {
		cache: {},
		init: function () {
			var galleries = document.getElementsByClassName ('gallery','ul');
			for (var g=0,gallen=galleries.length; g<gallen; g++) {
				var gallery = $(galleries[g]);
				var lis = gallery.$$ ('li');
				for (var i=0,lilen=lis.length; i<lilen; i++) {
					var a = lis[i].getElementsByTagName ('a')[0];
					a = $(a);
					a.addEvent ('mouseover',meijers.gallery.mover);
					a.addEvent ('focus',meijers.gallery.mover);
					a.addEvent ('mouseout',meijers.gallery.mout);
					a.addEvent ('blur',meijers.gallery.mout);
				}
			}
		},
		/**
		 * On mouseover, dim the other pictures by displaying the B element (see home.css for B styles)
		 */
		mover: function () {
			var gallery = this.parentNode.parentNode;
			var lis = gallery.$$ ('li');
			for (var i=0,lilen=lis.length; i<lilen; i++) {
				var a = lis[i].getElementsByTagName ('a')[0];
				if (a !== this) {
					var b = a.getElementsByTagName ('b')[0];
					b.style.display = 'block';
				}
			}
		},
		/**
		 * On mouseout, hide the B element again
		 */
		mout: function () {
			var gallery = this.parentNode.parentNode;
			var lis = gallery.$$ ('li');
			for (var i=0,lilen=lis.length; i<lilen; i++) {
				var a = lis[i].getElementsByTagName ('a')[0];
				if (a !== this) {
					var b = a.getElementsByTagName ('b')[0];
					b.style.display = '';
				}
			}
		},
		/**
		 * Show a larger version of a clicked image inline. View screen.css for additional style rules that make this possible.
		 */
		showLargeInline: function (e) {
			var imgUrl = this.getAttribute ('href');
			var parent = this.parentNode.parentNode;
			meijers.gallery.startAnimateOut (parent, imgUrl);
			What.Event.cancelBubble (e);
			What.Event.preventDefault (e);
			return false;
		},
		/**
		 * Start animating the gallery after preloading the image
		 */
		startAnimateOut: function (element, image_url) {
			// preload the image
			if (!meijers.gallery.cache [image_url]) {
				var img = new Image;
				img.src = image_url;
				meijers.gallery.cache [image_url]= img;
				// start only after the image finished loading
				img.onload = function () {
					meijers.gallery.animateOut (element, image_url);
				};
			} else {
				meijers.gallery.animateOut (element, image_url);
			}
		},
		/**
		 * Start slide out
		 */
		animateOut: function (element, image_url) {
			var img = meijers.gallery.cache [image_url];
			element.style.backgroundImage = 'url(' + image_url + ')';
			// create animation, which shoves all list items out of view until the image is visible (as a background image)
			var lis = element.$$ ('li');
			for (var i=0,lilen=lis.length; i<lilen; i++) {
				var ani = new What.Animation.Move (
					lis[i],
					-element.offsetWidth,
					0,
					10
				);
				// start the animation!
				ani.init ();
			}
			element.style.cursor = 'pointer';
			element.addEvent ('click',function (e){
				meijers.gallery.animateIn (this);
			});
		},
		/**
		 * Start slide in
		 */
		animateIn: function (element) {
			// create animation, which pulls all list items back into view
			var lis = element.$$ ('li');
			for (var i=0,lilen=lis.length; i<lilen; i++) {
				var ani = new What.Animation.Move (
					lis[i],
					0,
					0,
					10
				);
				ani.onAnimationEnd = function () {
					element.style.backgroundImage = element.style.cursor = '';
				};
				// start the animation!
				ani.init ();
			}
		}
	}
};

/**
 * Initialize general namespace
 */
meijers.init ();
