
function FancySlider(options)
{
	this.options = options;

	this.element = null;
	this.slider = null;

	// presentational!!!!
	this.width = 182;
	this.sliderBallRadius = 8;
	this.maxTicks = 6;

	this.min = 0;
	this.max = 0;
	this.step = 0;
	this.valueMin = 0;
	this.valueMax = 0;
	this.showLower = 0;
	this.showHigher = 0;
	this.lowValue = null;
	this.highValue = null;

	this.initialized = false;

	this.drag = false;
	this.cx = 0;
	this.sx = 0;
	this.x = 0;
	this.maxX = 0;

	this.init();
}
Object.extend(FancySlider.prototype,
{
	init: function()
	{
		if (this.options)
		{
			this.element = document.createElement('div');
			this.element.className = 'sliderControl';
			this.element.onselectstart = function() { return false; }

			this.sliderArea = document.createElement('div');
			this.sliderArea.className = 'sliderArea';
			this.element.appendChild(this.sliderArea);

			var sliderBallImg = 'slider_ball';
			var sliderBallImgHover = 'slider_ball_hover';
			if ('width' in this.options)
			{
				if (this.options.width >= 300)
				{
					this.element.className = 'sliderControlLarge';
					this.sliderBallRadius = 10;
					sliderBallImg = 'slider_ball_large';
					sliderBallImgHover = 'slider_ball_large_hover';
				}

				this.width = this.options.width - 2 * this.sliderBallRadius;

				this.element.style.width = this.options.width + 'px';
			}

			preload('slider_ball', KiImgURL+'g/slider/slider_ball.gif');
			preload('slider_ball_hover', KiImgURL+'g/slider/slider_ball_hover.gif');
			preload('slider_ball_large', KiImgURL+'g/slider_large/slider_ball.gif');
			preload('slider_ball_large_hover', KiImgURL+'g/slider_large/slider_ball_hover.gif');

			if (this.options.minSelect || this.options.maxSelect)
			{
				if (this.options.minSelect && this.options.minSelect.tagName.toLowerCase() == 'select')
				{
					if ('lowValue' in this.options)
					{
						this.options.minSelect.value = this.options.lowValue;
					}
					else
					{
						this.minSelect = this.options.minSelect;

						if ('highValue' in this.options)
							this.highValue = this.options.highValue;

						if (this.options.showLower)
							this.showLower = 1;

						if (this.minSelect.options.length)
						{
							this.min = this.showLower + (this.minSelect.options[0].value == '' ? 1 : 0);
							this.max = this.minSelect.options.length - 1;
						}

						this.options.valueMin = Math.max(this.minSelect.selectedIndex, this.min - this.showLower);
					}
				}

				if (this.options.maxSelect && this.options.maxSelect.tagName.toLowerCase() == 'select')
				{
					if ('highValue' in this.options)
					{
						this.options.maxSelect.value = this.options.highValue;
					}
					else
					{
						this.maxSelect = this.options.maxSelect;

						if ('lowValue' in this.options)
							this.lowValue = this.options.lowValue;

						if (this.options.showHigher)
							this.showHigher = 1;

						if (this.maxSelect.options.length)
						{
							this.max = this.maxSelect.options.length - 1 - this.showHigher;

							if (!this.minSelect)
							{
								this.showLower = 0;
								this.min = this.maxSelect.options[0].value == '' ? 1 : 0;
							}
							else
								this.max += this.showLower;
						}

						this.options.valueMax = this.maxSelect.selectedIndex ? this.maxSelect.selectedIndex + this.showLower : this.max + this.showHigher;
					}
				}

				this.options.step = 1;
			}
			else
			{
				this.min = parseInt(this.options.min || 0, 10);
				this.max = parseInt(this.options.max, 10);
			}

			if ('step' in this.options)
				this.step = parseInt(this.options.step, 10);
			else
				this.step = Math.ceil((this.max - this.min) / 10);

			this.sliderBar = document.createElement('div');
			this.sliderBar.className = 'sliderBar';
			this.sliderArea.appendChild(this.sliderBar);

			var sliderStart = document.createElement('div');
			sliderStart.className = 'sliderStart';
			var sliderEnd = document.createElement('div');
			sliderEnd.className = 'sliderEnd';

			var minSlider = 'valueMin' in this.options;
			var maxSlider = 'valueMax' in this.options;

			// save original width
			this.maxX = this.width;

			if (this.showLower)
			{
				sliderStart.className += ' sliderStartLower';
				this.width -= this.sliderBallRadius;
			}
			if (minSlider && !maxSlider && (this.showLower || this.highValue !== null))
				sliderEnd.className += ' sliderEndSelected';

			if (this.showHigher)
			{
				sliderEnd.className += ' sliderEndHigher';
				this.width -= this.sliderBallRadius;
			}
			if (maxSlider && !minSlider && (this.showHigher || this.lowValue !== null))
				sliderStart.className += ' sliderStartSelected';

			this.sliderBar.appendChild(sliderStart);
			this.sliderBar.appendChild(sliderEnd);

			// FIXME
			var totalSteps = Math.ceil((this.max - this.min) / this.step);
			this.tickwidth = this.width / totalSteps;

			if ((minSlider && maxSlider) || this.showLower || this.showHigher || this.lowValue !== null || this.highValue !== null)
			{
				this.sliderSelected = document.createElement('div');
				this.sliderSelected.className = 'sliderSelected';
				this.sliderBar.appendChild(this.sliderSelected);
			}

			if (minSlider)
			{
				this.valueMin = parseInt(this.options.valueMin, 10);

				this.sliderMin = document.createElement('img');
				this.sliderMin.className = 'sliderBall';
				this.sliderMin.src = getPreloadImage(sliderBallImg);
				imageHoverSwap(this.sliderMin, sliderBallImg, sliderBallImgHover);
				this.sliderBar.appendChild(this.sliderMin);
				
				if (!this.options.noLabels)
				{
					this.sliderMinLabel = document.createElement('div');
					this.sliderMinLabel.className = 'sliderLabel';
					this.sliderMinLabel.appendChild(document.createTextNode(''));
					this.sliderBar.appendChild(this.sliderMinLabel);
				}

				this.sliderSnap(this.sliderMin);

				addEvent(this.sliderMin, 'mousedown', this.sliderStart.bind(this, this.sliderMin));
				this.sliderMin.ondragstart = function() { return false; }
			}

			if (maxSlider)
			{
				this.valueMax = parseInt(this.options.valueMax, 10);

				this.sliderMax = document.createElement('img');
				this.sliderMax.className = 'sliderBall';
				this.sliderMax.src = getPreloadImage(sliderBallImg);
				imageHoverSwap(this.sliderMax, sliderBallImg, sliderBallImgHover);
				this.sliderBar.appendChild(this.sliderMax);
				
				if (!this.options.noLabels)
				{
					this.sliderMaxLabel = document.createElement('div');
					if (this.sliderMinLabel)
					{
						// higher positioning than first label, add extra padding for sliderControl element
						this.sliderMaxLabel.className = 'sliderSecondLabel';
						this.element.className += ' doubleLabel';
					}
					else
					{
						this.sliderMaxLabel.className = 'sliderLabel';
					}
					this.sliderMaxLabel.appendChild(document.createTextNode(''));
					this.sliderBar.appendChild(this.sliderMaxLabel);
				}

				this.sliderSnap(this.sliderMax);

				addEvent(this.sliderMax, 'mousedown', this.sliderStart.bind(this, this.sliderMax));
				this.sliderMax.ondragstart = function() { return false; }
			}

			if (this.options.rangeLabels)
			{
				this.createLabels();
			}
			else
			{
				this.createTicks(totalSteps);
			}

			// append clearing element
			var clear = document.createElement('div');
			clear.style.clear = 'both';
			this.element.appendChild(clear);

			addEvent(this.sliderArea, 'click', this.sliderClick.bind(this));

			addEvent(this.element, 'mousemove', this.sliderMove.bind(this));
			addEvent(document, 'mouseup', this.sliderStop.bind(this));

			addCleanupHandler(this, ['maxSelect', 'minSelect', 'slider', 'element', 'options']);

			this.initialized = true;
		}
	},
	update: function()
	{
		this.initialized = false;

		if (this.minSelect)
			this.valueMin = Math.max(this.minSelect.selectedIndex, this.min - this.showLower);

		if (this.maxSelect)
			this.valueMax = this.maxSelect.selectedIndex ? this.maxSelect.selectedIndex + this.showLower : this.max + this.showHigher;

		this.sliderSnap(this.sliderMin, this.sliderMax);

		this.initialized = true;
	},
	createTicks: function(totalSteps)
	{
		// reduce steps
		var tickStep = 1;
		if (totalSteps > this.maxTicks)
		{
			var i = 0, prime = [2,3,5,7,11,13,17,19,23], _totalSteps = totalSteps; 
			while (_totalSteps > this.maxTicks && prime[i] <= this.maxTicks)
			{
				if (_totalSteps % prime[i])
					i++;
				else
				{
					_totalSteps /= prime[i];
					tickStep *= prime[i];
				}
			}
		}

		var tickSize = this.tickwidth * tickStep;

		// create ticks
		var value, width, totalWidth = 0;
		var select = this.minSelect || this.maxSelect;
		var tick, span;
		var initialMargin = (this.showLower + 1) * this.sliderBallRadius - 2;
		for (var i = 0; i <= totalSteps; i+=tickStep)
		{
			tick = document.createElement('div');
			tick.className = 'sliderTick';

			if (i == 0)
				tick.style.marginLeft = initialMargin + 'px';

			if (i == totalSteps)
			{
				// relies on overflow
				tick.style.width = this.sliderBallRadius + 'px';
			}
			else
			{
				width = Math.round(i * this.tickwidth + tickSize - totalWidth);
				tick.style.width = width + 'px';
				totalWidth += width;
			}

			span = document.createElement('span');

			// add click event
			addEvent(span, 'click', this.sliderSet.bind(this, 2 + initialMargin + i * this.tickwidth));

			value = this.min + i * this.step;

			// override value to label for selects
			if (select)
				value = select.options[value].text;

			span.appendChild(document.createTextNode(value));

			// ugly hack to get some form of centering
			span.style.left = (-2 * value.length) + 'px';

			tick.appendChild(span);

			this.element.appendChild(tick);
		}
	},
	createLabels: function()
	{
		var i = 0, labelData, values = [0, 0], j = 0, valueRange;

		var tick = document.createElement('div');
		tick.className = 'sliderTick rangeLabel';
		tick.style.marginLeft = ((this.showLower + 1) * this.sliderBallRadius - 2) + 'px';

		// IE is stupid and doesn't clone empty textnodes
		tick.appendChild(document.createTextNode(' '));

		var label, labelData, width, totalWidth = 0, totalRange = 0;
		for (var i = 0; i < this.options.rangeLabels.length; i++)
		{
			labelData = this.options.rangeLabels[i];

			if (this.minSelect)
			{
				for (;j < this.minSelect.options.length; j++)
				{
					if (this.minSelect.options[j].value == '' || this.minSelect.options[j].value != labelData[0])
						continue;

					values = [j, j];

					for(;j < this.minSelect.options.length; j++)
					{
						if (this.minSelect.options[j].value == labelData[1])
							break;

						values[1]++;
					}

					break;
				}
			}
			else
			{
				values = labelData;
			}

			valueRange = (values[1] - values[0]) / this.step;
			totalRange += valueRange;

			// FIXME: q&d hack to support showHigher for labels
			if (this.minSelect && values[1] == this.minSelect.options.length && this.showHigher)
			{
				totalRange--;
				totalWidth -= this.sliderBallRadius;
			}

			label = tick.cloneNode(true);
			width = Math.round(totalRange * this.tickwidth - totalWidth);
			label.style.width = (width - 7) + 'px'; // allow for padding
			label.firstChild.nodeValue = labelData[2];

			totalWidth += width;

			addEvent(label, 'click', this.labelClick.bind(this, values[0], values[1]));

			this.element.appendChild(label);

			if (i == 0)
				tick.style.marginLeft = 0;
		}

		// laatste 'tick'
		tick.className = 'sliderTick';
		tick.firstChild.nodeValue = this.showHigher ? String.fromCharCode(8734) : '';

		this.element.appendChild(tick.cloneNode(true));
	},
	sliderStart: function(slider, e)
	{
		this.cx = parseInt(slider.style.left);
		this.sx = e.clientX;
		this.drag = slider;

		e.preventDefault();
	},
	sliderMove: function(e)
	{
		if (this.drag)
		{
			var nx = this.cx - this.sx + e.clientX;
			if (nx < 0) nx = 0;
			if (nx > this.maxX) nx = this.maxX;
			this.drag.style.left = nx + 'px';

			this.sliderOnChange(this.drag);
		}
	},
	sliderClick: function(e)
	{
		var target = e.target || e.srcElement;

		if (this.drag || target == this.sliderMin || target == this.sliderMax)
		{
			e.preventDefault();
			return false;
		}

		var nx = e.layerX || e.offsetX || 0;

		while (target != this.sliderArea)
		{
			nx += target.offsetLeft;
			target = target.parentNode;
		}

		this.sliderSet(nx);
	},
	sliderSet: function(nx)
	{
		nx -= this.sliderBallRadius;

		if (nx < 0) nx = 0;
		if (nx > this.maxX) nx = this.maxX;

		var selectedSlider = this.sliderMin || this.sliderMax;

		if (this.sliderMin && this.sliderMax)
		{
			var sliderMinPos = parseInt(this.sliderMin.style.left);

			if (sliderMinPos < nx)
			{
				var sliderMaxPos = parseInt(this.sliderMax.style.left);
				if (sliderMaxPos < nx || sliderMaxPos - nx < nx - sliderMinPos)
					selectedSlider = this.sliderMax;
			}
		}

		selectedSlider.style.left = nx + 'px';

		this.sliderOnChange(selectedSlider, true);
	},
	labelClick: function(min, max)
	{
		if (this.sliderMin)
			this.valueMin = min;

		if (this.sliderMax)
			this.valueMax = max;

		this.sliderSnap(this.sliderMin, this.sliderMax);
	},
	sliderStop: function(e)
	{
		if (this.drag)
		{
			var slider = this.drag;
			this.drag = false;
			this.sliderSnap(slider);
		}
	},
	sliderSnap: function()
	{
		var slider, value, left;
		for (var i = 0; i < arguments.length; i++)
		{
			if ((slider = arguments[i]))
			{
				value = slider == this.sliderMin ? this.valueMin : this.valueMax;

				if (value < this.min)
					left = 0;
				else if (value > this.max)
					left = this.maxX;
				else
					left = Math.round(((value - this.min) / this.step) * this.tickwidth + this.showLower * this.sliderBallRadius);

				slider.style.left = left + 'px'
			}
		}

		this.setSelection();
	},
	setSelection: function()
	{
		var left = this.sliderBallRadius, right, label, l;

		if (this.sliderMin || this.lowValue !== null)
		{
			if (this.sliderMin)
				left += parseInt(this.sliderMin.style.left);

			if (this.minSelect)
			{
				label = this.minSelect.options[this.valueMin].text;

				this.minSelect.selectedIndex = this.valueMin;
				if (this.minSelect.onchange && this.initialized)
					this.minSelect.onchange();
			}
			else
				label = this.valueMin;

			if (this.sliderMinLabel)
			{
				this.sliderMinLabel.firstChild.nodeValue = label;

				// some centering
				l = this.sliderMinLabel.firstChild.nodeValue.length;
				this.sliderMinLabel.style.left = (left - (l > 3 ? 3 : 2) * l) + 'px';
			}
		}

		if (this.sliderSelected)
			this.sliderSelected.style.left = left + 'px';

		if (this.sliderMax || this.highValue !== null)
		{
			if (this.sliderMax)
				right = parseInt(this.sliderMax.style.left) + this.sliderBallRadius;
			else
				right = this.maxX + this.sliderBallRadius;

			if (this.sliderSelected)
				this.sliderSelected.style.width = Math.max(0, right - left) + 'px';

			if (this.maxSelect)
			{
				label = this.maxSelect.options[this.valueMax-this.showLower].text;

				this.maxSelect.selectedIndex = this.valueMax-this.showLower;
				if (this.maxSelect.onchange && this.initialized)
					this.maxSelect.onchange();
			}
			else
				label = this.valueMax;

			if (this.sliderMaxLabel)
			{
				this.sliderMaxLabel.firstChild.nodeValue = label;

				// some centering
				l = this.sliderMaxLabel.firstChild.nodeValue.length;
				this.sliderMaxLabel.style.left = (right - (l > 3 ? 3 : 2) * l) + 'px';
			}
		}
		else
		{
			if (this.sliderSelected)
			{
				right = Math.max(0, this.maxX - left + this.sliderBallRadius);
				this.sliderSelected.style.width = right + 'px';
			}
		}

		// special onmove handler
		if ('onmove' in this.options)
			this.options.onmove(left, right);
	},
	sliderOnChange: function(slider, snap)
	{
		var value = this.min + ((parseInt(slider.style.left) - this.showLower * this.sliderBallRadius) / this.tickwidth) * this.step;

		if (slider == this.sliderMin)
		{
			if (value < this.min)
				value = this.min - this.showLower * this.step;
			else
				value = Math.round(value);

			if (this.sliderMax && value >= this.valueMax)
			{
				value = this.valueMax - this.step;
				snap = true;
			}

			this.valueMin = value;
		}
		else
		{
			if (value > this.max)
				value = this.max + this.showHigher * this.step;
			else
				value = Math.round(value);

			if (this.sliderMin && value <= this.valueMin)
			{
				value = this.valueMin + this.step;
				snap = true;
			}

			this.valueMax = value;
		}

		if (snap)
			this.sliderSnap(slider);
		else
			this.setSelection();
	}
});

