var CONFIG = {};
var Overlayer, planner, map, directionDisplay, directionsService, stepDisplay;
var markerArray = [];

var isiPad = navigator.userAgent.match(/iPad/i) != null;
var html = $$('html')[0];

if(Browser.name == 'ie') {
	html.addClass('ie');
	html.addClass('ie' + Browser.version);
}

window.addEvent('domready', function()
{
	CONFIG.BASE_URL = $(document.head).getElement('base').get('href');

	Overlayer = new Overlay();

	var headerImages = new RotateImages({'items': $('header').getElements('.visuals img'), 'duration': 6000});
	
	var placeholder = inputPlaceholders($$('input[type=text], textarea'));
	
	if($('categories')) {
		var storeFilter = new StoreFilter({
			categories: $('categories').getElements('ul.stores a'),
			storesWrapper: $('stores'),
			storesList: $('stores').getElement('ul.stores'),
			storeTitle: $('stores').getElement('h3.title'),
			storeItems: $('stores').getElements('ul.stores'),
			btnShowAll: $('stores').getElement('a.show-all'),
			loader: $('loading')
		});
	}
	
	$$('input[type=radio]').each(function(el) {	
		new CustomRadio({
			input: el,
			label: $$('label[for='+ el.get('id') +']')
		});
	}.bind(this));
	
	if($('poll')) {
		var poll = new Poll({
			form: $('poll').getElement('form'),
			question: $('poll').getElement('.question'),
			answers: $('poll').getElements('form input'),
			button: $('poll').getElement('a.btn-default'),
			results: $('poll').getElements('.results'),
			resultNumbers: $('poll').getElements('.results label span'),
			resultBars: $('poll').getElements('.results .bar')
		});
	}
	
	if($('album')) {
		var album = new Carousel({
			wrapper: $('album'),
			carouselWrapper: $('album').getElement('.photos-wrapper'),
			carousel: $('album').getElement('.carousel'),
			items: $('album').getElements('ul.photos a'),
			photo: $('album').getElement('.image'),
			buttons: $('album').getElements('ul.buttons a'),
			photoButtons: $('album').getElements('.image a.control')
		});	
	}
	
	if($('guide')) {
		var map = new Guide({
			guide: $('guide'),
			maps: $('guide').getElements('.map'),
			hovers: $('guide').getElements('.hovers img'),
			buttons: $('guide').getElements('.buttons a')
		});	
	}
	
	if($('slideshow')) {
		var slideshow = new RotateImages({'items': $('slideshow').getElements('img'), 'duration': 3000});
	}
	
	if($('fontsize')) {
		new FontSize({
			wrapper: $('fontsize'),
			buttons: $('fontsize').getElements('a')
		});	
	}
	
	if($('footer')) {
		acFooter = new AutoCompleter('searchStoresInput', 'ajax/index/autocomplete', {
			onChoose: function(selection) {
				window.location = CONFIG.BASE_URL + 'winkels/' + selection.key + '/' + selection.value
			}
		});
	}
	
	if($('search')) {
		acSearch = new AutoCompleter('searchStoresSearch', 'ajax/index/autocomplete', {
			onChoose: function(selection) {
				window.location = CONFIG.BASE_URL + 'winkels/' + selection.key + '/' + selection.value
			}
		});	
	}
	
	if($('route')) {
		planner = new RoutePlanner({
			wrapper: $('route'),
			form: {
				location: $('route').getElement('form.route input[name=location]')
			},
			submitButton: $('route').getElement('form.route .btn-default')
		});				
	}
	
	$$('.ajaxform').each(function(el, i) {
		new AjaxForm({
			wrapper: el,
			form: el.getElement('form'),
			formWrapper: el.getElement('.form-wrapper'),
			resultWrapper: el.getElement('.result-wrapper')
		});	
	}.bind(this));
});



function inputPlaceholders(elements) {
	elements.each(function(el, i) {
		var placeholder = el.get('value');
		el.addEvents({
			'focus': function(e) {
				if(el.get('value') == placeholder) {
					el.set('value', '');
				}
			}.bind(this),
			'blur': function(e) {
				if(el.get('value') == '') {
					el.set('value', placeholder);	
				}
			}.bind(this)
		});	
	}.bind(this));
}



