function linkTitleInStatusbar(targets)
{
	addEventToTargets(targets, 'mouseover', showTitleInStatusbar, 'a');
	addEventToTargets(targets, 'mouseout', clearStatusbar, 'a');
};

function showTitleInStatusbar()
{
	if(this.title.length == 0)
		return;

	if(this.accessKey.length == 1)
	{
		window.status = this.title + ' - sneltoets: Alt + '+this.accessKey;
	}
	else
	{
		window.status = this.title + ' - ' + this.href;
	}
};

function clearStatusbar()
{
	window.status = '';
	return true;
};

var maxImageWidth = 560;
var maxImageHeight = 800;
var imagesToScale = [];
function scaleImages(targets)
{
	imagesToScale = getTargets(targets, 'ol div.message-content img');
	if(imagesToScale.length > 0)
		addEvent(window, 'load', _scaleImages);
};

function _scaleImages()
{
	for(var i=0, image;(image=imagesToScale.get(i));i++)
	{
		scaleImage(image);
	}
};

function scaleImage(img)
{
	if (maxImageWidth == 0 || maxImageHeight == 0)
		return;

	var scaleRatio = maxImageWidth / maxImageHeight;

	if (img.width > maxImageWidth || img.height > maxImageHeight)
	{
		var ratio = img.width / img.height;
		img.originalWidth = img.width;
		img.originalHeight = img.height;

		if (ratio > scaleRatio)
		{
			img.width = maxImageWidth;
			img.height = maxImageWidth / ratio;
		}
		else
		{
			img.height = maxImageHeight;
			img.width = maxImageHeight * ratio;
		}

		if (img.parentNode.nodeName != 'A')
		{
			addEvent(img, 'click', popupImage);
			jscss('add', img, 'enlargeable');
			img.title += getText('extra', 'click_to_enlarge');
		}
	}
};

function popupImage()
{
	window.open(this.src, 'img', 'width='+(this.originalWidth+16)+',height='+(this.originalHeight+16)+',left=0,top=0');
};

function makeSmileysClickable(targets)
{
	addEventToTargets(targets, 'click', _insertSmiley, 'div#smileys img');
};

function _insertSmiley()
{
	putStr(' ' +  this.alt + ' ');
	hideSmileys();
};

function localAnchors()
{
	/* strict checking for the moment, should be evaluated at a later point */
	if(!jscss('check', document.body, 'list_message') && !jscss('check', document.body, 'list_messages'))
		return;

	var container = new DOMQuery('ol#messages').get(0);
	if(!container)
		return;

	var items = new DOMQuery('address.posted-at a, blockquote.quote-blockquote a.messagelink', container);
	var pattern = /list_message\//;
	for(var i = 0, item; (item=items.get(i)); i++)
	{
		if(pattern.test(item.pathname))
		{
			addEvent(item, 'click', function(e) { if(!_localAnchors(this)) { e.preventDefault(); } } );
		}
	}
};

function _localAnchors(x)
{
	var id = x.hash.substring(1), anchors = document.anchors;

	for(var i=0, anchor; (anchor=anchors[i]); i++)
	{
		if(anchor.name == id)
		{
			window.location.hash = id;
			return false;
		}
	}
};

function slashdotLinks(targets)
{
	var items = getTargets(targets, 'ol.messages a.link'), a = createDOMNode('a', {"href" : board_script_url}, []), span, clone, shortname;
	for(var i=0, item; (item = items.get(i)); i++)
	{
		if(a.hostname != item.hostname)
		{
			if(item.href == item.text || item.hostname == item.text)
				continue;

			shortname = hostnameToShortname(item.hostname);
			span = createDOMNode('span', {}, [item.cloneNode(true), ' [' + shortname + ']']);
			item.parentNode.replaceChild(span, item);
		}
	}
};
/* these regexp's have been copied from slashcode which is GPL */
/* file: utils/domainTagifyComments */
function hostnameToShortname(hostname)
{
	if(/^(\d{1,3}\.){3}\d{1,3}$/.test(hostname))
		return hostname;

	var result;

	for(var i=1; i<=3; i++)
	{
		switch(i)
		{
			case 1:
				result = hostname.match(/([\w-]+\.[a-z]{3,4})$/i);
			break;
			case 2:
				result = hostname.match(/([\w-]+\.[a-z]{2,4}\.[a-z]{2})$/i);
			break;
			case 3:
				result = hostname.match(/([a-z]+\.[a-z]{2})$/i);
			break;
		}
		if(result)
			return result[1];
	}

	var items = hostname.split('.');
	if(items.length >= 3)
		return items.reverse().slice(0,3).reverse().join('.');

	return hostname;
};