function FancySelectList(options)
{
	this.options = options;

	this.element = null;
	this.select = null;

	this.multiple = false;
	this.hideUnpopulars = false;
	this.hasUnpopulars = false;

	this.items = [];
	this.selected = null;

	this.init();
}
Object.extend(FancySelectList.prototype,
{
	init: function()
	{
		if (this.options)
		{
			if (this.options.select)
			{
				this.select = this.options.select;
				this.multiple = this.select.multiple;
				this.hideUnpopulars = hasClass(this.select, 'hideunpopular');

				this.element = document.createElement('div');

				var ul = document.createElement('ul');
				this.element.appendChild(ul);

				var li, cb, label, title, option;
				for (var i = 0; i < this.select.length; i++)
				{
					option = this.select.options[i];

					if (option && option.value != '')
					{
						title = option.getAttribute('title') || option.text;

						li = document.createElement('li');

						if (this.multiple)
						{
							cb = document.createElement('input');
							cb.type = 'checkbox';
							cb.id = this.select.name + '_' + i;
							cb.onclick = this.check.bind(this,i,cb);
							cb.checked = option.selected;
							li.appendChild(cb);
						}

						label = document.createElement('label');

						if (this.multiple)
						{
							label.htmlFor = cb.id;
							this.items[i] = cb;
						}
						else
						{
							label.onclick = this.check.bind(this,i,label);
							this.items[i] = label;
						}

						label.innerHTML = title;

						if (option.selected)
						{
							addClass(li, 'selected');

							if (!this.multiple)
								this.selected = li;
						}

						if (this.hideUnpopulars && hasClass(option, 'unpopular'))
						{
							addClass(li, 'unpopular');
							if (!option.selected)
								this.hasUnpopulars = true;
						}

						li.appendChild(label);

						ul.appendChild(li);
					}
				}

				if (this.hasUnpopulars)
				{
					// FIXME: add arrow-image
					this.unPopularToggle = document.createElement('span');
					this.unPopularToggle.className = 'toggleUnpopular';
					this.unPopularToggle.appendChild(document.createTextNode(''));
					this.unPopularToggle.onclick = this.toggleUnpopular.bind(this);
					this.element.appendChild(this.unPopularToggle);
					this.toggleUnpopular();
				}
			}

			addCleanupHandler(this, ['unPopularToggle', 'selected', 'items', 'select', 'element', 'options']);
		}
	},
	update: function()
	{
		this.selected = null;

		var cb, option;
		for (var i = 0; i < this.select.length; i++)
		{
			option = this.select.options[i];
			cb = this.items[i];

			if (cb && option.value != '')
			{
				if (this.multiple)
					cb.checked = option.selected;

				if (option.selected)
				{
					addClass(cb.parentNode, 'selected');

					if (!this.multiple)
						this.selected = cb.parentNode;
				}
				else
					removeClass(cb.parentNode, 'selected');
			}
		}
	},
	check: function(i, cb)
	{
		if (!this.multiple && this.selected == cb.parentNode)
			return;

		var checked = this.multiple ? cb.checked : true;

		this.select.options[i].selected = checked;

		if (checked)
		{
			addClass(cb.parentNode, 'selected');

			if (!this.multiple)
			{
				if (this.selected)
					removeClass(this.selected, 'selected');

				this.selected = cb.parentNode;
			}
		}
		else
			removeClass(cb.parentNode, 'selected');

		if (this.select.onchange)
			this.select.onchange();
	},
	toggleUnpopular: function()
	{
		if (hasClass(this.element, 'hideUnpopulars'))
		{
			removeClass(this.element, 'hideUnpopulars');
			this.unPopularToggle.firstChild.nodeValue = 'Toon populaire keuzes';
		}
		else
		{
			addClass(this.element, 'hideUnpopulars');
			this.unPopularToggle.firstChild.nodeValue = 'Toon alle keuzes';
		}
	}
});

