var galleries =
{
	init: function()
	{
		galleries.create_thumb();
		galleries.scrollbars = [];

		$('content').select('.thumbnails').each(galleries.load);
	},

	create_thumb: function()
	{
		this.thumb = new Element('a');

		this.thumb.image = new Element('img');
		this.thumb.appendChild(this.thumb.image);

		var demagnify_thumb_listener = this.demagnify_thumb.bindAsEventListener(galleries.thumb);
		this.thumb.observe('mouseout', demagnify_thumb_listener);
		this.thumb.observe('mouseover', demagnify_thumb_listener);
		this.thumb.observe('mousemove',  demagnify_thumb_listener);

		this.thumb.addClassName('magnified_thumbnail').hide();

		document.getElementsByTagName('body')[0].appendChild(this.thumb);
	},

	load: function(elm)
	{
		elm.className = 'thumbnails_enhanced';

		var nodes = elm.select('li');

		// set the container width
		elm.getElementsByTagName('ul')[0].style.width = nodes.length * 150 + 'px';

		nodes.each(function(i) {
			i.image = i.getElementsByTagName('img')[1];
			i.a = i.getElementsByTagName('a')[0];

			$(i).observe('mouseover', galleries.magnify_thumb.bindAsEventListener(i));
		});

		// create the scrollbar
		if(elm.scrollWidth > elm.clientWidth) {
		   var scrollbar = new Scrollbar(elm, elm.parentNode);
		   scrollbar.update();
		   galleries.scrollbars.push(scrollbar);
		}
	},

	magnify_thumb: function(event)
	{
//@todo onlx magnifz if not alreadz magnified!!!
		if(!galleries.scrolling)
		{
			galleries.thumb.origin = this;

			// move the thumb to the correct position
			var position = this.cumulativeOffset();
			galleries.thumb.style.left = position[0] - this.parentNode.parentNode.scrollLeft - 57 + 'px';
			galleries.thumb.style.top = position[1] - 56 + 'px';

//			galleries.thumb.image.src = 'about:blank'; // prevent flashing of previous image
////		galleries.thumb.image.width = this.image.getAttribute('width');
////		galleries.thumb.image.height = this.image.getAttribute('height');
			galleries.thumb.href = this.a.href;
//			galleries.thumb.image.src = this.image.src;

galleries.thumb.image.remove();
galleries.thumb.image = $(this.image.cloneNode(true));
galleries.thumb.appendChild(galleries.thumb.image);

			galleries.thumb.show();

			// hide the thumb automatically if the mouse pointer is not above it
			galleries.kill_timeout();
			galleries.timeout = setTimeout(function(){galleries.thumb.hide();}, 100);
		}

		Event.stop(event);
	},

	demagnify_thumb: function(event)
	{
		galleries.kill_timeout();

		var x = Event.pointerX(event);
		var y = Event.pointerY(event);
		var containerxy = this.origin.cumulativeOffset();
		containerxy[0] -= this.origin.parentNode.parentNode.scrollLeft;

		if(!(x >= containerxy[0] && x <= (containerxy[0] + this.origin.offsetWidth) && y >= containerxy[1] && y <= (containerxy[1] + this.origin.offsetHeight)))
		{
			galleries.thumb.hide();
		}

		Event.stop(event);
	},

	kill_timeout: function()
	{
		if(galleries.timeout)
		{
			clearTimeout(galleries.timeout);
			galleries.timeout = false;
		}
	}
}

Event.observe(document, 'dom:loaded', galleries.init);

// fix scrollbar width (may be caused by improper width calculation of css
// styled elements between 'dom:loaded' and 'window:load')
Event.observe(window, 'load', function() {
	galleries.scrollbars.invoke('update');
});

var Scrollbar = Class.create({
	initialize: function(scrollable, container) {
		var div = new Element('div', {'class': 'scrollbar'});
		this.div = div;

		this.scrollable = scrollable;

		var slider = new Element('div');
		slider.appendChild(document.createElement('span'));

		div.appendChild(slider);
		this.slider = slider;

		this.update();

		container.appendChild(div);

		slider.move = this.mousemove.bindAsEventListener(this);
		slider.stop_capture_mouseup = this.stop_scroll.bindAsEventListener(slider);

		div.observe('mousedown', this.bar_click.bindAsEventListener(this));
		slider.observe('mousedown', this.slider_click.bindAsEventListener(this));

		// hover effect
		slider.observe('mouseover', function() { this.addClassName('hover'); });
		slider.observe('mouseout', function() { this.removeClassName('hover'); });

		scrollable.scrollLeft = 0;
	},

	/* update width and position of the slider. Meant to be called externally,
	 * e.g. when the content of the scrollable area got bigger)
	 */
	update: function() {
		// update the slider width
		var width = (this.div.clientWidth * this.scrollable.clientWidth / this.scrollable.scrollWidth).toFixed(0);

		// preserve a minimum width
		if(width < 37) width = 37;

		this.slider.style.width = width + 'px';

		// update the slider position
		this.slider.style.left = (this.div.clientWidth * this.scrollable.scrollLeft / this.scrollable.scrollWidth).toFixed(0) + 'px';
	},

	mousemove: function(event)
	{
		var xdiff = Event.pointerX(event) - this.slider.xstart;
		var x = (this.slider.offsetstart + xdiff) / (this.div.clientWidth - this.slider.clientWidth);

		this.scrollTo(x);

		Event.stop(event);
	},

	stop_scroll: function(event)
	{
		// hover effect
		galleries.scrolling = false;
		this.removeClassName('scroll');

		Event.stopObserving(document, 'mousemove', this.move);
		Event.stopObserving(document, 'mouseup', this.stop_capture_mouseup);

		Event.stop(event);
	},

	/* handle clicks on the bar itself (besides the slider) */
	bar_click: function(event)
	{
		var x = Event.pointerX(event) - this.div.cumulativeOffset()[0];

		x -= this.slider.clientWidth / 2;
		xscroll = x / (this.div.clientWidth - this.slider.clientWidth);

		this.scrollTo(xscroll);

		Event.stop(event);
	},

	/* handle clicks on our slider */
	slider_click: function(event)
	{
		if(Event.isLeftClick(event))
		{
			var slider = this.slider;

			// hover effect
			galleries.scrolling = true;
			slider.addClassName('scroll');

			slider.xstart = Event.pointerX(event);
			slider.offsetstart = slider.offsetLeft;

			Event.observe(document, 'mousemove', slider.move);
			Event.observe(document, 'mouseup', slider.stop_capture_mouseup);
		}
		Event.stop(event);
	},

	/* scroll to a certain offset (interval [0, 1]) */
	scrollTo: function(x)
	{
		if(x < 0) x = 0;
		if(x > 1) x = 1;

		// scroll our target
		this.scrollable.scrollLeft = (x * (this.scrollable.scrollWidth - this.scrollable.clientWidth)).toFixed(0);

		// place our scrollbar scroller
		this.slider.style.left = (x * (this.div.clientWidth - this.slider.clientWidth)).toFixed(0) + 'px';
	}
});