var RotateImages = new Class({
	options: {
		items: null,
		active: 0,
		numberOfItems: null,
		timer: null,
		duration: null
	},
	Implements: Options,
	
	initialize: function(options) {
		this.setOptions(options);	
		this.options.numberOfItems = this.options.items.length;
		
		this.options.items.each(function(el, i) {
			if(i > 0) {
				el.fade('hide');	
			}
		});
				
		this.options.items[0].addClass('active');
		
		this.setPeriodical();
	},
	
	setPeriodical: function() {
		this.options.timer = this.autoSlide.periodical(this.options.duration, this);
	},
	
	autoSlide: function() {
		++this.options.active;
		if (this.options.active >= this.options.numberOfItems) {
			this.options.active = 0;
		}
		
		this.options.items.fade('out');
		this.options.items[this.options.active].fade('in');
	}
});



var CustomRadio = new Class({
	options: {
		input: null,
		label: null
	},
	Implements: Options,
	
	initialize: function(options) {
		this.setOptions(options);
		this.initRadioButton();
		
		this.addEvents();
	},
	
	initRadioButton: function() {
		this.options.input.setStyle('display', 'none');
		this.options.custom = new Element('a', {'href': '#', 'class': 'radiobutton ' + this.options.input.get('name'), 'rel': this.options.input.get('value')}).inject(this.options.input, 'after');
	},
	
	addEvents: function() {
		this.options.custom.addEvent('click', function(e) {
			e.stop();
			
			$$('.radiobutton').each(function(el) {
				el.removeClass('radio-active');
			}.bind(this));
			
			this.options.custom.addClass('radio-active');
			this.options.custom.getPrevious('input').set('checked', true);
			
		}.bind(this));
		
		this.options.label.addEvent('click', function(e) {
			e.stop();
			
			$$('.radiobutton').each(function(el) {
				el.removeClass('radio-active');
			}.bind(this));
			
			this.options.custom.addClass('radio-active');
			this.options.custom.getPrevious('input').set('checked', true);
			
		}.bind(this));
	}
});



var Poll = new Class({
	options: {
		form: null,
		question: null,
		answers: null,
		button: null,
		results: null,
		resultNumbers: null,
		resultBars: null
	},
	Implements: Options,
	
	initialize: function(options) {
		this.setOptions(options);
		this.options.question.setStyle('height', this.options.question.getSize().y);
		this.options.results.setStyle('display', 'none').fade('hide');
		this.addEvents();
	},
	
	addEvents: function() {
		this.options.button.addEvent('click', function(e) {
			e.stop();
			this.options.form.fireEvent('submit');
		}.bind(this));
		
		this.options.form.addEvent('submit', function(e) {
			this.submitForm(this.options.form.get('action'));
			this.options.question.set('html', '<img class="loader" src="inc/images/loader.gif">');
		}.bind(this));
	},
	
	submitForm: function(url) {
		new Request.JSON({
			url: url,
			onSuccess: function(response) {
				(function() {
					this.setResults(response);
				}.delay(1000, this));
			}.bind(this)
		}).post(this.options.form);
	},
	
	setResults: function(results) {
		this.options.question.setStyle('display', 'none');
		this.options.results.setStyle('display', 'block').fade('in');
		this.options.resultBars.each(function(el, i) {
			this.options.resultNumbers[i].set('html', '(' + results[i] + '%)');
			var tweenAnswer = new Fx.Tween.CSS3(el, { duration: 1000, transition: 'quint:in:out' });
			if(results[i] == 0) {
				results[i] = 1;
			}
			tweenAnswer.start('width', results[i] * 2);
		}.bind(this));
	}
});