function externalLinksInPopup(targets)
{
	var items = getTargets(targets, 'ol.messages a.link'), a = createDOMNode('a', {"href" : board_script_url}, []);

	for(var i=0, item; (item = items.get(i)); i++)
	{
		if(a.hostname != item.hostname)
		{
			addEvent(item, 'click', function(e) { if(!_localAnchors(this)) { window.open(this.href, 'popupexternal'); e.preventDefault(); } } );
		}
	}
};

function indicateSecureLink(targets)
{
	var items = getTargets(targets, 'ol.messages a.link'), a = createDOMNode('a', {"href" : board_script_url}, []);

	for(var i=0, item; (item = items.get(i)); i++)
	{
		if(a.hostname != item.hostname && item.protocol == 'https:')
		{
			jscss('add', item, 'secure-link');
		}
	}

};

function searchPopup(targets)
{
	addEventToTargets(targets, 'click', function() { try {_searchPopup(this);} catch (e) {} return false;}, 'div#navigation li#search-link a');
	addEventToTargets(targets, 'dblclick', function() { document.location.href = items[0].href; } , 'div#navigation li#search-link a');
};

function _searchPopup(x)
{
	var hiddenElements = [ ['action', 'find'], ['data[searchtype]', 'search'] ], input, fieldsetNodes = [];
	for(var i =0, item; (item = hiddenElements[i]);i++)
	{
		fieldsetNodes[fieldsetNodes.length] = createDOMNode('input', {"type" : 'hidden', "name" : item[0], "value" : item[1]}, []);
	}

	var form = createDOMNode('form', {"action" : board_script_url},
				[
					createDOMNode('fieldset', {},
					[
						/*fieldsetNodes,*/
						createDOMNode('input', {"type" : 'text', "name" : 'data[q]',"size" : 40, "id" : 'search-link-input', "defaultValue" : getText('extra', 'searchPopup'), "event" : ['focus', empty]}, [])
					]),

				]);

	x.parentNode.appendChild(form);

	new DOMQuery('input#search-link-input').get(0).focus();

	return false;
};

function closeAndSubmit(targets)
{
	var items = getTargets(targets, 'div#topic-admin input#status');
	if(items.length == 0)
		return;

	if(items.get(0).nextSibling.options[items.get(0).nextSibling.selectedIndex].value != 'Closed')
	{
		var input = createDOMNode('input', {"type" :'submit', "accessKey" :'c', "value" :getText('extra','close_and_submit'), "event" :['click', function() { _closeAndSubmit(this.form); }] }, []);
		items.get(0).parentNode.appendChild(input);
	}
};

function _closeAndSubmit(form)
{
	var items = new DOMQuery('input#status + select', form);
	if(items.length == 0)
		return;

	var select = items.get(0), opts = select.options;
	for(var i=0, option; (option=opts[i]); i++)
	{
		if(	option.value == 'Closed')
		{
			select.selectedIndex = i;
			select.previousSibling.checked = true;
			break;
		}
	}
};

function indicateAccesskey(targets)
{
	var items = getTargets(targets, 'input[accesskey]');

	var replacement, indicatorCharPos, textOnButton;
	for(var i=0, item; (item=items.get(i)); i++)
	{
		switch(item.type)
		{
			case 'submit':
			case 'reset':
				textOnButton = item.value;
				indicatorCharPos = textOnButton.toLowerCase().indexOf(item.accessKey);

				if(indicatorCharPos >= 0 )
				{
					replacement =	createDOMNode('button', {"accessKey" : item.accessKey, "name" : item.name, "id" : item.id, "type" : item.type, "class" : item.className},
									[
										textOnButton.substring(0, indicatorCharPos),
										createDOMNode('span', {"class" : 'accesskey'}, [textOnButton.charAt(indicatorCharPos)]),
										textOnButton.substring(indicatorCharPos+1)
									]);
				}
				else
				{
					replacement =	createDOMNode('button', {"accessKey" : item.accessKey, "name" : item.name, "id" : item.id, "type" : item.type, "class" : item.className},
									[
										textOnButton,
										' ',
										createDOMNode('span', {"class" : 'accesskey'}, [getText('extra', 'accesskey_indicator', item.accessKey)])
									]);
				}

				/* ie moet echt dood ofzo */
				/* ie pakt de 'type' attribute niet mee */
				if(isIE)
				{
					if(item.type == 'submit')
						addEvent(replacement, 'click', function() { this.form.submit(); } );
					else if(item.type == 'reset')
						addEvent(replacement, 'click', function() { this.form.reset(); } );
				}

				item.parentNode.replaceChild(replacement, item);
				break;
		}
	}

	return true;
};

