window.addEvent('domready', function () {
	//get main img tag and title
	var targetImg = null;
	var targetTitle = null;
	$('photo').getChildren().each(function(e) {
		if (e.tagName.toLowerCase() == 'img') {
			targetImg = e;
		}
		if (e.tagName.toLowerCase() == 'h2') {
			targetTitle = e;
		}
	});

	var thumbs = $E('#thumbs ul');
	var ms = new MotionScroller(thumbs, { restarea: 20, maxspeed: 4 });
	new Gallery(targetImg, targetTitle, thumbs, $E('#next a'), $E('#prev a'), {
		onStart: function (e) {
			ms.showElement(e);
		}
	});

	new LayerFader([$E('#nb3 a'), $E('#nb4 a')], [$('info'), $('contact')]);
});

var LayerFader = new Class({
	options: {
		'duration': 300
	},
	togglers: [],
	layers: [],
	current: -1,
	moving: false,
	initialize: function (togglers, layers, options) {
		this.setOptions(options);

		this.togglers = togglers;
		this.layers = layers;

		// set the opacity to zero
		this.layers.each(function (e) {
			e.setStyle('opacity', 0);
		});

		this.togglers.each(function (e, i) {
			e.addEvent('click', this.toggleClicked.bindWithEvent(this, i));
		}, this);
		this.layers.each(function (e, i) {
			e.addEvent('click', this.layerClicked.bindWithEvent(this, i));
		}, this);
	},
	layerClicked: function (evt, index) {
		if (evt.target != this.layers[index]) {
			return;
		}
		evt.stop();
		if (index == this.current) {
			this.hide();
			return;
		}
		this.show(index);
	},
	toggleClicked: function (evt, index) {
		evt.stop();
		if (index == this.current) {
			this.hide();
			return;
		}
		this.show(index);
	},
	show: function (index) {
		if (this.current >= 0) {
			// hide the current one first
			this.hide();
			this.show.delay(this.options.duration + 10, this, [index]);
		}

		if (index < 0 || index >= this.layers.length || this.moving) {
			return;
		}

		this.moving = true;
		var e = this.layers[index];
		new Fx.Style(e, 'opacity', $extend(this.options, {
			onComplete: function () {
				this.current = index;
				this.moving = false;
			}.bind(this)
		})).start(0, 1);
	},
	hide: function (index) {
		if (arguments.length == 0) {
			index = this.current;
		}

		if (index < 0 || index >= this.layers.length || this.moving) {
			return;
		}

		this.moving = true;
		var e = this.layers[index];
		new Fx.Style(e, 'opacity', $extend(this.options, {
			onComplete: function () {
				this.current = -1;
				this.moving = false;
			}.bind(this)
		})).start(1, 0);
	}
});
LayerFader.implement(new Options);


function toggleDisplay(e, showStyle) {
	options = {
		'duration': 300
	};
	if (e = $(e)) {
		if (e.getStyle('opacity') != 0) {
			var fx = new Fx.Style(e, 'opacity', options).start(1, 0);
		}
		else  {
			var fx = new Fx.Style(e, 'opacity', options).start(0, 1);
		}
	}
}