var Carousel = new Class({
	options: {
		wrapper: null,
		carouselWrapper: null,
		carousel: null,
		items: null,
		photo: null,
		buttons: null,
		photoButtons: null
	},
	Implements: Options,
	
	initialize: function(options) {
		this.setOptions(options);
		
		this.options.active = 0;
		this.options.currentPos = 0;
		this.options.visibleItems = 6;
		this.options.fxSlide = new Fx.Scroll(this.options.carouselWrapper, {'duration': 200});
		if(this.options.items.length <= this.options.visibleItems) {
			this.options.buttons.setStyle('display', 'none');	
		}
		
		this.addEvents();
	},
	
	addEvents: function() {
		this.options.buttons.each(function(el) {
			el.addEvent('click', function(e) {
				e.stop();
				if(el.hasClass('next')) {
					++this.options.currentPos;
				} else if(el.hasClass('previous')) {
					--this.options.currentPos;
				}
				
				if(this.options.currentPos < 0) {
					this.options.currentPos = this.options.items.length - this.options.visibleItems;
				} else if(this.options.currentPos > this.options.items.length - this.options.visibleItems) {
					this.options.currentPos = 0;
				}
				this.slide();
			}.bind(this));
		}.bind(this));
		
		this.options.items.each(function(el, i) {		
			el.addEvent('click', function(e) {
				e.stop();
				this.options.active = i;
				if(el.hasClass('video')) {
					this.showVideo(el.get('href'));
				} else {
					this.showImage(el.get('href'), el.get('data-file'));
				}
			}.bind(this));
		}.bind(this));
		
		this.options.photoButtons.addEvent('click', function(e) {
			e.stop();
			if(this.options.photoButtons.hasClass('next')) {
				++this.options.active;
			} else if(this.options.photoButtons.hasClass('previous')) {
				--this.options.active;
			}
			
			if(this.options.active < 0) {
				this.options.active = this.options.items.length - 1;
			} else if(this.options.active > this.options.items.length - 1) {
				this.options.active = 0;
			}
			this.setActiveSlide();
			this.showImage(this.options.items[this.options.active].get('href'), this.options.items[this.options.active].get('data-file'));
		}.bind(this));
	},
	
	showImage: function(image, url) {
		this.options.image = Asset.image(image, {
			id: 'image',
			onLoad: function() {
				this.setActiveSlide();
				this.clearContainer();
				this.options.image.inject(this.options.photo, 'inside');
				this.showDownload(url);
			}.bind(this)
		});
	},
	
	showVideo: function(videoID) {
		this.clearContainer();
		var video = new Element('iframe', {
			'src': 'http://www.youtube.com/embed/'+ videoID +'?rel=0&showinfo=0&autohide=1&jsapi=1',
			'width': 680,
			'height': 340,
			'frameborder': 0
		}).setProperty('allowfullscreen').inject(this.options.photo);
	},
	
	showDownload: function(url) {
		new Element('a', {
			'href': url,
			'class': 'download',
			'html': 'Download de originele foto naar uw computer'
		}).inject(this.options.photo);
	},
	
	clearContainer: function() {
		if(this.options.photo.getElement('img')) {
			this.options.photo.getElement('img').destroy();
		}
		
		if(this.options.photo.getElement('iframe')) {
			this.options.photo.getElement('iframe').destroy();
		}
		
		if(this.options.photo.getElement('a.download')) {
			this.options.photo.getElement('a.download').destroy();
		}
	},
	
	slide: function() {
		this.options.fxSlide.toElement(this.options.items[this.options.currentPos]);
	},
	
	setActiveSlide: function() {
		this.options.items.removeClass('active');
		this.options.items[this.options.active].addClass('active');
	}
});



StoreFilter = new Class({
	options: {
		categories: null,
		storesWrapper: null,
		storesList: null,
		storeTitle: null,
		storeItems: null,
		btnShowAll: null,
		loader: null		
	},
	Implements: Options,
	
	initialize: function(options) {
		this.setOptions(options);
		
		this.options.loader.setStyle('display', 'none').fade('hide');
		this.options.scroller = new Fx.Scroll(document.window);
		
		this.toggle(this.options.btnShowAll, 'hide');
		
		this.fillStoreList('ajax/index/getstoresbycategory?c=0');
		this.addEvents();
	},
	
	addEvents: function() {
		this.options.categories.each(function(el, i) {
			el.addEvent('click', function(e) {
				e.stop();
				this.setStores(el.get('href'));
				this.setTitle(el.getElement('span').get('html'));		
				this.toggle(this.options.btnShowAll, 'show');
			}.bind(this));
		}.bind(this));
		
		this.options.btnShowAll.addEvent('click', function(e) {
			e.stop();
			this.clearTitle();
			this.setStores(this.options.btnShowAll.get('href'));
			this.toggle(this.options.btnShowAll, 'hide');
		}.bind(this));
	},
	
	setStores: function(categoryUrl) {
		this.fillStoreList(categoryUrl);
		this.scrollToElement(this.options.storesWrapper);
	},
	
	fillStoreList: function(categoryUrl) {
		this.toggle(this.options.loader, 'show');
		this.toggle(this.options.storesList, 'hide');
		
		this.options.storesList.set('html', '');
		
		var loadStores = new Request.JSON({
			url: categoryUrl,
			onComplete: function(response) {
			
				if(!response.success) {
					// nothing found
					this.toggle(this.options.storesList, 'show');
					
					this.toggle(this.options.loader, 'hide');
					this.toggle(this.options.storesWrapper, 'show');
				}
			
				(function() {						
					if(response.success) {
						response.stores.each(function(store, i) {
							var storeItem = new Element('li').inject(this.options.storesList, 'inside');
							var storeLink = new Element('a', {'href': store.url, 'title': store.title }).inject(storeItem, 'inside');
							var storeImage = new Element('img', {'class': 'visual', 'src': store.logo, 'alt': store.title }).inject(storeLink, 'inside');
						}.bind(this));
					
						this.toggle(this.options.storesList, 'show');
						
						this.toggle(this.options.loader, 'hide');
						this.toggle(this.options.storesWrapper, 'show');
					}
				}.delay(1000, this));
			}.bind(this)
		}).get();
	},
	
	setTitle: function(title) {
		this.options.storeTitle.getElement('span').set('html', title);
	},
	
	clearTitle: function() {
		this.options.storeTitle.getElement('span').set('html', '');
	},
	
	toggle: function(element, method) {
		if(method == 'show') {
			element.setStyle('display', 'block').fade('in');
		} else {	
			element.setStyle('display', 'none').fade('hide');
		}
	},
	
	scrollToElement: function(element) {
		this.options.scroller.toElement(element);
	}
	
});