function FancyTextRangeSelect(options)
{
	this.options = options;
	this.element = null;
	this.items = [];

	this.minSelect = null;
	this.maxSelect = null;
	this.showLower = 0;
	this.showHigher = 0;

	this.selected = null;

	this.init();
}
Object.extend(FancyTextRangeSelect.prototype,
{
	init: function()
	{
		if (this.options)
		{
			if (this.options.minSelect || this.options.maxSelect)
			{
				this.minSelect = this.options.minSelect;
				this.maxSelect = this.options.maxSelect;

				this.showLower = this.options.showLower || 0;
				this.showHigher = this.options.showHigher || 0;

				this.element = document.createElement('div');

				var ul = document.createElement('ul');
				this.element.appendChild(ul);

				var li, title, option, option2, label;
				for (var i = 0, j = -1; i < this.minSelect.options.length - this.showHigher; i++)
				{
					option = this.minSelect.options[i];

					if (option && (option.value != '' || option.text))
					{
						title = option.getAttribute('title') || option.text;
						if (j < 0 && this.showLower)
						{
							j = 0;
						}
						else
						{
							j = i + 1 - this.showLower;
							if ((option2 = this.maxSelect.options[j]))
								title += ' t/m ' + (option2.getAttribute('title') || option2.text);
						}

						li = document.createElement('li');

						label = document.createElement('label');
						label.onclick = this.check.bind(this,i,j,li);
						label.innerHTML = title;

						li.appendChild(label);

						if (!this.selected && option.selected)
						{
							this.selected = li;
							addClass(li, 'selected');
						}

						this.items[i] = li;

						ul.appendChild(li);
					}
				}

				if (this.showHigher)
				{
					j = this.maxSelect.options.length - 1;
					if ((option = this.maxSelect.options[j]))
					{
						title = option.getAttribute('title') || option.text;

						li = document.createElement('li');

						label = document.createElement('label');
						label.onclick = this.check.bind(this,0,j,li);
						label.innerHTML = title;

						li.appendChild(label);

						if (!this.selected && option.selected)
						{
							this.selected = li;
							addClass(li, 'selected');
						}

						this.items[i] = li;

						ul.appendChild(li);
					}
				}
			}

			addCleanupHandler(this, ['selected', 'items', 'maxSelect', 'minSelect', 'options']);
		}
	},
	update: function()
	{
		if (this.selected)
		{
			removeClass(this.selected, 'selected');
			this.selected = null;
		}

		var option;
		for (var i = 0, j = -2; i < this.minSelect.options.length; i++)
		{
			option = this.minSelect.options[i];

			if (option && option.value != '')
			{
				if (j < -1 && this.showLower)
					j = -1;
				else
					j = i - this.showLower;

				if (option.selected)
				{
					this.selected = this.items[i];
					addClass(this.selected, 'selected');
					break;
				}
			}
		}

		if (this.showHigher && !this.selected)
		{
			if ((option = this.maxSelect.options[i - this.showLower]) && option.selected)
			{
				this.selected = this.items[i];
				addClass(this.selected, 'selected');
			}
		}
	},
	check: function(i, j, li)
	{
		if (li != this.selected)
		{
			if (this.selected)
				removeClass(this.selected, 'selected');

			this.selected = li;
			addClass(this.selected, 'selected');

			this.minSelect.selectedIndex = i;
			this.maxSelect.selectedIndex = j;

			if (this.minSelect.onchange)
				this.minSelect.onchange();
		}
	}
});

