﻿/**
 * class Galerie
 *
 * Copyright (C) 2006  Dao Gottwald
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 *
 * Contact information:
 *   Dao Gottwald  <dao at design-noir.de>
 *   Herltestraße 12
 *   D-01307, Germany
 *
 * @version  1.8.14
 * @url      http://design-noir.de/webdev/JS/Galerie/
 */

function Galerie (container, className) {
	if (typeof container == 'string') {
		container = document.getElementById(container);
		if (container == null)
			return null;
	}
	if (className)
		this.className = className;
	this.cache = {};
	this._clickLoad = this.clickLoad.bind(this);
	if (container)
		this.addLinks (container);
	return this;
}
whenDOMReady (function() {
	Galerie.BODY = document.getElementsByTagName('body')[0];
	Galerie.ROOT_ELEMENT = document.compatMode && document.compatMode != 'BackCompat' ? document.documentElement : Galerie.BODY;
	new Galerie ('Galerie');
});
Galerie.open = 0;
Galerie.LOADING_STATE = 'loading';
Galerie.BIG_STATE = 'big';
Galerie.SMALL_STATE = 'small';
Galerie.NO_STATE = '';
Galerie.LANG = (navigator.systemLanguage || navigator.userLanguage || navigator.language || navigator.browserLanguage || '').replace(/-.*/,'');
Galerie.adjustDocumentLayout = function() {
	if (Galerie.open++ > 0)
		return;
	Galerie._originalScroll = window.scrollY || Galerie.ROOT_ELEMENT.scrollTop || false;
	Galerie._originalOverflow = Galerie.ROOT_ELEMENT.style.overflow;
	Galerie._originalBodyPosition = Galerie.BODY.style.position;
	Galerie.ROOT_ELEMENT.style.overflow = 'hidden';
	Galerie.BODY.style.position = 'static';
};
Galerie.restoreDocumentLayout = function(scroll) {
	if (--Galerie.open > 0)
		return;
	Galerie.ROOT_ELEMENT.style.overflow = Galerie._originalOverflow;
	Galerie.BODY.style.position = Galerie._originalBodyPosition;
	if (scroll && Galerie._originalScroll)
		window.scroll (0, Galerie._originalScroll);
};
Galerie.KHTML = /KDE|Apple/.test(navigator.vendor);
/*@cc_on Galerie.IE6 = /MSIE [4-6]/.test(navigator.appVersion); @*/
Galerie.prototype = {
	className: 'galeriePop',
	imgCount: 0,
	currentUrl: '',
	slide: false,
	slidePauseSeconds: 3,
	slideCountdownStep: -1,
	prefetchPrev: 1,
	prefetchNext: 2,
	addLinks: function (container) {
		var links = container.getElementsByTagName('a');
		for (var ele, i=0; ele = links[i]; i++)
			this.addLink (ele);
	},
	addLink: function (ele) {
		var url = ele.href;
		if (!/\.(jpg|jpeg|gif|png)$/i.test (url))
			return;
		/*@ if (Galerie.IE6) url = this._IE_urlOpt (url); @*/
		if (this.cache[url])
			return;
		if (this.imgCount == 0)
			this.firstImage = url;
		this.cache[url] = {link: ele, pos: ++this.imgCount};
		if (this.count)
			this.count.firstChild.nodeValue = this.imgCount;
		if (this.nav && this.imgCount > 1) {
			this.nav.prev.className = 'prev';
			this.nav.next.className = 'next';
		}
		if (this.slideButton)
			this.slideButton.className = 'slideshow' + (this.imgCount == 1 ? ' disabled' : '');
		if (ele.title)
			this.setTitle (url, ele.title);
		if (this.lastImage) {
			this.cache[url].prev = this.lastImage;
			this.cache[this.lastImage].next = url;
		}
		this.lastImage = url;
		if (ele.nodeType)
			addEvent (ele, 'click', this._clickLoad);
	},
	/*@ _IE_urlOpt: function (url) {
		if (/^\w+:\/{2}/.test (url)) {
			url = escape(unescape(url));
			return url.replace(escape(':'),':');
		} else
			return escape(unescape(url));
	}, @*/
	init: function() {
		this.container = document.createElement('div');
		this.container.className = this.className;
		
		var background = document.createElement('span');
		background.className = 'background';
		this.container.appendChild (background);
		
		this.title = document.createElement('div');
		this.title.className = 'title empty-title';
		this.container.appendChild (this.title);
		
		this.nav = {
			prev: document.createElement('a'),
			next: document.createElement('a')};
		this.nav.prev.appendChild(document.createTextNode('«'));
		this.nav.next.appendChild(document.createTextNode('»'));
		this.nav.prev.className = this.imgCount > 1 ? 'prev' : 'prev disabled';
		this.nav.next.className = this.imgCount > 1 ? 'next' : 'next disabled';
		this.nav.prev.setAttribute('title', this.l10n.prev);
		this.nav.next.setAttribute('title', this.l10n.next);
		
		this.count = document.createElement('strong');
		this.count.appendChild(document.createTextNode(this.imgCount));
		
		this.pos = document.createElement('strong');
		this.pos.appendChild(document.createTextNode(1));
		
		var closeButton = document.createElement('a');
		closeButton.setAttribute('href', '#');
		closeButton.setAttribute('title', this.l10n.close);
		closeButton.appendChild(document.createTextNode('x'));
		closeButton.className = 'close';
		
		this.slideButton = document.createElement('a');
		this.slideButton.setAttribute('href', '#');
		this.slideButton.setAttribute('title', this.l10n.slideshow);
		this.slideButton.appendChild(document.createTextNode('…'));
		this.slideButton.className = 'slideshow' + (this.imgCount == 1 ? ' disabled' : '');
		
		this.slideCountdownContainer = document.createElement('div');
		this.slideCountdownContainer.className = 'countdown';
		this.slideCountdownContainer.appendChild(document.createTextNode(''));
		
		var navContainer = document.createElement('div');
		navContainer.className = 'nav';
		navContainer.appendChild (closeButton);
		navContainer.appendChild (this.slideButton);
		navContainer.appendChild (this.nav.prev);
		navContainer.appendChild (this.nav.next);
		navContainer.appendChild (document.createElement('br'));
		navContainer.appendChild (document.createTextNode(this.l10n.picture +' '));
		navContainer.appendChild (this.pos);
		navContainer.appendChild (document.createTextNode(' '+ this.l10n.of +' '));
		navContainer.appendChild (this.count);
		navContainer.appendChild (this.slideCountdownContainer);
		this.container.appendChild (navContainer);
		
		this.image = document.createElement('img');
		this.imgContainer = document.createElement('span');
		this.imgContainer.appendChild (this.image);
		this.container.appendChild (this.imgContainer);
		
		Galerie.BODY.appendChild (this.container);
		
		addEvent (this.nav.prev, 'click', this._clickLoad);
		addEvent (this.nav.next, 'click', this._clickLoad);
		
		addEvent (this.imgContainer, 'click', this.resizeImageToggle.bind(this));
		addEvent (closeButton, 'click', this.close.bind(this));
		addEvent (this.slideButton, 'click', this.slideToggle.bind(this));
		addEvent (document, 'keyup', this.keyNav.bind(this));
	},
	close: function (e) {
		if (!this.container || this.container.style.display != 'block')
			return;
		if (e)
			e.preventDefault();
		this.slideHalt();
		Galerie.restoreDocumentLayout(!!e);
		this.container.style.display = 'none';
	},
	load: function (url, prefetch) {
		if (!url)
			return false;
		/*@ if (Galerie.IE6) url = this._IE_urlOpt (url); @*/
		if (!this.cache[url])
			return false;
		if (!prefetch) {
			this.currentUrl = url;
			if (!this.container)
				this.init();
			this.setState (Galerie.LOADING_STATE);
			if (this.container.style.display != 'block') {
				Galerie.adjustDocumentLayout();
				this.container.style.display = 'block';
				/*@ if (Galerie.IE6) {
					this.container.style.top = Galerie.ROOT_ELEMENT.scrollTop + 'px';
					this.container.style.width = Galerie.ROOT_ELEMENT.clientWidth + 'px';
					this.container.style.height = Galerie.ROOT_ELEMENT.clientHeight + 'px';
				} @*/
			}
		}
		if (!this.cache[url].image) {
			this.cache[url].image = new Image;
			this.cache[url].image._galerie = this;
			this.cache[url].image._url = url;
			this.cache[url].image.onload = this.imageOnload;
			this.cache[url].image.src = url;
		}
		if (!prefetch)
			this.setContent (url);
		return true;
	},
	imageOnload: function () {
		var image = this;
		if (Galerie.KHTML) {
			image = document.createElement('img');
			image.src = this.src;
			this._galerie.cache[image._url = this._url].image = image;
		}
		if (image.naturalHeight === undefined) {
			image.naturalHeight = this.height;
			image.naturalWidth = this.width;
		}
		image.ready = true;
		this._galerie.showImage(image);
		this.onload = this._galerie = null;
	},
	getTitle: function (url) {
		return this.cache[url].title || '';
	},
	setTitle: function (url, title) {
		this.cache[url].title = title;
		this.showTitle (url);
	},
	showTitle: function (url) {
		if (url != this.currentUrl)
			return;
		var title = this.getTitle(url);
		if (title) {
			this.title.innerHTML = title;
			this.title.className = 'title';
		} else {
			this.title.className = 'title empty-title';
			this.title.innerHTML = '';
		}
	},
	setContent: function (url) {
		if (url != this.currentUrl)
			return;
		var o = this.cache[url];
		this.showImage (o.image);
		this.pos.firstChild.nodeValue = o.pos;
		this.showTitle (url);
		this.nav.next.setAttribute('href', this.getNext(url));
		this.nav.prev.setAttribute('href', this.getPrev(url));
		for (var _url = url, i = 0; i < this.prefetchNext; i++) {
			_url = this.getNext(_url);
			this.load (_url, true);
		}
		for (var _url = url, i = 0; i < this.prefetchPrev; i++) {
			_url = this.getPrev(_url);
			this.load (_url, true);
		}
	},
	showImage: function (image) {
		if (image._url != this.currentUrl || !image.ready)
			return;
		if (image != this.image) {
			this.imgContainer.replaceChild (image, this.image);
			this.image = image;
		}
		this.setState (this.image.naturalWidth > this.container.clientWidth || this.image.naturalHeight > this.container.clientHeight ? Galerie.SMALL_STATE : Galerie.NO_STATE);
		if (this.slide)
			this.slideCountdown();
	},
	centerImage: function (imageHeight) {
		this.image.style.marginTop = Math.max (0, Math.floor ((this.imgContainer.clientHeight - imageHeight) / 2)) + 'px';
	},
	setState: function (state) {
		if (state == Galerie.NO_STATE || state == Galerie.BIG_STATE)
			this.centerImage (this.image.naturalHeight);
		this.imgContainer.className = 'imgContainer ' + state;
		this.imgContainer.scrollLeft = this.imgContainer.scrollTop = 0;
		/*@ if (Galerie.IE6 && this.image) {
			if (state == Galerie.SMALL_STATE) {
				if (this.container.clientWidth / this.image.naturalWidth < this.container.clientHeight / this.image.naturalHeight) {
					this.image.style.width = this.container.clientWidth + 'px';
					this.image.style.height = '';
				} else {
					this.image.style.width = '';
					this.image.style.height = this.container.clientHeight + 'px';
				}
			} else {
				this.image.style.width = '';
				this.image.style.height = '';
			}
		} @*/
		if (state != Galerie.NO_STATE && state != Galerie.BIG_STATE && this.image.height)
			this.centerImage (this.image.height);
	},
	checkState: function (state) {
		return this.imgContainer.className.indexOf (' '+state) > -1;
	},
	resizeImageToggle: function (e) {
		if (e.type == 'click' && (e.target != this.image || !e.clientX && !e.clientY))
			return;
		if (this.checkState (Galerie.SMALL_STATE)) {
			if (e.type == 'click') {
				var	x = (e.clientX - this.image.offsetLeft) / this.image.clientWidth,
					y = (e.clientY - this.image.offsetTop) / this.image.clientHeight;
			}
			this.setState (Galerie.BIG_STATE);
			if (e.type == 'click') {
				this.imgContainer.scrollLeft = x > .3 ? (this.image.naturalWidth - this.imgContainer.clientWidth) * (x > .7 ? 1 : x) : 0;
				this.imgContainer.scrollTop = y > .3 ? (this.image.naturalHeight - this.imgContainer.clientHeight) * (y > .7 ? 1 : y) : 0;
			}
		} else if (this.checkState (Galerie.BIG_STATE))
			this.setState (Galerie.SMALL_STATE);
	},
	clickLoad: function (e) {
		e.currentTarget.blur();
		this.slideHalt();
		if (this.load (e.currentTarget.href)) {
			e.stopPropagation();
			e.preventDefault();
		}
	},
	keyNav: function (e) {
		if (this.container.style.display != 'block')
			return;
		switch (e.keyCode) {
		 	case 27: //Esc
				this.close(e);
				break;
			case 39: case 63235: //Right
				this.slideHalt();
				this.goNext();
				break;
			case 37: case 63234: //Left
				this.slideHalt();
				this.goPrev();
				break;
			case 13: //Enter
				this.resizeImageToggle(e);
				break;
			case 107: case 43: //Plus
				if (this.checkState (Galerie.SMALL_STATE))
					this.setState (Galerie.BIG_STATE);
				break;
			case 109: case 45: //Minus
				if (this.checkState (Galerie.BIG_STATE))
					this.setState (Galerie.SMALL_STATE);
				break;
			case 83: //s
				this.slideToggle();
				break;
			default:
				return;
		}
		e.preventDefault();
	},
	goPrev: function () {
		var url = this.getPrev(this.currentUrl);
		return this.load (url);
	},
	goNext: function () {
		var url = this.getNext(this.currentUrl);
		return this.load (url);
	},
	getNext: function (url) {
		url = this.cache[url].next;
		if (!url)
			url = this.firstImage;
		return url;
	},
	getPrev: function (url) {
		url = this.cache[url].prev;
		if (!url)
			url = this.lastImage;
		return url;
	},
	slideToggle: function (e) {
		if (this.slide || this.imgCount == 1)
			this.slideHalt();
		else
			this.slideCountdown();
		if (e) {
			e.currentTarget.blur();
			e.preventDefault();
		}
	},
	slideHalt: function () {
		if (this.slide)
			window.clearInterval (this.slide);
		this.slide = false;
		this.slideCountdownStep = -1;
		if (this.slideCountdownContainer)
			this.slideCountdownContainer.firstChild.nodeValue = '';
	},
	slideCountdown: function () {
		if (this.slideCountdownStep < 0) {
			if (typeof this.slide != 'boolean') {
				this.slideHalt();
				this.slide = true;
				this.goNext();
				return;
			}
			this.slideCountdownStep = 20;
			this.slide = window.setInterval (this.slideCountdown.bind(this), Math.floor (this.slidePauseSeconds * 1000 / this.slideCountdownStep));
		} else
			this.slideCountdownStep--;
		this.slideCountdownContainer.firstChild.nodeValue = new Array(this.slideCountdownStep+1).join('_');
	}
};
switch (Galerie.LANG) {
	case 'de': Galerie.prototype.l10n = {
			close:		'Schließen',
			slideshow:	'Diashow',
			picture:	'Bild',
			of:		'von',
			prev:		'Vorheriges Bild',
			next:		'Nächstes Bild'};
		break;
	case 'es': Galerie.prototype.l10n = {
			close:		'Final',
			slideshow:	'Slideshow',
			picture:	'Cuadro',
			of:		'de',
			prev:		'Cuadro anterior',
			next:		'Cuadro siguiente'};
		break;
	case 'fr': Galerie.prototype.l10n = {
			close:		'Fin',
			slideshow:	'Présentation',
			picture:	'Image',
			of:		'sur',
			prev:		'Image précédente',
			next:		'Image suivante'};
		break;
	case 'nl': Galerie.prototype.l10n = {
			close:		'Eind',
			slideshow:	'Slideshow',
			picture:	'Beeld',
			of:		'van de',
			prev:		'Vorige beeld',
			next:		'Volgende beeld'};
		break;
	case 'en':
	default: Galerie.prototype.l10n = {
			close:		'Close',
			slideshow:	'Slideshow',
			picture:	'Picture',
			of:		'of',
			prev:		'Previous picture',
			next:		'Next picture'};
}

if(!Function.prototype.bind) Function.prototype.bind = function() {
	var __method = this, args = arguments.length == 1 ? [arguments[0]] : Array.apply(null, arguments), object = args.shift();
	return function() {
		return __method.apply(object, args.concat(arguments.length == 1 ? [arguments[0]] : Array.apply(null, arguments)));
	}
};