var Guide = new Class({
	options: {
		guide: null,
		maps: null,
		hovers: null,
		buttons: null
	},
	Implements: Options,
	
	initialize: function(options) {
		this.setOptions(options);
		
		this.options.active = 0;
		this.options.mapHeight = 0;
		
		this.initMaps();
		this.preloadMap();
		this.initTooltip();
		
		this.addEvents();
	},
	
	initMaps: function() {
		this.options.maps.setStyle('opacity', '0');
		this.options.maps[this.options.active].setStyle('opacity', '1');
		
		this.options.hovers.setStyle('opacity', '0');
		this.options.hovers[this.options.active].setStyle('opacity', '1');
		
		this.options.mapHeight = this.options.maps[this.options.active].get('data-height');
		this.setHeights();
	},
	
	setHeights: function() {
		this.options.guide.set('tween', {'duration': 200, 'transition': 'quint:in:out'}).tween('height', this.options.mapHeight);
		this.options.maps[this.options.active].set('tween', {'duration': 200, 'transition': 'quint:in:out'}).tween('height', this.options.mapHeight);
	},
	
	preloadMap: function() {
		this.options.loader = new Element('img', {'class': 'loader', 'src': 'inc/images/map-loader.gif'}).inject(this.options.guide);
		if(this.options.activeMap) {
			this.options.activeMap.dispose();	
		}
		
		var mapWidth = 520;
		var mapHeight = 0;
		
		this.options.activeMap = Asset.image(this.options.maps[this.options.active].get('rel'), {
			onLoad: function() {
				if(this.options.maps[this.options.active].hasClass('map-gf')) {
					mapWidth = 520;
					mapHeight = 23814;
				} else if(this.options.maps[this.options.active].hasClass('map-ff')) {
					mapWidth = 521;
					mapHeight = 17064;
				}
				(function() {
					this.options.activeMap.inject(this.options.maps[this.options.active]);
					this.options.activeMap.setStyles({
						'width': mapWidth,
						'height': mapHeight	
					});
					this.options.activeMap.set('width', mapWidth);
					this.options.activeMap.set('height', mapHeight);
					this.setMapHovers();
				}.delay(500, this));
			}.bind(this)
		});
		this.options.hovers[this.options.active].setStyle('display', 'block');
	},
	
	setMapHovers: function() {
		this.options.loader.dispose();
		var area = this.options.hovers[this.options.active].get('usemap');
		var areaMap = area.replace('#', '');
		var areas = $$('map[name='+areaMap+']')[0].getElements('area');
		this.initMapHovers(areas);
	},
	
	initMapHovers: function(areas) {
		areas.each(function(el, i) {
			el.addEvents({
				'mouseenter': function(e) {
					e.stop();
					this.options.activeMap.style.top = (i + 1) * (this.options.mapHeight * -1) + 'px';
					this.toggleTooltip('show', areas, i);
				}.bind(this),
				'mouseleave': function(e) {
					this.options.activeMap.style.top = 0 + 'px';
					this.toggleTooltip('hide');
				}.bind(this),
				'mousemove': function(e) {
					this.options.tooltip.style.left = e.page.x + 'px';
					this.options.tooltip.style.top = e.page.y + 'px';
				}.bind(this)
			});
		}.bind(this));
	},
	
	initTooltip: function() {
		this.options.tooltip = new Element('div', {'id': 'tooltip', 'html': '<h2></h2><img src="">'}).inject($(document.body), 'inside').setStyle('display', 'none').fade('hide');
	},
	
	toggleTooltip: function(method, areas, i) {
		if(method == 'show') {
			var title = areas[i].get('data-title');
			var image = areas[i].get('data-logo');
			
			this.options.tooltip.getElement('h2').set('html', title);
			this.options.tooltip.getElement('img').set('src', image);
			
			this.options.tooltip.setStyle('display', 'block').fade('in');
		} else if(method == 'hide') {
			this.options.tooltip.setStyle('display', 'none').fade('hide');
		}
	},
	
	addEvents: function() {
		this.options.buttons.each(function(el, i) {
			el.addEvent('click', function(e) {
				e.stop();
				this.options.active = i;
				this.initMaps();
				this.preloadMap();
			}.bind(this));
		}.bind(this));
	}
});



