Slideshow=new Class({Implements: [Chain, Events, Options],
options:{captions: false,
center: true,
classes: [],
controller: false,
delay: 2000,
duration: 750,
fast: false,
height: false,
href:'',
hu:'/',
linked: false,
loader:{'animate': ['res/css/loader-#.png', 12]},
loop: true,
match: /\?slide=(\d+)$/,
overlap: true,
paused: false,
random: false,
replace: [/^slides(.*)$/, 'thumbs$1'],
resize: true,
slide: 0,
thumbnails: false,
transition: function(p){return -(Math.cos(Math.PI * p) - 1) / 2;},
width: false
},
initialize: function(el, data, options){this.setOptions(options);
this.slideshow=$(el);
if (!this.slideshow) 
return;
this.slideshow.set('styles',{'display':'block', 'position':'relative', 'z-index': 0});
var match=window.location.href.match(this.options.match);
this.slide=(this.options.match && match) ? match[1].toInt() : this.options.slide;
this.counter=this.delay=this.transition=0;
this.direction='left';
this.paused=false;
if (!this.options.overlap)
this.options.duration *=2;
var anchor=this.slideshow.getElement('a') || new Element('a');
if (!this.options.href)
this.options.href=anchor.get('href') || '';
if (this.options.hu.substr(-1) !='/') 
this.options.hu+='/';
var keys=['slideshow', 'first', 'prev', 'play', 'pause', 'next', 'last', 'images', 'captions', 'controller', 'thumbnails', 'hidden', 'visible', 'inactive', 'active', 'loader'];
var values=keys.map(function(key, i){return this.options.classes[i] || key;}, this);
this.classes=values.associate(keys);
this.classes.get=function(){var str='.'+this.slideshow;
for (var i=0, l=arguments.length; i < l; i++)
str+=('-'+this[arguments[i]]);
return str;}.bind(this.classes);
if (!data){data={};
this.slideshow.getElements(this.classes.get('images')+' img').each(function(img){var src=img.get('src').split('/').getLast();
var caption=img.get('alt') || img.get('title') || '';
var href=img.getParent().get('href') || '';
data[src]={'caption': caption, 'href': href};});}
var loaded=this.load(data);
if (!loaded)
return; 
this.events=$H({'keydown': [], 'keyup': [], 'mousemove': []});
var keyup=function(e){switch(e.key){case 'left': 
this.prev(e.shift); break;
case 'right': 
this.next(e.shift); break;
case 'p': 
this.pause(); break;}}.bind(this);
this.events.keyup.push(keyup);
document.addEvent('keyup', keyup);
var el=this.slideshow.getElement(this.classes.get('images'));
var images=(el) ? el.empty() : new Element('div',{'class': this.classes.get('images').substr(1)}).inject(this.slideshow);
var div=images.getSize();
this.height=this.options.height || div.y;
this.width=this.options.width || div.x;
images.set({'styles':{'display':'block', 'height': this.height, 'overflow':'hidden', 'position':'relative', 'width': this.width}});
this.slideshow.store('images', images);
this.a=this.image=this.slideshow.getElement('img') || new Element('img');
this.a.set('styles',{'display':'none', 'position':'absolute', 'zIndex': 1});
this.b=this.a.clone();
[this.a, this.b].each(function(img){anchor.clone().grab(img).inject(images);});
if (this.options.captions)
this._captions();
if (this.options.controller)
this._controller();
if (this.options.loader)
this._loader();
if (this.options.thumbnails)
this._thumbnails();
this._preload();},
go: function(n, direction){if ((this.slide - 1+this.data.images.length) % this.data.images.length==n || $time() < this.transition)
return;
$clear(this.timer);
this.delay=0;
this.direction=(direction) ? direction : ((n < this.slide) ? 'right' :'left');
this.slide=n;
if (this.preloader) 
this.preloader=this.preloader.destroy();
this._preload(this.options.fast || this.paused);},
first: function(){this.prev(true);},
prev: function(first){var n=0;
if (!first){if (this.options.random){
if (this.showed.i < 2)
return;
this.showed.i -=2;
n=this.showed.array[this.showed.i];}
else
n=(this.slide - 2+this.data.images.length) % this.data.images.length;}
this.go(n, 'right');},
pause: function(p){if ($chk(p))
this.paused=(p) ? false : true;
if (this.paused){this.paused=false;
this.delay=this.transition=0;
this.timer=this._preload.delay(100, this);
[this.a, this.b].each(function(img){['morph', 'tween'].each(function(p){if (this.retrieve(p)) this.get(p).resume();}, img);});
if (this.options.controller)
this.slideshow.getElement('.'+this.classes.pause).removeClass(this.classes.play);}
else{this.paused=true;
this.delay=Number.MAX_VALUE;
this.transition=0;
$clear(this.timer);
[this.a, this.b].each(function(img){['morph', 'tween'].each(function(p){if (this.retrieve(p)) this.get(p).pause();}, img);});
if (this.options.controller)
this.slideshow.getElement('.'+this.classes.pause).addClass(this.classes.play);}},
next: function(last){var n=(last) ? this.data.images.length - 1 : this.slide;
this.go(n, 'left');},
last: function(){this.next(true);},
load: function(data){this.firstrun=true;
this.showed={'array': [], 'i': 0};
if ($type(data)=='array'){this.options.captions=false;
data=new Array(data.length).associate(data);}
this.data={'images': [], 'captions': [], 'hrefs': [], 'thumbnails': []};
for (image in data){var obj=data[image] ||{};
var caption=(obj.caption) ? obj.caption.trim() :'';
var href=(obj.href) ? obj.href.trim() : ((this.options.linked) ? this.options.hu+image : this.options.href);
var thumbnail=(obj.thumbnail) ? obj.thumbnail.trim() : image.replace(this.options.replace[0], this.options.replace[1]);
this.data.images.push(image);
this.data.captions.push(caption);
this.data.hrefs.push(href);
this.data.thumbnails.push(thumbnail);}
if (this.options.thumbnails && this.slideshow.retrieve('thumbnails'))
this._thumbnails();
if (this.slideshow.retrieve('images')){[this.a, this.b].each(function(img){['morph', 'tween'].each(function(p){if (this.retrieve(p)) this.get(p).cancel();}, img);});
this.slide=this.transition=0;
this.go(0);}
return this.data.images.length;},
destroy: function(p){this.events.each(function(array, e){array.each(function(fn){document.removeEvent(e, fn);});});
this.pause(1);
if (this.options.loader)
$clear(this.slideshow.retrieve('loader').retrieve('timer'));
if (this.options.thumbnails)
$clear(this.slideshow.retrieve('thumbnails').retrieve('timer'));
Element.Storage[this.slideshow.uid]={};
if (p)
$try(this.slideshow[p]());},
_preload: function(fast){if (!this.preloader)
this.preloader=new Asset.image(this.options.hu+this.data.images[this.slide],{'onload': function(){this.store('loaded', true);}});
if (this.preloader.retrieve('loaded') && $time() > this.delay && $time() > this.transition){if (this.stopped){if (this.options.captions)
this.slideshow.retrieve('captions').get('morph').cancel().start(this.classes.get('captions', 'hidden'));
this.pause(1);
this.stopped=false;
return;}
this.image=(this.counter % 2) ? this.b : this.a;
this.image.set('styles',{'display':'block', 'height':'auto', 'visibility':'hidden', 'width':'auto', 'zIndex': this.counter});
['src', 'height', 'width'].each(function(prop){this.image.set(prop, this.preloader.get(prop));}, this);
this._resize(this.image);
this._center(this.image);
var anchor=this.image.getParent();
if (this.data.hrefs[this.slide])
anchor.set('href', this.data.hrefs[this.slide]);
else
anchor.erase('href');
if (this.data.captions[this.slide])
anchor.set('title', this.data.captions[this.slide].replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, "'"));
else
anchor.erase('title');
if (this.options.loader)
this.slideshow.retrieve('loader').fireEvent('hide');
if (this.options.captions)
this.slideshow.retrieve('captions').fireEvent('update', fast);
if (this.options.thumbnails)
this.slideshow.retrieve('thumbnails').fireEvent('update', fast); 
this._show(fast);
this._loaded();}
else{if ($time() > this.delay && this.options.loader)
this.slideshow.retrieve('loader').fireEvent('show');
this.timer=(this.paused && this.preloader.retrieve('loaded')) ? null : this._preload.delay(100, this, fast);}},
_show: function(fast){if (!this.image.retrieve('morph')){var options=(this.options.overlap) ?{'duration': this.options.duration, 'link':'cancel'}:{'duration': this.options.duration / 2, 'link':'chain'};
$$(this.a, this.b).set('morph', $merge(options,{'transition': this.options.transition}));}
var hidden=this.classes.get('images', ((this.direction=='left') ? 'next' :'prev'));
var visible=this.classes.get('images', 'visible');
var img=(this.counter % 2) ? this.a : this.b;
if (fast){img.get('morph').cancel().set(hidden);
this.image.get('morph').cancel().set(visible);}
else{if (this.options.overlap){img.get('morph').set(visible);
this.image.get('morph').set(hidden).start(visible);}
else{var fn=function(hidden, visible){this.image.get('morph').set(hidden).start(visible);}.pass([hidden, visible], this);
hidden=this.classes.get('images', ((this.direction=='left') ? 'prev' :'next'));
img.get('morph').set(visible).start(hidden).chain(fn);}}},
_loaded: function(){this.counter++;
this.delay=(this.paused) ? Number.MAX_VALUE : $time()+this.options.duration+this.options.delay;
this.direction='left';
this.transition=(this.paused || this.options.fast) ? 0 : $time()+this.options.duration;
if ((this.slide+1==this.data.images.length && !this.options.loop && !this.options.random) || (this.firstrun && this.options.paused))
this.stopped=true;
if (this.options.random){this.showed.i++;
if (this.showed.i >=this.showed.array.length){var n=this.slide;
if (this.showed.array.getLast() !=n) this.showed.array.push(n);
while (this.slide==n)
this.slide=$random(0, this.data.images.length - 1);}
else
this.slide=this.showed.array[this.showed.i];}
else
this.slide=(this.slide+1) % this.data.images.length;
this.firstrun=false;
if (this.preloader) 
this.preloader=this.preloader.destroy();
this._preload();},
_center: function(img){if (this.options.center){var size=img.getSize();
img.set('styles',{'left': (size.x - this.width) / -2, 'top': (size.y - this.height) / -2});}},
_resize: function(img){if (this.options.resize){var h=this.preloader.get('height');
var w=this.preloader.get('width');
var dh=this.height / h;
var dw=this.width / w;
var delta=(dw > dh) ? dw : dh;
img.set('styles',{height: Math.ceil(h * delta), width: Math.ceil(w * delta)});}},
_captions: function(){if (this.options.captions===true) 
this.options.captions={};
var el=this.slideshow.getElement(this.classes.get('captions'));
var captions=(el) ? el.empty() : new Element('div',{'class': this.classes.get('captions').substr(1)}).inject(this.slideshow);
captions.set({'events':{'update': function(fast){var captions=this.slideshow.retrieve('captions');
var empty=(this.data.captions[this.slide]==='');
if (fast){var p=(empty) ? 'hidden' :'visible';
captions.set('html', this.data.captions[this.slide]).get('morph').cancel().set(this.classes.get('captions', p));}
else{var fn=(empty) ? $empty : function(n){this.slideshow.retrieve('captions').set('html', this.data.captions[n]).morph(this.classes.get('captions', 'visible'))
}.pass(this.slide, this);
captions.get('morph').cancel().start(this.classes.get('captions', 'hidden')).chain(fn);}}.bind(this)
},
'morph': $merge(this.options.captions,{'link':'chain'})
});
this.slideshow.store('captions', captions);},
_controller: function(){if (this.options.controller===true)
this.options.controller={};
var el=this.slideshow.getElement(this.classes.get('controller'));
var controller=(el) ? el.empty() : new Element('div',{'class': this.classes.get('controller').substr(1)}).inject(this.slideshow);
var ul=new Element('ul').inject(controller);
$H({'first':'Shift+Leftwards Arrow', 'prev':'Leftwards Arrow', 'pause':'P', 'next':'Rightwards Arrow', 'last':'Shift+Rightwards Arrow'}).each(function(accesskey, action){var li=new Element('li',{'class': (action=='pause' && this.options.paused) ? this.classes.play+' '+this.classes[action] : this.classes[action]
}).inject(ul);
var a=this.slideshow.retrieve(action, new Element('a',{'title': ((action=='pause') ? this.classes.play.capitalize()+' / ' :'')+this.classes[action].capitalize()+' ['+accesskey+']'
}).inject(li));
a.set('events',{'click': function(action){this[action]();}.pass(action, this),
'mouseenter': function(active){this.addClass(active);}.pass(this.classes.active, a),
'mouseleave': function(active){this.removeClass(active);}.pass(this.classes.active, a)
});}, this);
controller.set({'events':{'hide': function(hidden){if (!this.retrieve('hidden'))
this.store('hidden', true).morph(hidden);}.pass(this.classes.get('controller', 'hidden'), controller),
'show': function(visible){if (this.retrieve('hidden'))
this.store('hidden', false).morph(visible);}.pass(this.classes.get('controller', 'visible'), controller)
},
'morph': $merge(this.options.controller,{'link':'cancel'})
}).store('hidden', false);
var keydown=function(e){if (['left', 'right', 'p'].contains(e.key)){var controller=this.slideshow.retrieve('controller');
if (controller.retrieve('hidden'))
controller.get('morph').set(this.classes.get('controller', 'visible')); 
switch(e.key){case 'left': 
this.slideshow.retrieve((e.shift) ? 'first' :'prev').fireEvent('mouseenter'); break;
case 'right':
this.slideshow.retrieve((e.shift) ? 'last' :'next').fireEvent('mouseenter'); break;
default:
this.slideshow.retrieve('pause').fireEvent('mouseenter'); break;}}}.bind(this);
this.events.keydown.push(keydown);
var keyup=function(e){if (['left', 'right', 'p'].contains(e.key)){var controller=this.slideshow.retrieve('controller');
if (controller.retrieve('hidden'))
controller.store('hidden', false).fireEvent('hide'); 
switch(e.key){case 'left': 
this.slideshow.retrieve((e.shift) ? 'first' :'prev').fireEvent('mouseleave'); break;
case 'right': 
this.slideshow.retrieve((e.shift) ? 'last' :'next').fireEvent('mouseleave'); break;
default:
this.slideshow.retrieve('pause').fireEvent('mouseleave'); break;}}}.bind(this);
this.events.keyup.push(keyup);
var mousemove=function(e){var images=this.slideshow.retrieve('images').getCoordinates();
if (e.page.x > images.left && e.page.x < images.right && e.page.y > images.top && e.page.y < images.bottom)
this.slideshow.retrieve('controller').fireEvent('show');
else
this.slideshow.retrieve('controller').fireEvent('hide');}.bind(this);
this.events.mousemove.push(mousemove);
document.addEvents({'keydown': keydown, 'keyup': keyup, 'mousemove': mousemove});
this.slideshow.retrieve('controller', controller).fireEvent('hide');},
_loader: function(){if (this.options.loader===true) 
this.options.loader={};
var loader=new Element('div',{'class': this.classes.get('loader').substr(1),
'morph': $merge(this.options.loader,{'link':'cancel'})
}).store('hidden', false).store('i', 1).inject(this.slideshow.retrieve('images'));
if (this.options.loader.animate){for (var i=0; i < this.options.loader.animate[1]; i++)
img=new Asset.image(this.options.loader.animate[0].replace(/#/, i));
if (Browser.Engine.trident4 && this.options.loader.animate[0].contains('png'))
loader.setStyle('backgroundImage', 'none');}
loader.set('events',{'animate': function(){var loader=this.slideshow.retrieve('loader');
var i=(loader.retrieve('i').toInt()+1) % this.options.loader.animate[1];
loader.store('i', i);
var img=this.options.loader.animate[0].replace(/#/, i);
if (Browser.Engine.trident4 && this.options.loader.animate[0].contains('png'))
loader.style.filter='progid:DXImageTransform.Microsoft.AlphaImageLoader(src="'+img+'", sizingMethod="scale")';
else 
loader.setStyle('backgroundImage', 'url('+img+')');}.bind(this),
'hide': function(){var loader=this.slideshow.retrieve('loader');
if (!loader.retrieve('hidden')){loader.store('hidden', true).morph(this.classes.get('loader', 'hidden'));
if (this.options.loader.animate)
$clear(loader.retrieve('timer'));}}.bind(this),
'show': function(){var loader=this.slideshow.retrieve('loader');
if (loader.retrieve('hidden')){loader.store('hidden', false).morph(this.classes.get('loader', 'visible'));
if (this.options.loader.animate)
loader.store('timer', function(){this.fireEvent('animate');}.periodical(50, loader));}}.bind(this)
});
this.slideshow.retrieve('loader', loader).fireEvent('hide');},
_thumbnails: function(){if (this.options.thumbnails===true) 
this.options.thumbnails={}; 
var el=this.slideshow.getElement(this.classes.get('thumbnails'));
var thumbnails=(el) ? el.empty() : new Element('div',{'class': this.classes.get('thumbnails').substr(1)}).inject(this.slideshow);
thumbnails.setStyle('overflow', 'hidden');
var ul=new Element('ul',{'tween':{'link':'cancel'}}).inject(thumbnails);
this.data.thumbnails.each(function(thumbnail, i){var li=new Element('li').inject(ul);
var a=new Element('a',{'events':{'click': function(i){this.go(i); 
return false;}.pass(i, this),
'loaded': function(){this.data.thumbnails.pop();
if (!this.data.thumbnails.length){var div=thumbnails.getCoordinates();
var props=thumbnails.retrieve('props');
var limit=0, pos=props[1], size=props[2];
thumbnails.getElements('li').each(function(li){var li=li.getCoordinates();
if (li[pos] > limit) limit=li[pos];}, this);
thumbnails.store('limit', div[size]+div[props[0]] - limit);}}.bind(this)
},
'href': this.options.hu+this.data.images[i],
'morph': $merge(this.options.thumbnails,{'link':'cancel'}),
'title': this.data.captions[i]
}).inject(li);
var img=new Asset.image(this.options.hu+thumbnail,{'onload': function(){this.fireEvent('loaded');}.bind(a) 
}).inject(a);}, this);
thumbnails.set('events',{'scroll': function(n, fast){var div=this.getCoordinates();
var ul=this.getElement('ul').getPosition();
var props=this.retrieve('props');
var axis=props[3], delta, pos=props[0], size=props[2], value;
var tween=this.getElement('ul').get('tween',{'property': pos});
if ($chk(n)){var li=this.getElements('li')[n].getCoordinates();
delta=div[pos]+(div[size] / 2) - (li[size] / 2) - li[pos]
value=(ul[axis] - div[pos]+delta).limit(this.retrieve('limit'), 0);
if (fast)
tween.set(value);
else 
tween.start(value);}
else{var area=div[props[2]] / 3, page=this.retrieve('page'), velocity=-0.2;
if (page[axis] < (div[pos]+area))
delta=(page[axis] - div[pos] - area) * velocity;
else if (page[axis] > (div[pos]+div[size] - area))
delta=(page[axis] - div[pos] - div[size]+area) * velocity;
if (delta){value=(ul[axis] - div[pos]+delta).limit(this.retrieve('limit'), 0);
tween.set(value);}}}.bind(thumbnails),
'update': function(fast){var thumbnails=this.slideshow.retrieve('thumbnails');
thumbnails.getElements('a').each(function(a, i){if (i==this.slide){if (!a.retrieve('active', false)){a.store('active', true);
var active=this.classes.get('thumbnails', 'active');
if (fast) a.get('morph').set(active);
else a.morph(active);}}
else{if (a.retrieve('active', true)){a.store('active', false);
var inactive=this.classes.get('thumbnails', 'inactive');
if (fast) a.get('morph').set(inactive);
else a.morph(inactive);}}}, this);
if (!thumbnails.retrieve('mouseover'))
thumbnails.fireEvent('scroll', [this.slide, fast]);}.bind(this)
})
var div=thumbnails.getCoordinates();
thumbnails.store('props', (div.height > div.width) ? ['top', 'bottom', 'height', 'y'] : ['left', 'right', 'width', 'x']);
var mousemove=function(e){var div=this.getCoordinates();
if (e.page.x > div.left && e.page.x < div.right && e.page.y > div.top && e.page.y < div.bottom){this.store('page', e.page);
if (!this.retrieve('mouseover')){this.store('mouseover', true);
this.store('timer', function(){this.fireEvent('scroll');}.periodical(50, this));}}
else{if (this.retrieve('mouseover')){this.store('mouseover', false);
$clear(this.retrieve('timer'));}}}.bind(thumbnails);
this.events.mousemove.push(mousemove);
document.addEvent('mousemove', mousemove);
this.slideshow.store('thumbnails', thumbnails);}});