function KoopInfoFilterForm(formId,catId,subCatId)
{
	this.filters = {};
	this.formId = formId;
	this.catId = catId;
	this.subCatId = subCatId;

	this.form = null;
	this.initialized = false;

	this.ajax = null;
	this.ajaxTimeout = null;
	this.ajaxPending = false;
	this.ajaxBusy = false;
	this.requestDelay = 300;

	this.productListing = null;
	this.overlay = null;
	this.fancyElements = [];
}
Object.extend(KoopInfoFilterForm.prototype,
{
	init: function()
	{
		this.form = document.getElementById(this.formId);
		if (this.form)
		{
			addClass(this.form, 'jsEnabled');

			if (this.koopwijzer)
				this.initKoopwijzer();

			this.productListing = document.getElementById('productListing');

			// ajaxify; async
			this.ajax = new Ajax();
			if (this.ajax.getRequestObject(true))
			{
				// check hash
				HashChecker().setCallback(this.hashChange.bind(this), 'filter', true);

				this.form.onsubmit = this.ajaxify.bind(this);
			}

			this.addOnchangeHandlers();

			if (!this.ajaxBusy)
			{
				this.ajaxifyListing();
				this.showFilters();
			}

			addCleanupHandler(this, ['ajax', 'fancyElements', 'overlay', 'productListing',
				'summaryFunctions', 'steps', 'filters', 'form']
			);
		}
	},
	hashChange: function(hash)
	{
		this.sendRequest(hash, 'fromHash=1');
	},
	sendRequest: function(hash, parms, e)
	{
		// first cancel all ajax calls
		if (this.ajaxTimeout)
		{
			clearTimeout(this.ajaxTimeout)
			this.ajaxTimeout = null;
		}

		this.ajaxPending = false;
		this.ajaxBusy = true;

		// FIXME: hide all filters?
		if (this.initialized)
		{
		}
		else
		{
			this.productListing.innerHTML = '';
		}

		this.showOverlay();
		this.hideUpdateNote();

		var ajaxSuccess = this.ajax.sendRequest(
			getXmlHttpUrl('koopinfo', 'catfilters', (this.koopwijzer ? 'koopwijzer' : 'search'), 'catId=' + this.catId + (hash !== false ? '&currFilters=' + encodeURIComponent(hash) : '') + (parms ? '&' + parms : '')),
			{
				type: 'json',
				method: 'GET',
				async: true,
				handler: this.handleAjaxResponse.bind(this)
			}
		);

		if (e)
		{
			e.preventDefault();
			return false;
		}

		return !ajaxSuccess;
	},
	ajaxify: function()
	{
		return this.sendRequest(false, getQueryString(this.form));
	},
	addOnchangeHandlers: function()
	{
		// add onchange handlers to all form elements
		var element, eventType;
		for (var i = 0; i < this.form.elements.length; i++)
		{
			element = this.form.elements[i];

			if (element.name)
			{
				eventType = '';
				switch (element.tagName.toLowerCase())
				{
					case 'input':
						switch (element.type.toLowerCase())
						{
							case 'text':
								eventType = 'keyup';
								element.currentValue = element.value;
							break;
							case 'radio':
							case 'checkbox':
								eventType = 'click';
								// Fix IE events
								/*@cc_on
									if (element.parentNode.tagName.toLowerCase() == 'label')
									{
										addEvent(element.parentNode, 'click', this.fixIELabelHandling.bind(this, element));
										this.addSimpleEvent(element, 'onclick', this.fixLabelClass);
										toggleLabelClass(element);
									}
								@*/
							break;
						}
					break;
					case 'textarea':
						eventType = 'keyup';
					break;
					case 'select':
						eventType = 'change';
					break;
				}

				if (eventType)
					this.addSimpleEvent(element, 'on'+eventType, this.ajaxTimer.bind(this));
			}
		}
	},
	fixIELabelHandling: function(element, e)
	{
		if (e.target.tagName && e.target.tagName.toLowerCase() == 'img')
		{
			element.checked = element.type.toLowerCase() == 'checkbox' ? !element.checked: true;
			element.onclick();
		}
	},
	fixLabelClass: function()
	{
		var elements = this.type.toLowerCase() == 'checkbox' ? [this] : this.form.elements[this.name];
		Array.forEach(elements, toggleLabelClass);
	},
	addSimpleEvent: function(element, event, func)
	{
		if (element[event])
		{
			var oldFunction = element[event];
			element[event] = function()
			{
				oldFunction.apply(this);
				func.apply(this);
			}
		}
		else
			element[event] = func;
	},
	ajaxTimer: function(e)
	{
		// special case for text-inputs
		var target = e && (e.target || e.srcElement);
		if (target && target.nodeName.toLowerCase() == 'input' && target.type.toLowerCase() == 'text')
		{
			if (target.value == target.currentValue)
				return;

			target.currentValue = target.value;

			if (target.value.length && target.value.length < 3)
				return;
		}

		if (this.ajaxBusy)
		{
			this.ajaxPending = true;
		}
		else
		{
			if (this.ajaxTimeout)
			{
				clearTimeout(this.ajaxTimeout)
				this.ajaxTimeout = null;
			}

			this.showOverlay();
			this.hideUpdateNote();

			this.ajaxTimeout = setTimeout(this.form.onsubmit.bind(this.form), this.requestDelay);
		}
	},
	handleAjaxResponse: function(response)
	{
		if (this.ajaxPending)
		{
			// restart timer; don't update results
			this.ajaxPending = false;
			this.ajaxBusy = false;
			this.ajaxTimer();
		}
		else
		{
			var data = checkJsonResponse(response);
			if (data)
			{
				this.setProductListing(data['html']);

				this.showUpdateNote(data['html']);

				if ('hash' in data)
					HashChecker().setHash(data['hash'], 'filter');

				if ('querystring' in data)
					this.updateForm(data['querystring']);
			}
			else
			{
				// FIXME: mooiere foutmelding?
				this.setProductListing('<p class="error">Er is iets foutgegaan...<\/p>');
			}

			this.ajaxBusy = false;
		}

		// show default filters after initializing
		if (!this.initialized)
			this.showFilters();
	},
	showOverlay: function()
	{
		if (this.productListing)
		{
			if (!this.overlay)
			{
				this.overlay = document.createElement('div');
				this.overlay.className = 'overlay';

				var img = document.createElement('img');
				img.src = ImgURL + 'g/imageviewer/loading.gif';
				this.overlay.appendChild(img);

				this.productListing.parentNode.style.position = 'relative';
				if (is.ie && ieVersion() < 7) this.productListing.parentNode.style.zoom = 1;
				this.productListing.parentNode.appendChild(this.overlay);
			}

			this.overlay.style.top = this.productListing.offsetTop + 'px';
			this.overlay.style.left = this.productListing.offsetLeft + 'px';
			this.overlay.style.width = this.productListing.offsetWidth + 'px';
			this.overlay.style.height = this.productListing.offsetHeight + 'px';
			this.overlay.style.display = 'block';

			addClass(this.productListing, 'opaque');
		}
	},
	setProductListing: function(html)
	{
		if (this.productListing)
		{
			this.productListing.innerHTML = html;
			this.ajaxifyListing();

			if (this.overlay)
			{
				this.overlay.style.display = 'none';
				removeClass(this.productListing, 'opaque');
			}
		}
	},
	ajaxifyListing: function()
	{
		// ajaxify links in HTML
		var links = this.productListing.getElementsByTagName('a'), i = links.length, link, j, get, parms;
		while (i--)
		{
			if ((j = links[i].href.indexOf('?currFilters=')) > -1)
			{
				parms = [];

				if (this.subCatId)
					parms.push('subCatId=' + this.subCatId);

				get = this.parseGetString(links[i].href.substr(j+1));
				['orderField', 'orderSort', 'page'].forEach(
					function(el)
					{
						if (el in get)
							parms.push(el + '=' + get[el]);
					}
				);

				addEvent(links[i], 'click', this.sendRequest.bind(this, decodeURIComponent(get['currFilters']), parms.join('&')));
			}
		}
	},
	showUpdateNote: function(html)
	{
		// retrieve number of results from html comment
		var numResults = /<!-- num_results:([0-9]+) -->/.exec(html);
		numResults = numResults ? numResults[1] : 0;

		if (!this.updateNote)
		{
			this.updateNote = document.createElement('div');

			addClass(this.updateNote, 'updatenote');
			if (this.koopwijzer)
				addClass(this.updateNote, 'updatenoteKoopwijzer');
			
			addClass(this.updateNote, 'updatenoteHide');

			document.body.appendChild(this.updateNote);
			addEvent(this.updateNote, 'click', this.clickUpdateNote.bind(this));
		}		
		
		var message = '';
		if (numResults == 0)
		{
			message = '<div><span class="numResults">Er zijn helaas geen</span> producten gevonden.' + (this.koopwijzer ? '<br>' : '');
			message += '</div>';
		}
		else
		{
			message = numResults + ' producten';
			if (numResults == 1)
				message = 'één product';
			
			message = '<div><span class="numResults">' + message + '</span> gevonden. ' + (this.koopwijzer ? '<br>' : '');
			message += 'Klik hier voor de resultaten.</div>';
		}
		
		this.updateNote.innerHTML = message;
		
		var listEl = document.getElementById("productList"); // werkt niet met getById?

		if (!listEl)
		{
			listEl = getById("productListing").firstChild;
		}

		this.updateNote.style.left = (getOffsetLeft(this.productListing) + (this.koopwijzer ? 0: 50) ) + 'px';

		var listBottom = getOffsetTop(listEl) + listEl.offsetHeight;
		var pageDimensions = getPageDimensions();
			
		var topPosition = 0;
		if (pageDimensions['offsetY'] > listBottom)
			topPosition = pageDimensions['offsetY'] + Math.round(pageDimensions['availHeight']/2);

		this.updateNote.style.top = topPosition + 'px';

		// niet weergeven als hij buiten de content valt of als alle resultaten op het scherm staan
		var content = getById("content");
			
		if (topPosition > 0 && (getOffsetTop(content) + content.offsetHeight) > (topPosition + 100))
			removeClass(this.updateNote, 'updatenoteHide');
	},
	hideUpdateNote: function()
	{
		if (this.updateNote)
			addClass(this.updateNote, 'updatenoteHide');
	},
	clickUpdateNote: function()
	{
		window.scrollTo(0, 0);
		this.hideUpdateNote();
	},
	// FIXME: should this be a generic function?
	parseGetString: function(string)
	{
		// remove fragment
		var component = string.indexOf('#');
		if (component > -1)
			string = string.substr(0, component);

		var components = string.split('&'), i = components.length, get = {};

		while (i--)
		{
			component = components[i].split('=');
			get[component[0]] = component.length > 1 ? component[1] : '';
		}

		return get;
	},
	updateForm: function(querystring)
	{
		this.form.reset();

		var name, value, element, i;
		for (var name in querystring)
		{
			if (typeof querystring[name] == 'object' && !(querystring[name] instanceof Array))
                                continue;

			// fallback for array-like elements that have '[]'
			if (!(element = this.form.elements[name]) && querystring[name] instanceof Array)
			{
				element = this.form.elements[name+'[]'];
			}

			if (element)
			{
				if (!element.length)
				{
					if (element.tagName.toLowerCase() == 'textarea')
						element = element.options;
					else
						element = [element];
				}

				// convert values to strings
				if (querystring[name] instanceof Array)
				{
					for (i = 0; i < querystring[name].length; i++)
						querystring[name][i] = '' + querystring[name][i];
				}
				else
				{
					querystring[name] = '' + querystring[name];
				}
				
				for (i = 0; i < element.length; i++)
				{
					switch (element[i].tagName.toLowerCase())
					{
						case 'input':
							switch (element[i].type.toLowerCase())
							{
								case 'hidden':
									element[i].value = querystring[name];
								continue;

								case 'text':
									element[i].value = querystring[name];
								break;
								case 'radio':
								case 'checkbox':
									if (querystring[name] instanceof Array)
									{
										if (querystring[name].indexOf(element[i].value) > -1)
											element[i].checked = true;
									}
									else
									{
										if (element[i].value === querystring[name])
											element[i].checked = true;
									}

									/*@cc_on
										if (element[i].parentNode.tagName.toLowerCase() == 'label')
										{
											toggleLabelClass(element[i]);
										}
									@*/
								break;
							}
						break;
						case 'textarea':
							element[i].value = querystring[name];
						break;
						case 'option':
							value = hasAttribute(element[i], 'value') ? element[i].value : element[i].text;

							if (querystring[name] instanceof Array)
							{
								if (querystring[name].indexOf(value) > -1)
									element[i].selected = true;
							}
							else
							{
								if (value === querystring[name])
									element[i].selected = true;
							}
						break;
					}
				}

				// get the parent of this form-element to show the filter if it is hidden
				element = element[0].parentNode;
				while (element != document && !hasClass(element, 'productFilterItem'))
					element = element.parentNode;

				if (element && element.id)
					this.show(element.id);
			}
		}

		for (var i = 0; i < this.fancyElements.length; i++)
		{
			this.fancyElements[i].update();
		}
	},
	addFilter: function(id, isDefault, options)
	{
		var filter = document.getElementById(id);
		if (filter)
		{
			this.filters[id] = {
				element: filter,
				isDefault: isDefault,
				hidden: true,
				options: options
			};

			filter.style.display = 'none';
		}
	},
	showFilters: function(e)
	{
		var showAll = false;
		if (this.koopwijzer)
		{
			showAll = true;
		}
		else
		{
			showAll = e && (e.target || e.srcElement);

			if (showAll)
			{
				do
				{
					if (hasClass(showAll, 'showAll'))
					{
						showAll.parentNode.removeChild(showAll);
						break;
					}
				}
				while ((showAll = showAll.parentNode));

				showAll = true;
			}
		}

		var hasHidden = false;
		for (var id in this.filters)
		{
			if (this.filters[id].hidden)
			{
				if (showAll || this.filters[id].isDefault)
					this.show(id);
				else
					hasHidden = true;
			}
		}

		// check if there are still any hidden filters
		if (hasHidden && !this.initialized)
		{
			var showAllDiv = HTMLBuilder().built({n:'div',a:{className:'showAll'},c:[{n:'img',a:{src:KiImgURL+'g/filterbox/arrow_down_blue.gif'}},{n:'span',c:[{n:'#text',v:'Toon alle filters'}]}]});
			addEvent(showAllDiv, 'click', this.showFilters.bind(this));
			this.form.appendChild(showAllDiv);
		}

		// execute summary functions for koopwijzer
		if (this.summaryFunctions)
		{
			this.summaryFunctions.forEach( function(func){ func(); } );
		}

		this.initialized = true;
	},
	show: function(id)
	{
		var options, filterType, fancyElement, defaultElement;

		if (id in this.filters && this.filters[id].hidden)
		{
			options = this.filters[id]['options'];
			filterType = options ? options['filterType'] : 'none';
			fancyElement = null;
			defaultElement = this.filters[id]['element'];

			switch (filterType)
			{
				case 'single_slider':
				case 'double_slider':
					fancyElement = new FancySlider(
						{
							'width': options['width'] || (this.koopwijzer ? 516: 194),
							'minSelect': options['minSelect'] && this.form.elements[options['minSelect']],
							'maxSelect': options['maxSelect'] && this.form.elements[options['maxSelect']],
							'showLower': options['showLower'],
							'showHigher': options['showHigher'],
							'rangeLabels': options['rangeLabels'],
							'noLabels': options['noLabels']
						}
					);
				break;
				case 'multiselect':
					fancyElement = new FancySelectList(
						{
							'select': options['minSelect'] && this.form.elements[options['minSelect']]
						}
					);
				break;
				case 'text_range':
					fancyElement = new FancyTextRangeSelect(
						{
							'minSelect': options['minSelect'] && this.form.elements[options['minSelect']],
							'maxSelect': options['maxSelect'] && this.form.elements[options['maxSelect']],
							'showLower': options['showLower'],
							'showHigher': options['showHigher']
						}
					);
				break;
				case 'custom':
					fancyElement = new window[options['filterClass']](this);
				break;
				case 'range':
				case 'select':
					// do nothing
				default:
					getElementsByClassName(
						'filterForm',
						'div',
						defaultElement,
						function(el)
						{
							el.style.display='block';
						}
					);
			}

			if (fancyElement)
			{
				if (this.koopwijzer)
					defaultElement.parentNode.insertBefore(fancyElement.element, defaultElement);
				else
					first_child(defaultElement).appendChild(fancyElement.element);

				this.fancyElements.push(fancyElement);
			}

			this.filters[id].hidden = false;

			if (!this.koopwijzer)
				defaultElement.style.display = '';
		}
	},
	getHidden: function()
	{
		var hidden = [];

		for (var id in this.filters)
		{
			if (this.filters[id].hidden)
				hidden.push(id);
		}

		return hidden;
	},
	showHidden: function(div)
	{
		div.parentNode.removeChild(div);

		var hidden = this.getHidden();
		if (hidden.length)
			this.show.apply(this, hidden);
	}
});