var FontSize = new Class({
	options: {
		wrapper: null,
		buttons: null
	},
	Implements: Options,
	
	initialize: function(options) {
		this.setOptions(options);
		
		this.initFontSize();
		this.addEvents();
	},
	
	initFontSize: function() {
		if(Cookie.read('fontsize')) {
			this.setFontSize(Cookie.read('fontsize'));
		}
	},
	
	addEvents: function() {
		this.options.buttons.each(function(el, i) {
			el.addEvent('click', function(e) {
				e.stop();
				this.setFontSize(el.get('data-fontsize'));
				this.setCookie(el.get('data-fontsize'));
			}.bind(this));
		}.bind(this));
	},
	
	setFontSize: function(size) {
		$(document.body).setStyle('font-size', size + 'em');
	},
	
	setCookie: function(size) {
		Cookie.write('fontsize', size);
	}
});



var AjaxForm = new Class({
	options: {
		form: null,
		formWrapper: null,
		resultWrapper: null
	},
	Implements: Options,
	
	initialize: function(options) {
		this.setOptions(options);
		
		this.options.formFx = new Fx.Morph(this.options.formWrapper, {'duration': 200, 'transition': Fx.Transitions.Expo.easeOut});
		this.options.resultFx = new Fx.Tween(this.options.resultWrapper, {'duration': 200, 'transition': Fx.Transitions.Expo.easeOut});
		
		this.options.formHeight = this.options.formWrapper.getSize().y;
		this.options.resultHeight = this.options.resultWrapper.getElement('article').getSize().y;
		
		this.initForm();
		this.addEvents();
	},
	
	initForm: function() {
		this.options.submitForm = this.options.form.set('send', {
			'method': 'post',
			onComplete: function(reponse) {
				this.tweenForm();
			}.bind(this)
		});
	},
	
	addEvents: function() {
		this.options.form.getElement('a.btn-default').addEvent('click', function(e) {
			e.stop();
			if(this.checkFormField()) {
				this.options.submitForm.send();	
			}
		}.bind(this));
	},
	
	checkFormField: function() {
		var valid = true;
		var inputFields = this.options.form.getElements('input, textarea');
		var defaultValues = [
			'Naam',
			'E-mailadres',
			'Bericht'
		];
		
		inputFields.each(function(el, i) {
			if(defaultValues.contains(el.get('value'))) {
				el.addClass('error');
				valid = false;
			} else {
				el.removeClass('error');
			}
		}.bind(this));
		
		if(valid) {
			return true;	
		} else {
			return false;	
		}
	},
	
	tweenForm: function() {
		this.options.formFx.start({
			'height': 0,
			'opacity': 0
		});
		this.options.resultFx.start('height', this.options.resultHeight);
		(function() {
			this.options.formFx.start({
				'height': this.options.formHeight + 18,
				'opacity': 1
			});
			this.options.resultFx.start('height', 0);
		}.delay(5000, this));
	}
});