function allPagesNavigation(targets)
{
	addEventToTargets(targets, 'click', _allPagesNavigation, 'dl.topic-navigation span.cutoff');
};

function _allPagesNavigation()
{
	var dl = getSiblingNode(this, 'up', 'dl');

	var link = new DOMQuery('dd a', dl);

	if(link.length == 0)
		return;
	else
		link = link.get(0);

	/* number is stored in dl's pages-... */
	var maxPage = dl.className.match(/pages\-([0-9]+)/)[1];

	var pageNumber = prompt(getText('extra','enter_page_number', maxPage), '1');
	if(!pageNumber)
		return;

	pageNumber = parseInt(pageNumber);

	if(isNaN(pageNumber) || pageNumber < 1 || pageNumber > maxPage)
	{
		alert(getText('extra', 'page_number_incorrect'));
		return;
	}

	var matches = link.href.match(/^([^0-9]+\/[0-9]+)(\/[0-9]+)?(.*)$/);
	var _link = matches[1] + '/' + pageNumber + matches[3];

	document.location.href = _link;
};

function highlightReferrerQuery()
{
	var q = '', item = null, el = [];
	var ref = document.referrer;
	if(ref != '')
	{
		ref = createDOMNode('a', {'href' : ref}, []).search.substr(1).split('&');
		/* ref now contains a list of a=b, x=y, ... sets */
		for(var i=0; (item = ref[i]); i++)
		{
			el = item.split('=');
			if(['q', 'p', 'query'].indexOf(el[0]) > -1)
			{
				q = el[1];
				break;
			}
		}

		if(q == '')
			return;

		/* tnx to http://svn.fucoder.com/fucoder/se-hilite/se_hilite_src.js */
		q = decodeURIComponent(q);
		q = q.replace(/\'|"/g, '');
		q = q.split(/[\s,\+\.]+/);

		highlightStrings(document.body, q );
	}
};

function highlightStrings(el, strs)
{
	var regexp, metch, words, replacement;
	for(var i=0, item; (item = el.childNodes[i]); i++)
	{
		if(item.nodeType == 3)
		{
			regexp = new RegExp('\\b('+strs.join('|')+')\\b', 'ig');
			if(words = item.nodeValue.split( regexp ))
			{
				/* now highlight the individual words */
				replacement = [];
				for(var j=0, word; (word = words[j]); j++)
				{
					replacement.push( strs.indexOf(word) > -1 ? createDOMNode('span', {'class' : 'highlight1'}, [word]) : word );
				}

				item.parentNode.replaceChild(createDOMNode('span', {'class' : 'highlighting'}, replacement), item);
			}
		}
		else if(item.nodeType == 1)
		{
			highlightStrings(item, strs);
		}
	}
};

function resolveIP2Hostname()
{
	var items = new DOMQuery('li.message-ip a');

	for(var i=0, item; (item=items.get(i)); i++)
	{
		addEvent(item, 'mouseover', _resolveIP2Hostname);
		addEvent(item, 'mouseout', _resolveIP2Hostname);
	}
};

var _resolveIP2HostnameXHR;
function _resolveIP2Hostname(ev)
{
	var target = this;

	switch(ev.type)
	{
		case 'mouseover':
			_resolveIP2HostnameXHR = setTimeout( function()
				{
					var callback = function()
					{
						if (typeof req != 'undefined' && req != null && req.readyState == 4)
						{
							var result = req.responseText.match(/<dd class="lookup_user">(.+)<\/dd>/);
							alert(result[1]);
						}
					};
					var req = httpreq_string('', callback, target.href, false);
				}, 250);
		break;
		case 'mouseout':
			clearTimeout(_resolveIP2HostnameXHR);
		break;
	}
};

function autocomplete(targets)
{
	var items = getTargets(targets, 'input[suggestions]');

	for(var i=0, item; (item=items.get(i));i++)
	{
		if(item.getAttribute('readonly'))
			addEvent(item, 'focus', autocompleteSuggest);
		else
			addEvent(item, 'keyup', autocompleteSuggest);

		addEvent(item, 'keydown', dontSubmit);
		addEvent(item, 'blur', hideAutocompleteSuggest);
		item.setAttribute('autocomplete', 'off');
	}
};

function dontSubmit(e)
{
	var e = e || fixEvent(window.event);
	if(e.keyCode == 13 && this.suggesting)
	{
		e.preventDefault();
	}
};

function hideAutocompleteSuggest()
{
	var list = new DOMQuery('div.autocomplete', document.body).get(0);
	if (list)
	{
		list.noFocus = true;
		if (list.noMouse)
			list.parentNode.removeChild(list);
	}
};

function autocompleteSuggest(e)
{
	var e = e || fixEvent(window.event), li_item;

	var list = new DOMQuery('div.autocomplete', document.body).get(0);
	switch(e.keyCode)
	{
		case 27: /* esc */
			if (!list)
				return;

			list.parentNode.removeChild(list);
			this.suggesting = false;
			return;
		break;
		case 40: /* down */
		case 38: /* up */
			if (!list)
				return;

			var items = new DOMQuery('li', list);
			for(var i=0, item; (item=items.get(i));i++)
			{
				if(!jscss('check', item, 'selected'))
					continue;

				var j = i;
				if(e.keyCode == 38) /* previous */
					j--;
				else				/* next */
					j++;

				var newSelection = items.get(j);
				if(newSelection)
				{
					jscss('remove', item, 'selected', '');
					jscss('add', newSelection, 'selected');

 					var corr = newSelection.offsetTop + newSelection.offsetHeight - list.scrollTop - list.offsetHeight;
					if (corr>0)
						list.scrollTop += corr;
					corr = list.scrollTop - newSelection.offsetTop;
 					if (corr>0)
 						list.scrollTop -= corr;
				}
				break;
			}
			return;
		break;
		case 13: /* enter */
			if (!list)
				return;

			var currentSelection = new DOMQuery('li.selected', list).get(0);

			if(!currentSelection)
				return;

			var no_input = (this.value.substr(-1) == ' ');

			var values = this.value.replace(/\s+$/, '').split(/\s+/);

			if (!no_input)
				values.pop(); /* current word */

			values.push(currentSelection.getAttribute('keyword'));
			this.value = values.join(' ') + ' ';

			list.parentNode.removeChild(list);
			this.suggesting = false;
			return;
		break;
	}


	var choices = this.getAttribute('suggestions').replace(/^\s+|\s+$/g, '').toLowerCase().split(/\s+/);
	var suggestions = [];

	var values = this.value.split(/\s+/);
	var value = values.pop();
	if(!value)
		value = '';
	value = value.toLowerCase();
	var input = this; /* copy for scope reference */
	var readonly = false;

	if(input.getAttribute('readonly'))
		readonly = true;

	for(var i=0; i<choices.length;i++)
	{
		if(choices[i].indexOf(value) != 0 && !readonly)
			continue;

		li_item =
			createDOMNode(
				'li',
				{
					'class' : (suggestions.length == 0 ? 'selected' : '') + (values.indexOf(choices[i]) >= 0 ? ' picked' : ''),
					'keyword'	: choices[i],
					'event' : ['click', function()
					{
						var values = input.value.replace(/\s+$/, '').split(/\s+/);
						var list = new DOMQuery('div.autocomplete', document.body).get(0);

						if(readonly)
						{
							for(var i = 0; i < values.length; i++)
							{
								if(values[i].toLowerCase() == this.getAttribute('keyword').toLowerCase())
								{
									values.splice(i,1);
									var removed = true;
									break;
								}
							}
						}
						else if (value.length > 0)
							values.pop(); /* current word */

						if(!removed)
							values.push( this.getAttribute('keyword').toLowerCase() );

						input.value = values.join(' ') + ' ';
						if (list)
							list.parentNode.removeChild(list);
					}]
				},
				[choices[i]]
			);

		addEvent(
			li_item,
			'mouseover',
			function ()
			{
				jscss('remove', new DOMQuery('li.selected', this.parentNode).get(0), 'selected', '');
				jscss('add', this, 'selected');
			}
		);

		suggestions.push(li_item);
	}

	if(list)
		list.parentNode.removeChild(list);
	this.suggesting = false;

	if(suggestions.length > 0)
	{
		var autocompleteList = createDOMNode('div', {'class' : 'autocomplete'}, [createDOMNode('ul', {}, suggestions)] );
		document.body.appendChild(autocompleteList);
		var pos = findPos(this);
		if (isIE)
			autocompleteList.style.left = (pos.x - document.body.offsetLeft) +'px';
		else
			autocompleteList.style.left = (pos.x + 6) +'px';

		autocompleteList.style.top = (pos.y + this.offsetHeight + 4) +'px';

		addEvent(autocompleteList, 'mouseover', autocompleteListMouseOver);
		addEvent(autocompleteList, 'mouseout', autocompleteListMouseOut);

		autocompleteList.noMouse = true;

		this.suggesting = true;
	}
};

function autocompleteListMouseOver()
{
	this.noMouse = false;
};

function autocompleteListMouseOut()
{
	this.noMouse = true;
	if (this.noFocus)
		this.parentNode.removeChild(this);
};

function findPos(obj)
{
	var curleft = curtop = 0;
	if (obj.offsetParent)
	{
		curleft = obj.offsetLeft;
		curtop = obj.offsetTop;
		while (obj = obj.offsetParent)
		{
			curleft += obj.offsetLeft;
			curtop += obj.offsetTop;
		}
	}
	return {x: curleft, y: curtop};
}

function stretchTextareas(targets)
{
	addEventToTargets(targets, 'keyup', stretchTextarea, 'textarea');
};

function stretchTextarea()
{
	var lines = this.value.match(/([\r\n])/g);
	if(lines == null)
		return;

	this.style.height = Math.min(50, lines.length + 8) + 'em';

	this.scrollIntoView(false);
};

function xhrPagination(targets)
{
	if(['list_messages', 'list_message'].indexOf(board_action) == -1)
		return;

	addEventToTargets(targets, 'click', _xhrPagination, 'dl.topic-navigation dd a');
};

function _xhrPagination(e)
{
	if(['last'].indexOf(this.getAttribute('rel')) > -1 || document.location.pathname.match(/list_messages\/[0-9]+\/last/) ) /* we don't handle 'last' cause it's "special" */
		return;

	if(!arguments.callee.initialPage)
	{
		/* determine the page currently shown */
		arguments.callee.initialPage = parseInt(new DOMQuery('dl.topic-navigation dd a.current-page').get(0).href.match(/list_messages\/[0-9]+\/([0-9]+)/)[1]) + 1;
		arguments.callee.totalPages = parseInt(new DOMQuery('dl.topic-navigation').get(0).className.match(/pages-([0-9]+)/)[1]);
		new DOMQuery('ol.messages').get(0).setAttribute('page', arguments.callee.initialPage);
	}

	if(jscss('check', this, 'placeholder'))
	{
		var thisPage = this.getAttribute('page');
	}
	else
	{
		var thisPage = parseInt(this.getAttribute('href').match(/list_messages\/[0-9]+\/([0-9]+)/)[1]) + 1;
	}

	if(thisPage - 1 >= arguments.callee.totalPages || new DOMQuery('ol.messages[page="'+thisPage+'"]').get(0)) // duplicate request / out-of-bounds
	{
		e && e.preventDefault();
		return;
	}

	var request = httpreq_string('', null, this.getAttribute('href'), false, "GET");
	var messages = getElementFromXHR(request, 'ol.messages');
	var thisPage = parseInt(getElementFromXHR(request, 'dl.topic-navigation dd a.current-page').href.match(/list_messages\/[0-9]+\/([0-9]+)/)[1]) + 1;
	if(!messages) // should we show x-errormessage?
		return;

	// fill blanks
	var containers = new DOMQuery('ol.messages');
	var placeholders = [];
	if(thisPage > arguments.callee.initialPage) /* we're paging ahead */
	{
		var lastContainer = containers.get(containers.length - 1);
		/* we're skipping the current lastPageAvailable and do create one for the thisPage as we'll need the reference later */
		for(var i = parseInt(lastContainer.getAttribute('page')) + 1; i <= thisPage; i++)
		{
			placeholders.push( createDOMNode('p', {'class' : 'placeholder clickable', 'page' : i, 'event' : ['click', arguments.callee], 'href' : this.href.replace(/(list_messages\/[0-9]+\/)([0-9]+)/, '$1' + (i-1) ) }, ['Skipped page: ' + i]) );
		}

		// append the placeholders
		if(placeholders.length)
		{
			lastContainer.parentNode.insertBefore( createDOMNode(null, {}, placeholders), lastContainer.nextSibling );
		}
	}
	else /* we're paging backwards */
	{
		var firstContainer = containers.get(0);
		/* we're skipping the current lastPageAvailable and do create one for the thisPage as we'll need the reference later */
		for(var i = parseInt(firstContainer.getAttribute('page')) - 1; i >= thisPage; i--)
		{
			placeholders.unshift( createDOMNode('p', {'class' : 'placeholder clickable', 'page' : i, 'event' : ['click', arguments.callee], 'href' : this.href.replace(/(list_messages\/[0-9]+\/)([0-9]+)/, '$1' + (i-1) ) }, ['Skipped page: ' + i]) );
		}

		// prepend the placeholders
		if(placeholders.length)
		{
			firstContainer.parentNode.insertBefore( createDOMNode(null, {}, placeholders), firstContainer.previousSibling );
		}
	}

	var placeholder = new DOMQuery('p.placeholder[page="'+thisPage+'"]').get(0);
	if(!placeholder) /* something went pearshaped */
		return;

	messages.setAttribute('page', thisPage);
	placeholder.parentNode.insertBefore(messages, placeholder);
	placeholder.parentNode.removeChild(placeholder);

	var nextLinks = new DOMQuery('dl.topic-navigation dd a[rel="next"]');
	for(var i = 0, nextLink; (nextLink = nextLinks.get(i)); i++)
	{
		nextLink.href = nextLink.href.replace(/(list_messages\/[0-9]+\/)([0-9]+)/, '$1' + thisPage )
	}

	var currentPages = new DOMQuery('dl.topic-navigation dd a[href*="list_messages/'+this.getAttribute('href').match(/list_messages\/([0-9]+)/)[1]+'/'+(thisPage-1)+'"]');
	for(var i = 0, currentPage; (currentPage = currentPages.get(i)); i++)
	{
		jscss('add', currentPage, 'current-page');
	}

	if(messages.scrollIntoView)
		messages.scrollIntoView();

	_init(events, messages);
	e && e.preventDefault();
	/*if(events.indexOf(pageIndicator) > -1)
	{
		updatePageIndicator();
	}*/
};


/* this is UNFINISHED */
function pageIndicator()
{
	if(arguments.callee.initialRun)
		return;

	document.body.appendChild(
		createDOMNode('div', {'id' : 'container', 'style' : 'width: 50px; height: 200px; border: 1px solid black; position: absolute; top: 0; left: 275px;'}, [
		])
	);

	updatePageIndicator();
	arguments.callee.initialRun = true;
}

function updatePageIndicator()
{
	var container = new DOMQuery('div#container').get(0);
	while(container.firstChild)
		container.removeChild(container.firstChild);

	var messageCount = 13; // should be dynamic
	var perPage = 5; // should be dynamic

	var containerHeight = currentStyle(container, 'height');
	var perPixel = containerHeight / messageCount;

	var availablePage = createDOMNode('div', {'class' : 'viewport', 'style' : 'width: 48px; height: 0; border: 1px solid red; position: absolute; top: 0; left: 0; background-color: yellow; opacity: .6'}, []);
	var items = new DOMQuery('ol.messages');
	for(var i = 0, item; (item = items.get(i)); i++)
	{
		var messagesVisible = new DOMQuery('li.message', item).length;
		var currentPage = parseInt(item.getAttribute('page'));
		if(!currentPage) // this only happens when someone has not executed _xhrPagination
		{
			currentPage = parseInt(new DOMQuery('dl.topic-navigation dd a.current-page').get(0).href.match(/list_messages\/[0-9]+\/([0-9]+)/)[1]) + 1;
		}

		var clone = availablePage.cloneNode(true);
		clone.style.height = Math.floor(messagesVisible * perPixel) + 'px';
		clone.style.top = Math.floor((currentPage - 1) * perPage * perPixel) + 'px';

		container.appendChild(clone);
	}

	var viewport = createDOMNode('div', {'class' : 'viewport', 'style' : 'width: 48px; height: 0; border: 1px solid red; position: absolute; top: 0; left: 0; background-color: blue; opacity: .7'}, []);
	viewport.style.height = 30 + 'px';
	container.appendChild(viewport);
}