function initKoopwijzerIndexForm(options)
{
	var form = document.forms['koopwijzerForm'];
	if (form)
	{
		addClass(form, 'jsEnabled');
		var parent = form.elements[options['minSelect']].parentNode;
		var slider = new FancySlider(
			{
				'width': parent.parentNode.offsetWidth - 10,
				'minSelect': form.elements[options['minSelect']],
				'maxSelect': form.elements[options['maxSelect']],
				'showLower': options['showLower'],
				'showHigher': options['showHigher'],
				'rangeLabels': options['rangeLabels']
			}
		);
		parent.parentNode.insertBefore(slider.element, parent);
	}
}

function KoopwijzerForm(formId,catId)
{
	this.koopwijzer = true;
	this.steps = [];
	this.summaryFunctions = [];

	this.formId = formId;
	this.catId = catId;
	this.step = 0;
}
KoopwijzerForm.prototype = new KoopInfoFilterForm();
Object.extend(KoopwijzerForm.prototype,
{
	initKoopwijzer: function()
	{
		// preloads
		preload('koopwijzer_min', KiImgURL + 'g/koopwijzer/koopwijzer_min.gif');
		preload('koopwijzer_plus', KiImgURL + 'g/koopwijzer/koopwijzer_plus.gif');
		preload('koopwijzer_min_hover', KiImgURL + 'g/koopwijzer/koopwijzer_min_hover.gif');
		preload('koopwijzer_plus_hover', KiImgURL + 'g/koopwijzer/koopwijzer_plus_hover.gif');

		var steps = getElementsByClassName('koopwijzerBoxItem', 'div', this.form), i = 0, step, img, summary;
		var content, nav, p;
		while ((step = steps[i++]))
		{
			img = document.createElement('img');
			img.src = getPreloadImage('koopwijzer_plus');
			img.className = 'expand';
			img.onclick = this.setActive.bind(this, i, img);
			imageHoverSwap(img, 'koopwijzer_plus', 'koopwijzer_plus_hover');

			step.insertBefore(img, step.firstChild);

			content = getElementsByClassName('koopwijzerBoxContent', 'div', step);
			if (content.length)
			{
				content = content[0];

				nav = document.createElement('div');
				nav.className = 'nav';
				nav.style.display = 'none';

				p = document.createElement('p');
				if (i == 1)
				{
					p.className = 'prev_inactive';
				}
				else
				{
					p.className = 'prev_active';
					p.onclick = this.setActive.bind(this, i - 1, null);
				}
				p.appendChild(document.createTextNode('vorige stap'));
				nav.appendChild(p);

				p = document.createElement('p');
				if (i == steps.length)
				{
					p.className = 'next_inactive';
				}
				else
				{
					p.className = 'next_active';
					p.onclick = this.setActive.bind(this, i + 1, null);
				}
				p.appendChild(document.createTextNode('volgende stap'));
				nav.appendChild(p);

				step.nav = nav;

				content.appendChild(nav);

				if (this.summaryFunctions[i])
				{
					summary = document.createElement('span');
					summary.className = 'ellipsis summary';
					summary.appendChild(document.createTextNode(''));

					content.parentNode.insertBefore(summary, content.parentNode.firstChild);

					this.summaryFunctions[i] = this.wrapSummaryFunction(summary, this.summaryFunctions[i].bind(this));
				}
			}

			this.steps[i] = step;
		}

		// current step
		HashChecker().setCallback(this.setActive.bind(this), 'step');

		var currentStep = HashChecker().getHash('step');
		if (!currentStep)
		{
			// check for priceMin/priceMax GET vars
			var get = this.parseGetString(window.location.search.substr(1));
			if ('priceMin' in get && 'priceMax' in get)
				currentStep = 2;
			else
				currentStep = 1;
		}

		this.setActive(currentStep);
	},
	setActive: function(step, img)
	{
		// make sure step is a number
		step = parseInt(step, 10);
		if (!step || !this.steps[step])
			step = 1;

		var currentStep = this.steps[step];

		if (img)
		{
			if (currentStep.className == 'koopwijzerBoxItemActive')
			{
				currentStep.className = 'koopwijzerBoxItem';
				img.src = getPreloadImage('koopwijzer_plus');
				imageHoverSwap(img, 'koopwijzer_plus', 'koopwijzer_plus_hover');

				if (this.summaryFunctions[step])
					this.summaryFunctions[step]();
			}
			else
			{
				currentStep.className = 'koopwijzerBoxItemActive';
				img.src = getPreloadImage('koopwijzer_min');
				imageHoverSwap(img, 'koopwijzer_min', 'koopwijzer_min_hover');
			}
		}
		else
		{
			if (step != this.step)
			{
				var previousStep = this.step && this.steps[this.step];
				if (previousStep)
				{
					previousStep.className = 'koopwijzerBoxItem';
					previousStep.firstChild.src = getPreloadImage('koopwijzer_plus');
					imageHoverSwap(previousStep.firstChild, 'koopwijzer_plus', 'koopwijzer_plus_hover');
					if (previousStep.nav)
						previousStep.nav.style.display = 'none';
					if (this.summaryFunctions[this.step])
						this.summaryFunctions[this.step]();
				}

				this.step = step;

				currentStep.className = 'koopwijzerBoxItemActive';
				currentStep.firstChild.src = getPreloadImage('koopwijzer_min');
				imageHoverSwap(currentStep.firstChild, 'koopwijzer_min', 'koopwijzer_min_hover');
				if (currentStep.nav)
					currentStep.nav.style.display = 'block';

				if (this.initialized || step > 1)
				{
					// set hash
					HashChecker().setHash(step, 'step');

					// scroll into view
					(document.documentElement || document.body).scrollTop = getOffsetTop(currentStep);
				}
			}
		}
	},
	registerSummaryFunction: function(step, func)
	{
		this.summaryFunctions[step] = func;
	},
	wrapSummaryFunction: function(summary, func)
	{
		return function()
		{
			var summaryText = func();
			summary.firstChild.nodeValue = summaryText;
			summary.title = summaryText;
			ellipsis(summary);
		}
	}
});