RoutePlanner = new Class({
	options: {
		wrapper: null,
		form: {
			location: null
		},
		submitButton: null
	},
	Implements: Options,
	
	initialize: function(options) {
		this.setOptions(options);
		this.initMaps();
		this.addEvents();
	},
	
	initMaps: function() {
		directionsService = new google.maps.DirectionsService();
		
		var latlng = new google.maps.LatLng(52.22483, 5.177127);
		var myOptions = {
			zoom: 12,
			center: latlng,
			mapTypeId: google.maps.MapTypeId.ROADMAP
		};
		
		var map = new google.maps.Map(document.getElementById('map_canvas'), myOptions);
		var rendererOptions = {
			map: map
		}
		
		directionsDisplay = new google.maps.DirectionsRenderer(rendererOptions);
		stepDisplay = new google.maps.InfoWindow();
	},
	
	calcRoute: function(start) {
		for (i = 0; i < markerArray.length; i++) {
			markerArray[i].setMap(null);
		}
		
		markerArray = [];
		
		var end = '52.22483, 5.177127';
		var request = {
			origin: start,
			destination: end,
			travelMode: google.maps.DirectionsTravelMode.DRIVING
		};
		
		directionsService.route(request, function(response, status) {
			if (status == google.maps.DirectionsStatus.OK) {
				var warnings = document.getElementById('warnings_panel');
				warnings.innerHTML = '<b>' + response.routes[0].warnings + '</b>';
				directionsDisplay.setDirections(response);
				planner.showSteps(response);
				planner.setRouteDescriptions(response.routes[0].legs[0].steps);
			}
		});
	},
	
	setRouteDescriptions: function(directions) {
		$('route_description').getElement('.routes').set('html', '');
		directions.each(function(dir, i) {
			new Element('p', {'class': 'description', 'html': dir.instructions}).inject($('route_description').getElement('.routes'), 'inside');
			new Element('p', {'class': 'details distance', 'html': dir.distance.text}).inject($('route_description').getElement('.routes'), 'inside');
			new Element('p', {'class': 'details duration', 'html': dir.duration.text}).inject($('route_description').getElement('.routes'), 'inside');
			new Element('div', {'class': 'clear'}).inject($('route_description').getElement('.routes'), 'inside');
		}.bind(this));
		this.setRouteHeight();
		this.scrollToMap();
	},
	
	showSteps: function(directionResult) {
		var myRoute = directionResult.routes[0].legs[0];
		
		for (var i = 0; i < myRoute.steps.length; i++) {
			var marker = new google.maps.Marker({
				position: myRoute.steps[i].start_point, 
				map: map
			});
			planner.attachInstructionText(marker, myRoute.steps[i].instructions);
			markerArray[i] = marker;
		}
	},
	
	attachInstructionText: function(marker, text) {
		google.maps.event.addListener(marker, 'click', function() {
			stepDisplay.setContent(text);
			stepDisplay.open(map, marker);
		});
	},
	
	addEvents: function() {
		this.options.submitButton.addEvent('click', function(e) {
			e.stop();
			this.getInput();
		}.bind(this));
		
		this.options.wrapper.getElement('form').addEvent('submit', function(e) {					
			e.stop();
			this.getInput();
		}.bind(this));	
	},
	
	getInput: function() {
		if(this.options.form.location.get('value') != 'Straatnaam, Plaatsnaam en/of Postcode') {
			this.options.form.location.removeClass('error');
			this.calcRoute(this.options.form.location.get('value'));
		} else {
			this.options.form.location.addClass('error');
		}
	},
	
	scrollToMap: function() {
		this.options.scrollFx = new Fx.Scroll($(document.body));	
		this.options.scrollFx.toElement($('route').getElement('form.route'));
	},
	
	setRouteHeight: function() {
		var size = $('route_description').getElement('.routes').measure(function(){ return this.getSize(); });
		this.options.fxTween = new Fx.Tween($('route_description'));
		this.options.fxTween.start('height', size.y + 100);
	}
});



Overlay = new Class({
	options: {
		toggler: 'a.overlay',
		overlay: 'overlayer',
		content: 'overlay-content',
		close: 'btn-close',
		mask: null
	},
	Implements: Options,
	
	initialize: function(options) {
		this.setOptions(options);
		this.options.mask = new Mask;
		this.options.mask.addEvent('click', function(){
			this.hide();
		}.bind(this));
		
		this.createElements();
		this.addEvents();
	},
	
	createElements: function() {
		this.options.toggler = $$(this.options.toggler);
		this.options.overlay = new Element('div', { 'id': this.options.overlay }).inject(document.body, 'bottom');
		this.options.content = new Element('div', { 'id': this.options.content }).inject(this.options.overlay);
		this.options.close = new Element('a', { 'id': this.options.close }).inject(this.options.overlay);
	},
	
	addEvents: function() {
		this.options.toggler.each(function(button, key) {
			button.addEvent('click', function(e){
				e.stop();
				this.getPage(button.get('rel'), button.get('href'));
			}.bind(this));
		}.bind(this));
		
		this.options.close.addEvent('click', function(e) {
			this.hide();
		}.bind(this));
	},
	
	getPage: function(rel, href) {
		var getPage = new Request.HTML({
			url: href,
			onSuccess: function(responseTree, responseElements, responseHTML, responseJavaScript){
				this.options.content.set('html', responseHTML);
				this.show();
				this.setOverlayPosition(rel, this.calc());
			}.bind(this)
		}).get();
	},
	
	initPage: function(mediaId, mediaType) {
		
	},
	
	calc: function() {
		return this.options.overlay.measure(function(){ return this.getSize(); });
	},
	
	setOverlayPosition: function(rel, size) {
		this.options.overlay.set('class', rel);
	},
	
	show: function() {
		this.options.mask.show();
		this.options.overlay.setStyle('display', 'block');
	},
	
	hide: function() {
		this.options.mask.hide();
		this.options.content.set('html', '');
		this.options.overlay.setStyle('display', 'none');		
	}
	
});