var Gallery = new Class({
	targetImg: null,
	targetTitle: null,
	triggers: [],
	moving: false,
	nextImg: false,
	tmpImg: null,
	loaderTimer: null,
	current: 0,
	options: {
		duration: 300,
		minOpacity: 0.2,
		onStart: Class.empty,
		onComplete: Class.empty,
		loaderSrc: 'media/img/loader.gif',
		loaderWidth: 32,
		loaderHeight: 32
	},

	initialize: function(targetImg, targetTitle, triggers, next, previous, options) {
		this.setOptions(options);

		this.targetImg = $(targetImg);
		this.targetTitle = $(targetTitle);
		if ($(triggers)) {
			var as = $(triggers).getElementsByTagName('a');
			this.triggers = $A(as);
		}

		this.setTriggersAction();

		//create loader image
		this.loader = new Element('img', {
			'src': this.options.loaderSrc,
			'width': this.options.loaderWidth,
			'height': this.options.loaderHeight,
			'styles': {
				'position': 'absolute',
				'right': (this.targetImg.width - this.options.loaderWidth) / 2,
				'top': (this.targetImg.height - this.options.loaderHeight) / 2
			}
		});

		next.addEvent('click', this.next.bind(this));
		previous.addEvent('click', this.previous.bind(this));
	},


	showImage: function (num) {
		if (num < 0 || (num > this.triggers.length - 1)) {
			return;
		}
		this.swapImage(null, this.triggers[num]);
		this.fireEvent('onStart', this.triggers[num]);
	},

	next: function () {
		this.showImage(this.current + 1);
	},

	previous: function () {
		this.showImage(this.current - 1);
	},

	setTriggersAction: function() {
		this.triggers.each(function(e) {
			$(e).addEvent('click', this.swapImage.bindWithEvent(this, e));
		}, this);
	},

	swapImage: function(evt, e) {
		if (evt) {
			evt.stop();
		}
		if (e.href == '') return;
		this.nextImg = {'src': e.href, 'title': e.title};

		this.triggers.each(function(el) {
			el.removeClass('selected');
		});
		e.addClass('selected');

		if (!this.moving) {
			var options = this.options;
			options.onStart = this.onHideStart.bind(this);
			options.onComplete = this.onHideComplete.bind(this);
			var fx = new Fx.Style(this.targetImg, 'opacity', options).start(1, this.options.minOpacity);
		}

		for (var i = 0; i < this.triggers.length; i++) {
			if (this.triggers[i] == e) {
				this.current = i;
				break;
			}
		}
	},

	onHideStart: function() {
		if (this.moving) return;
		this.moving = true;
	},

	onHideComplete: function() {
		//this.moving = false;

		//show loader
		this.showLoader();

		//create new image
		this.tmpImg = new Element('img', {
			'src': this.nextImg.src,
			'width': this.targetImg.width,
			'height': this.targetImg.height,
			'alt': this.nextImg.src.replace(/.*\/(.+)\.[^\.]+$/, '$1').replace(/%20/g, ' '),
			'styles': {
				'position': 'absolute',
				'top': 0,
				'left': 0,
				'opacity': 0
			}
		});
		this.tmpImg.injectAfter(this.targetImg);
		if (/MSIE/.test(navigator.userAgent) && this.tmpImg.complete) {
			this.onShowReady();
		}
		else {
			this.tmpImg.addEvent('load', this.onShowReady.bindWithEvent(this));
		}
	},

	onShowReady: function() {
		//new image has loaded: show
		if (!this.tmpImg) return;
		this.moving = true;

		//remove loader
		this.hideLoader();

		//set title
		var title = (this.nextImg.title == '') ? '&nbsp;' : this.nextImg.title;
		this.targetTitle.innerHTML = title;

		var options = this.options;
		options.onStart = this.onShowStart.bind(this);
		options.onComplete = this.onShowComplete.bind(this);
		var fx = new Fx.Style(this.tmpImg, 'opacity', options).start(0, 1);
	},

	onShowStart: function() {
		this.moving = true;
	},

	onShowComplete: function() {
		this.moving = false;

		this.targetImg.setAttribute('src', this.tmpImg.src);
		this.targetImg.setAttribute('alt', this.tmpImg.alt);
		this.targetImg.setStyle('opacity', 1);
		//safari actually always returns true to the test below
		if ((/MSIE/.test(navigator.userAgent) || /Safari/.test(navigator.userAgent)) && this.targetImg.complete) {
			this.removeTmpImage();
		}
		else {
			this.targetImg.addEvent('load', this.removeTmpImage.bindWithEvent(this));
		}
		this.fireEvent('onComplete');
	},

	removeTmpImage: function() {
		if (this.tmpImg) {
			this.tmpImg.remove();
			this.tmpImg = null;
		}
	},

	showLoader: function() {
		this.loaderTimer = function() {
			//only show if still moving
			if (this.moving) {
				this.loader.injectAfter(this.targetImg);
			}
		}.delay(10, this);
	},

	hideLoader: function() {
		if (this.loaderTimer) {
			$clear(this.loaderTimer);
		}
		if (this.targetImg.getParent().hasChild(this.loader)) {
			this.loader.remove();
		}
	}
});
Gallery.implement(new Events, new Options);