function CouchSlider(koopwijzer)
{
	this.koopwijzer = koopwijzer;
	this.element = null;
	this.slider = null;
	this.couch = null;
	this.distance = null;
	this.advice = null;
	this.select = null;

	this.cx = 0;
	this.sx = 0;
	this.drag = false;

	this.init();
}
Object.extend(CouchSlider.prototype,
{
	init: function()
	{
		this.element = document.createElement('div');
		this.element.id = 'thaCouch';

		this.distance = document.createElement('img');
		this.distance.id = 'distance';
		this.distance.src = KiImgURL + 'g/koopwijzer/televisies/distance.png';
		this.element.appendChild(this.distance);

		this.couch = document.createElement('img');
		this.couch.id = 'couch';
		this.couch.src = KiImgURL + 'g/koopwijzer/televisies/couch.png';
		this.element.appendChild(this.couch);

		this.advice = document.createElement('p');
		this.advice.className = 'advice';
		this.element.appendChild(this.advice);

		this.select = this.koopwijzer.form.elements['distance'];
		this.slider = new FancySlider(
			{
				'width': 316,
				'minSelect': this.select,
				'noLabels': true,
				'onmove': this.sliderMove.bind(this)
			}
		);

		this.element.appendChild(this.slider.element);

		this.updateAdvice();

		// add onchange handler for slider
		this.koopwijzer.addSimpleEvent(this.select, 'onchange', this.updateAdvice.bind(this));

		// add onclick handler for size
		var size = this.koopwijzer.form.elements['size'], i = size.length;
		while (i--)
			this.koopwijzer.addSimpleEvent(size[i], 'onclick', this.updateAdvice.bind(this));

		// drag functionality for the couch
		addEvent(this.couch, 'mousedown', this.couchStart.bind(this));
		addEvent(this.element, 'mousemove', this.couchMove.bind(this));
		addEvent(document, 'mouseup', this.couchStop.bind(this));

		this.couch.ondragstart = function() { return false; }
		this.couch.style.cursor = 'pointer';

		addCleanupHandler(this, ['koopwijzer', 'select', 'element', 'distance', 'couch', 'advice', 'slider'], 'cleanUp');
	},
	update: function()
	{
		this.slider.update();
		this.updateAdvice();
	},
	updateAdvice: function()
	{
		var distance = Math.round(2 * parseFloat(getSelectedValue(this.select))) - 2;
		switch (getSelectedValue(this.koopwijzer.form.elements['size']))
		{
			case 'small':
				distance -= 1;
			break;
			case 'large':
				distance += 1;
			break;
		}

		if (distance < 0)
			distance = 0;
		else if (distance > 8)
			distance = 8;

		var dt = ['t/m 19"', '19"-22"', '22"-32"', '32"-37"', '37"-42"', '42"-47"', '47"-52"', '52"-63"', 'v.a. 63"'];

		this.advice.innerHTML = '<b>Advies:<\/b><br>Beelddiagonaal: ' + dt[distance];
	},
	couchStart: function(e)
	{
		this.cx = parseInt(this.couch.style.left) - 140 - this.slider.sliderBallRadius;
		this.sx = e.clientX;
		this.drag = true;

		e.preventDefault();
	},
	couchMove: function(e)
	{
		if (this.drag)
		{
			var nx = this.cx - this.sx + e.clientX;
			if (nx < 0) nx = 0;
			if (nx > this.slider.maxX) nx = this.slider.maxX;
			this.slider.sliderMin.style.left = nx + 'px';

			this.slider.sliderOnChange(this.slider.sliderMin);
		}
	},
	couchStop: function(e)
	{
		if (this.drag)
		{
			this.drag = false;
			this.slider.sliderSnap(this.slider.sliderMin);
		}
	},
	sliderMove: function(left, right)
	{
		// warning: presentational!
		this.couch.style.left = (left + 140) + 'px';
		this.distance.style.clip = 'rect(0,'+(left+15)+'px,92px,0)';
	}
});

// helper function to toggle the class of a checkbox or radiobutton's label parent; used for IE since it is a backwards browser
function toggleLabelClass(element)
{
	if (element.checked)
		addClass(element.parentNode, 'checked');
	else
		removeClass(element.parentNode, 'checked');
}