var AutoCompleter = new Class({
	Implements: [Options,Events],
	options: {
		ajaxMethod: 'get',
		ajaxParam: 'search',
		inputMinLength: 1,
		pause: 0,

		targetfieldForKey: '', 
		targetfieldForValue: '', 

		suggestionBoxOuterClass: 'autocompleteWrapper',
		suggestionBoxListClass: 'autocompleteChoices',
		suggestionBoxLoadingClass: 'autocompleteLoading',
		suggestionBoxHoverClass: 'autocompleteChoicesHover',

		clearChoicesOnBlur: true,
		clearChoicesOnEsc: true,
		clearChoicesOnChoose: true,
		setValuesOnChoose: true,

		suggestionContainer: {},
		choiceContainer: 'ul',
		choiceElement: 'li',

		onChoose: function() {}
	},

	initialize: function(inputfield, url, options) {
		this.setOptions(options);
		if (!$(inputfield)) { return; }

		this.prevlength = 0;
		this.textfield = $(inputfield);
		this.url = url;
		this.clickeddoc = false;

		var mywidth = 300;
		var myleft = this.textfield.getPosition().x;
		var mytop = this.textfield.getPosition().y + this.textfield.getSize().y;

		if (this.options.suggestionContainer && $(this.options.suggestionContainer)) {
			this.container = $(this.options.suggestionContainer);
			this.container.addClass(this.options.suggestionBoxOuterClass);
		} else {
		this.container = new Element('div', {
			'class': this.options.suggestionBoxOuterClass,
			'styles': { 'width': mywidth, 'left': 0, 'top': 0, 'height': 0 }
		}).inject($(inputfield), 'after');
		}

		this.choices = new Element(this.options.choiceContainer, {
			'class': this.options.suggestionBoxListClass
		}).inject($(this.container), 'inside');
		this.clearChoices();

		this.textfield.setProperty('autocomplete', 'off');
		this.textfield.addEvents( {'keydown': this.keypressed.bind(this), 'keyup': this.keypressed.bind(this)} );
		if (this.options.clearChoicesOnBlur) {
			if (!Browser.ie) {
				this.textfield.addEvents( {'blur': this.clearChoices.bind(this) } );
			}
			else {
				document.addEvent('click', this.docclick.bind(this));
				this.textfield.addEvents( {'blur': this.blurLater.bind(this) } );
			}
		}

		if (!Browser.ie) {
			this.choices.addEvents( {'mousedown': function(e){e.preventDefault();} } );
		}

		if (this.url) {
			this.ajax = new Request({
				url: this.url,
				method: this.options.ajaxMethod});
			this.ajax.addEvent('onComplete', this.ajaxComplete.bind(this));
		}
	},

	getValues: function(input) {
		var t_input = input;

		if (this.options.doRetrieveValues != null) {
			this.setValues(this.options.doRetrieveValues.apply(input));
		}
		else if (this.ajax) {
			if (this.options.pause === 0) {
				this.choices.hide();
				this.container.addClass(this.options.suggestionBoxLoadingClass);
				this.container.show();
				this.ajax.send(this.options.ajaxParam+"="+t_input);
			}
			else {
				var myself = this;
				window.setTimeout(
				   function() {
						if ( t_input == myself.textfield.get('value') ) {
							myself.choices.hide();
							myself.container.addClass(myself.options.suggestionBoxLoadingClass);
							myself.container.show();
						   	myself.ajax.send(myself.options.ajaxParam+"="+t_input);
					   } else {
						   myself.ajax.cancel();
					   }
				   }, myself.options.pause);
			}
		}
	},

	ajaxComplete: function(input) {
		if (!input) { return; }
		var myvalue = JSON.decode(input, true);

		if (myvalue === false || !myvalue.length) {
			this.clearChoices();
		}
		else {
			this.setValues(myvalue);
		}
	},

	setValues: function(values) {
		this.values = values;
		this.clearChoices();
		this.values.each( function(avalue, i) {
			if (avalue) {
				this.lielems[i] = new Element(this.options.choiceElement, { 'html': avalue[1] });
				this.lielems[i].addEvent('click',this.enterValue.bind(this, {id: avalue[0], value: avalue[1] })	);
				if (Browser.ie) {
					this.lielems[i].addEvent('mousedown',this.enterValue.bind(this, {id: avalue[0], value: avalue[1] }));
				}
				this.lielems[i].inject(this.choices, 'inside');
			}
		}.bind(this));

		this.container.show();
		this.container.removeClass(this.options.suggestionBoxLoadingClass);
		this.choices.show();
		this.lielems[this.selected].addClass(this.options.suggestionBoxHoverClass);
	},

	clearChoices: function(obj) {
		this.lielems = [];
		this.selected = 0;
		this.choices.set('html', '');
		this.container.hide();
	},

	enterValue: function(selected) {
		if (this.options.setValuesOnChoose) {
			if (this.options.targetfieldForKey && $(this.options.targetfieldForKey)) {
				$(this.options.targetfieldForKey).value = selected['id'];
			}
			if (this.options.targetfieldForValue && $(this.options.targetfieldForValue)) {
				$(this.options.targetfieldForValue).value = selected['value'];
			}
			else {
				this.textfield.value = selected['value'];
			}
		}

		this.fireEvent('onChoose', {'key': selected['id'], 'value': selected['value']});

		if (this.options.clearChoicesOnChoose) {
			this.clearChoices();
		}
	},

	moveUp: function(el, event) {
		if (this.lielems[this.selected] && this.lielems[this.selected - 1]) {
			this.lielems[this.selected].removeClass(this.options.suggestionBoxHoverClass);
			this.selected -= 1;
			this.lielems[this.selected].addClass(this.options.suggestionBoxHoverClass);
		}
	},

	moveDown: function(el, event) {
		if (this.lielems[this.selected] && this.lielems[this.selected + 1]) {
			this.lielems[this.selected].removeClass(this.options.suggestionBoxHoverClass);
			this.selected += 1;
			this.lielems[this.selected].addClass(this.options.suggestionBoxHoverClass);
		}
	},

	keypressed: function(event) {
		var myevent = new Event(event);
		if (myevent.target.id === this.textfield.id) {
			if (myevent.type == 'keyup') {
				switch (myevent.key) {
					case 'enter':
						if (this.lielems[this.selected]) {
							this.lielems[this.selected].fireEvent('click');
						}
						event.preventDefault();
						break;
					case 'down':
						this.moveDown();
						event.preventDefault();
						break;
					case 'up':
						this.moveUp();
						event.preventDefault();
						break;
					case 'esc':
						if (this.options.clearChoicesOnEsc) {
							this.clearChoices();
						}
						break;
					default:
						var text = myevent.target.value;
						if (text.length != this.prevlength) {
							if (text.length >= this.options.inputMinLength) {
								this.prevlength = text.length;
								this.getValues(text);
							} else {
								this.clearChoices();
							}
							event.preventDefault();
						}
				}
			} else if (myevent.key == 'enter' || myevent.key == 'esc') {
				event.preventDefault();
			}
			else {
				this.prevlength = myevent.target.value.length;
			}
		}
	},

	// IE6/7 workaround...
	docclick: function(event) {
		if (this.textfield.id !== event.target.id) {
	        this.clickeddoc = true;
		}
    },

	// IE6/7 workaround...
    blurLater: function(event) {
		var that = this;
		var callback = function()
		{
			if (that.clickeddoc) {
				that.clickeddoc = false;
				that.clearChoices(event);
			}
			else {
          		that.textfield.focus();
        	}
		};
		setTimeout(callback, 200);
    }
});



// Element Implements
Element.implement({
	hasEvent: function(eventType,fn){
		var myEvents = this.retrieve('events');
		return myEvents && myEvents[eventType] && (fn == undefined || myEvents[eventType].keys.contains(fn));
	},
	show: function() {
		this.setStyle('display','block');
	},
	inline: function() {
		this.setStyle('display','inline');
	},
	hide: function() {
		this.setStyle('display','none');
	}
});