var MotionScroller = new Class({
	element: null,
	width: 0,
	left: 0,
	timer: null,
	moving: false,
	parent: {
		element: null,
		width: 0,
		left: 0
	},
	options: {
		restarea: 10,	// width in pixels of the dead area in the center
		maxspeed: 7		// pixels to move with each iteratio
	},
	initialize: function (element, options) {
		this.element = $(element);
		this.setOptions(options);

		// hide the element while it's loading
		this.element.setStyle('visibility', 'hidden');

		this.loaded();
		// we need to wait until all the images have loaded before we can get the width
		//window.addEvent('load', this.loaded.bind(this));
	},
	loaded: function () {
		// set the width of the element
		var width = 0;
		this.element.getChildren().each(function (e) {
			var widths = e.getStyles('margin-left', 'margin-right');
			for (var property in widths) {
				width += isNaN(parseInt(widths[property])) ? 0 : parseInt(widths[property]);
			}
			width += e.getSize().size.x;
		});

		this.element.setStyles({
			width: width,
			visibility: 'visible'
		});

		this.width = width;
		this.left = 0;

		var parent = this.element.getParent();
		this.parent = {
			element: parent,
			width: parent.getSize().size.x,
			left: parent.getPosition().x
		}

		this.element.getParent().addEvent('mousemove', this.mousemove.bindWithEvent(this));
		this.element.getParent().addEvent('mouseleave', this.mouseout.bindWithEvent(this));
	},
	mouseout: function () {
		$clear(this.timer);
	},
	mousemove: function (evt) {
		$clear(this.timer);

		var posx = evt.client.x - this.parent.left;

		var leftbound = (this.parent.width - this.options.restarea) / 2;
		var rightbound = (this.parent.width + this.options.restarea) / 2;

		if (posx > rightbound) {
			// scroll left
			var direction = 'left';
			var speed = (posx - rightbound) / ((this.parent.width - this.options.restarea) / 2) * this.options.maxspeed;
			this.move(direction, speed);
		}
		else if (posx < leftbound) {
			// scroll right
			var direction = 'right';
			var speed = (leftbound - posx) / ((this.parent.width - this.options.restarea) / 2) * this.options.maxspeed;
			this.move(direction, speed);
		}

		this.timer = this.mousemove.delay(10, this, evt);
	},
	move: function (direction, speed) {
		if (this.moving) {
			return;
		}
		var pos = Math.round(direction == 'left' ? this.left - speed : this.left + speed);

		if (direction == 'left' && pos > (this.parent.width - this.width)) {
			this.left = pos;
		}
		else if (direction == 'right') {
			this.left = (pos < 0) ? pos : 0;
		}

		this.element.setStyles({
			left: this.left
		});
	},
	showElement: function (e) {
		// makes sure the element is visible inside the scroll area

		var p1 = this.element.getPosition();

		// find the position of the element
		var p2 = e.getPosition();
		var offset = this.element.getStyle('left').toInt();
		offset = isNaN(offset) ? 0 : offset;
		var lpos = p2.x - p1.x + offset;
		var rpos = lpos + e.getSize().size.x;

		var left = offset;
		var duration = 300;
		if (lpos < 0) {
			left = offset - lpos;
		}
		else if (rpos > this.parent.width) {
			left = offset - rpos + this.parent.width;
		}

		if (left != offset) {
			this.left = left;
			new Fx.Style(this.element, 'left', {
				duration: duration,
				onComplete: function () {
					this.moving = false;
				}.bind(this)
			}).start(left);
			this.moving = true;
		}
	}
});
MotionScroller.implement(new Options);



