Add desktop summit page
[marble] / www / scripts / jd.gallery.js
1 /*
2     This file is part of JonDesign's SmoothGallery v2.1beta1.
3
4     JonDesign's SmoothGallery is free software; you can redistribute it and/or modify
5     it under the terms of the GNU General Public License as published by
6     the Free Software Foundation; either version 3 of the License, or
7     (at your option) any later version.
8
9     JonDesign's SmoothGallery is distributed in the hope that it will be useful,
10     but WITHOUT ANY WARRANTY; without even the implied warranty of
11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12     GNU General Public License for more details.
13
14     You should have received a copy of the GNU General Public License
15     along with JonDesign's SmoothGallery; if not, write to the Free Software
16     Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
17
18     Main Developer: Jonathan Schemoul (JonDesign: http://www.jondesign.net/)
19     Contributed code by:
20     - Christian Ehret (bugfix)
21         - Nitrix (bugfix)
22         - Valerio from Mad4Milk for his great help with the carousel scrolling and many other things.
23         - Archie Cowan for helping me find a bugfix on carousel inner width problem.
24         - Tomocchino from #mootools for the preloader class
25         Many thanks to:
26         - The mootools team for the great mootools lib, and it's help and support throughout the project.
27         - Harald Kirschner (digitarald: http://digitarald.de/) for all his great libs. Some used here as plugins.
28 */
29
30 /* some quirks to circumvent broken stuff in mt1.2 */
31 function isBody(element){
32         return (/^(?:body|html)$/i).test(element.tagName);
33 };
34 Element.implement({
35         getPosition: function(relative){
36                 if (isBody(this)) return {x: 0, y: 0};
37                 var el = this, position = {x: 0, y: 0};
38                 while (el){
39                         position.x += el.offsetLeft;
40                         position.y += el.offsetTop;
41                         el = el.offsetParent;
42                 }
43                 var rpos = (relative) ? $(relative).getPosition() : {x: 0, y: 0};
44                 return {x: position.x - rpos.x, y: position.y - rpos.y};
45         }
46 });
47
48 // declaring the class
49 var gallery = {
50         Implements: [Events, Options],
51         options: {
52                 showArrows: true,
53                 showCarousel: true,
54                 showInfopane: true,
55                 embedLinks: true,
56                 fadeDuration: 500,
57                 timed: false,
58                 delay: 9000,
59                 preloader: true,
60                 preloaderImage: true,
61                 preloaderErrorImage: true,
62                 /* Data retrieval */
63                 manualData: [],
64                 populateFrom: false,
65                 populateData: true,
66                 destroyAfterPopulate: true,
67                 elementSelector: "div.imageElement",
68                 titleSelector: "h3",
69                 subtitleSelector: "p",
70                 linkSelector: "a.open",
71                 imageSelector: "img.full",
72                 thumbnailSelector: "img.thumbnail",
73                 defaultTransition: "fade",
74                 /* InfoPane options */
75                 slideInfoZoneOpacity: 0.7,
76                 slideInfoZoneSlide: true,
77                 /* Carousel options */
78                 carouselMinimizedOpacity: 0.4,
79                 carouselMinimizedHeight: 20,
80                 carouselMaximizedOpacity: 0.9,
81                 thumbHeight: 75,
82                 thumbWidth: 100,
83                 thumbSpacing: 10,
84                 thumbIdleOpacity: 0.2,
85                 textShowCarousel: 'Pictures',
86                 showCarouselLabel: true,
87                 thumbCloseCarousel: true,
88                 useThumbGenerator: false,
89                 thumbGenerator: 'resizer.php',
90                 useExternalCarousel: false,
91                 carouselElement: false,
92                 carouselHorizontal: true,
93                 activateCarouselScroller: true,
94                 carouselPreloader: true,
95                 textPreloadingCarousel: 'Loading...',
96                 /* CSS Classes */
97                 baseClass: 'jdGallery',
98                 withArrowsClass: 'withArrows',
99                 /* Plugins: HistoryManager */
100                 useHistoryManager: false,
101                 customHistoryKey: false,
102                 /* Plugins: ReMooz */
103                 useReMooz: false
104         },
105         initialize: function(element, options) {
106                 this.setOptions(options);
107                 this.fireEvent('onInit');
108                 this.currentIter = 0;
109                 this.lastIter = 0;
110                 this.maxIter = 0;
111                 this.galleryElement = element;
112                 this.galleryData = this.options.manualData;
113                 this.galleryInit = 1;
114                 this.galleryElements = Array();
115                 this.thumbnailElements = Array();
116                 this.galleryElement.addClass(this.options.baseClass);
117                 
118                 if (this.options.useReMooz&&(this.options.defaultTransition=="fade"))
119                         this.options.defaultTransition="crossfade";
120                 
121                 this.populateFrom = element;
122                 if (this.options.populateFrom)
123                         this.populateFrom = this.options.populateFrom;          
124                 if (this.options.populateData)
125                         this.populateData();
126                 element.style.display="block";
127                 
128                 if (this.options.useHistoryManager)
129                         this.initHistory();
130                 
131                 if ((this.options.embedLinks)|(this.options.useReMooz))
132                 {
133                         this.currentLink = new Element('a').addClass('open').setProperties({
134                                 href: '#',
135                                 title: ''
136                         }).injectInside(element);
137                         if ((!this.options.showArrows) && (!this.options.showCarousel))
138                                 this.galleryElement = element = this.currentLink;
139                         else
140                                 this.currentLink.setStyle('display', 'none');
141                 }
142                 
143                 this.constructElements();
144                 if ((this.galleryData.length>1)&&(this.options.showArrows))
145                 {
146                         var leftArrow = new Element('a').addClass('left').addEvent(
147                                 'click',
148                                 this.prevItem.bind(this)
149                         ).injectInside(element);
150                         var rightArrow = new Element('a').addClass('right').addEvent(
151                                 'click',
152                                 this.nextItem.bind(this)
153                         ).injectInside(element);
154                         this.galleryElement.addClass(this.options.withArrowsClass);
155                 }
156                 this.loadingElement = new Element('div').addClass('loadingElement').injectInside(element);
157                 if (this.options.showInfopane) this.initInfoSlideshow();
158                 if (this.options.showCarousel) this.initCarousel();
159                 this.doSlideShow(1);
160         },
161         populateData: function() {
162                 currentArrayPlace = this.galleryData.length;
163                 options = this.options;
164                 var data = $A(this.galleryData);
165                 data.extend(this.populateGallery(this.populateFrom, currentArrayPlace));
166                 this.galleryData = data;
167                 this.fireEvent('onPopulated');
168         },
169         populateGallery: function(element, startNumber) {
170                 var data = [];
171                 options = this.options;
172                 currentArrayPlace = startNumber;
173                 element.getElements(options.elementSelector).each(function(el) {
174                         elementDict = $H({
175                                 image: el.getElement(options.imageSelector).getProperty('src'),
176                                 number: currentArrayPlace,
177                                 transition: this.options.defaultTransition
178                         });
179                         if ((options.showInfopane) | (options.showCarousel))
180                                 elementDict.extend({
181                                         title: el.getElement(options.titleSelector).innerHTML,
182                                         description: el.getElement(options.subtitleSelector).innerHTML
183                                 });
184                         if ((options.embedLinks) | (options.useReMooz))
185                                 elementDict.extend({
186                                         link: el.getElement(options.linkSelector).href||false,
187                                         linkTitle: el.getElement(options.linkSelector).title||false,
188                                         linkTarget: el.getElement(options.linkSelector).getProperty('target')||false
189                                 });
190                         if ((!options.useThumbGenerator) && (options.showCarousel))
191                                 elementDict.extend({
192                                         thumbnail: el.getElement(options.thumbnailSelector).getProperty('src')
193                                 });
194                         else if (options.useThumbGenerator)
195                                 elementDict.extend({
196                                         thumbnail: options.thumbGenerator + '?imgfile=' + elementDict.image + '&max_width=' + options.thumbWidth + '&max_height=' + options.thumbHeight
197                                 });
198                         
199                         data.extend([elementDict]);
200                         currentArrayPlace++;
201                         if (this.options.destroyAfterPopulate)
202                                 el.dispose();
203                 });
204                 return data;
205         },
206         constructElements: function() {
207                 el = this.galleryElement;
208                 if (this.options.embedLinks && (!this.options.showArrows))
209                         el = this.currentLink;
210                 this.maxIter = this.galleryData.length;
211                 var currentImg;
212                 for(i=0;i<this.galleryData.length;i++)
213                 {
214                         var currentImg = new Fx.Morph(
215                                 new Element('div').addClass('slideElement').setStyles({
216                                         'position':'absolute',
217                                         'left':'0px',
218                                         'right':'0px',
219                                         'margin':'0px',
220                                         'padding':'0px',
221                                         'backgroundPosition':"center center",
222                                         'opacity':'0'\r
223                                 }).injectInside(el),
224                                 {duration: this.options.fadeDuration}
225                         );
226                         if (this.options.preloader)
227                         {
228                                 currentImg.source = this.galleryData[i].image;
229                                 currentImg.loaded = false;
230                                 currentImg.load = function(imageStyle, i) {
231                                         if (!imageStyle.loaded) {
232                                                 this.galleryData[i].imgloader = new Asset.image(imageStyle.source, {
233                                             'onload'  : function(img, i){
234                                                                                                         img.element.setStyle(
235                                                                                                         'backgroundImage',
236                                                                                                         "url('" + img.source + "')")
237                                                                                                         img.loaded = true;
238                                                                                                         img.width = this.galleryData[i].imgloader.width;
239                                                                                                         img.height = this.galleryData[i].imgloader.height;
240                                                                                                 }.pass([imageStyle, i], this)
241                                                 });
242                                         }
243                                 }.pass([currentImg, i], this);
244                         } else {
245                                 currentImg.element.setStyle('backgroundImage',
246                                                                         "url('" + this.galleryData[i].image + "')");
247                         }
248                         this.galleryElements[parseInt(i)] = currentImg;
249                 }
250         },
251         destroySlideShow: function(element) {
252                 var myClassName = element.className;
253                 var newElement = new Element('div').addClass('myClassName');
254                 element.parentNode.replaceChild(newElement, element);
255         },
256         startSlideShow: function() {
257                 this.fireEvent('onStart');
258                 this.loadingElement.style.display = "none";
259                 this.lastIter = this.maxIter - 1;
260                 this.currentIter = 0;
261                 this.galleryInit = 0;
262                 this.galleryElements[parseInt(this.currentIter)].set({opacity: 1});
263                 if (this.options.showInfopane)
264                         this.showInfoSlideShow.delay(1000, this);
265                 if (this.options.useReMooz)
266                         this.makeReMooz.delay(1000, this);
267                 var textShowCarousel = formatString(this.options.textShowCarousel, this.currentIter+1, this.maxIter);
268                 if (this.options.showCarousel&&(!this.options.carouselPreloader)&&(!this.options.useExternalCarousel))
269                         this.carouselBtn.set('html', textShowCarousel).setProperty('title', textShowCarousel);
270                 this.prepareTimer();
271                 if (this.options.embedLinks)
272                         this.makeLink(this.currentIter);
273         },
274         nextItem: function() {
275                 this.fireEvent('onNextCalled');
276                 this.nextIter = this.currentIter+1;
277                 if (this.nextIter >= this.maxIter)
278                         this.nextIter = 0;
279                 this.galleryInit = 0;
280                 this.goTo(this.nextIter);
281         },
282         prevItem: function() {
283                 this.fireEvent('onPreviousCalled');
284                 this.nextIter = this.currentIter-1;
285                 if (this.nextIter <= -1)
286                         this.nextIter = this.maxIter - 1;
287                 this.galleryInit = 0;
288                 this.goTo(this.nextIter);
289         },
290         goTo: function(num) {
291                 this.clearTimer();
292                 if(this.options.preloader)
293                 {
294                         this.galleryElements[num].load();
295                         if (num==0)
296                                 this.galleryElements[this.maxIter - 1].load();
297                         else
298                                 this.galleryElements[num - 1].load();
299                         if (num==(this.maxIter - 1))
300                                 this.galleryElements[0].load();
301                         else
302                                 this.galleryElements[num + 1].load();
303                                 
304                 }
305                 if (this.options.embedLinks)
306                         this.clearLink();
307                 if (this.options.showInfopane)
308                 {
309                         this.slideInfoZone.clearChain();
310                         this.hideInfoSlideShow().chain(this.changeItem.pass(num, this));
311                 } else
312                         this.currentChangeDelay = this.changeItem.delay(500, this, num);
313                 if (this.options.embedLinks)
314                         this.makeLink(num);
315                 this.prepareTimer();
316                 /*if (this.options.showCarousel)
317                         this.clearThumbnailsHighlights();*/
318         },
319         changeItem: function(num) {
320                 this.fireEvent('onStartChanging');
321                 this.galleryInit = 0;
322                 if (this.currentIter != num)
323                 {
324                         for(i=0;i<this.maxIter;i++)
325                         {
326                                 if ((i != this.currentIter)) this.galleryElements[i].set({opacity: 0});
327                         }
328                         gallery.Transitions[this.galleryData[num].transition].pass([
329                                 this.galleryElements[this.currentIter],
330                                 this.galleryElements[num],
331                                 this.currentIter,
332                                 num], this)();
333                         this.currentIter = num;
334                         if (this.options.useReMooz)
335                                 this.makeReMooz();
336                 }
337                 var textShowCarousel = formatString(this.options.textShowCarousel, num+1, this.maxIter);
338                 if ((this.options.showCarousel)&&(!this.options.useExternalCarousel))
339                         this.carouselBtn.set('html', textShowCarousel).setProperty('title', textShowCarousel);
340                 this.doSlideShow.bind(this)();
341                 this.fireEvent('onChanged');
342         },
343         clearTimer: function() {
344                 if (this.options.timed)
345                         $clear(this.timer);
346         },
347         prepareTimer: function() {
348                 if (this.options.timed)
349                         this.timer = this.nextItem.delay(this.options.delay, this);
350         },
351         doSlideShow: function(position) {
352                 if (this.galleryInit == 1)
353                 {
354                         imgPreloader = new Image();
355                         imgPreloader.onload=function(){
356                                 this.startSlideShow.delay(10, this);
357                         }.bind(this);
358                         imgPreloader.src = this.galleryData[0].image;
359                         if(this.options.preloader)
360                                 this.galleryElements[0].load();
361                 } else {
362                         if (this.options.showInfopane)
363                         {
364                                 if (this.options.showInfopane)
365                                 {
366                                         this.showInfoSlideShow.delay((500 + this.options.fadeDuration), this);
367                                 } else
368                                         if ((this.options.showCarousel)&&(this.options.activateCarouselScroller))
369                                                 this.centerCarouselOn(position);
370                         }
371                 }
372         },
373         createCarousel: function() {
374                 var carouselElement;
375                 if (!this.options.useExternalCarousel)
376                 {
377                         var carouselContainerElement = new Element('div').addClass('carouselContainer').injectInside(this.galleryElement);
378                         this.carouselContainer = new Fx.Morph(carouselContainerElement, {transition: Fx.Transitions.Expo.easeOut});
379                         this.carouselContainer.normalHeight = carouselContainerElement.offsetHeight;
380                         this.carouselContainer.set({'opacity': this.options.carouselMinimizedOpacity, 'top': (this.options.carouselMinimizedHeight - this.carouselContainer.normalHeight)});
381                         this.carouselBtn = new Element('a').addClass('carouselBtn').setProperties({
382                                 title: this.options.textShowCarousel
383                         }).injectInside(carouselContainerElement);
384                         if(this.options.carouselPreloader)
385                                 this.carouselBtn.set('html', this.options.textPreloadingCarousel);
386                         else
387                                 this.carouselBtn.set('html', this.options.textShowCarousel);
388                         this.carouselBtn.addEvent(
389                                 'click',
390                                 function () {
391                                         this.carouselContainer.cancel();
392                                         this.toggleCarousel();
393                                 }.bind(this)
394                         );
395                         this.carouselActive = false;
396         
397                         carouselElement = new Element('div').addClass('carousel').injectInside(carouselContainerElement);
398                         this.carousel = new Fx.Morph(carouselElement);
399                 } else {
400                         carouselElement = $(this.options.carouselElement).addClass('jdExtCarousel');
401                 }
402                 this.carouselElement = new Fx.Morph(carouselElement, {transition: Fx.Transitions.Expo.easeOut});
403                 this.carouselElement.normalHeight = carouselElement.offsetHeight;
404                 if (this.options.showCarouselLabel)
405                         this.carouselLabel = new Element('p').addClass('label').injectInside(carouselElement);
406                 carouselWrapper = new Element('div').addClass('carouselWrapper').injectInside(carouselElement);
407                 this.carouselWrapper = new Fx.Morph(carouselWrapper, {transition: Fx.Transitions.Expo.easeOut});
408                 this.carouselWrapper.normalHeight = carouselWrapper.offsetHeight;
409                 this.carouselInner = new Element('div').addClass('carouselInner').injectInside(carouselWrapper);
410                 if (this.options.activateCarouselScroller)
411                 {
412                         this.carouselWrapper.scroller = new Scroller(carouselWrapper, {
413                                 area: 100,
414                                 velocity: 0.2
415                         })
416                         
417                         this.carouselWrapper.elementScroller = new Fx.Scroll(carouselWrapper, {
418                                 duration: 400,
419                                 onStart: this.carouselWrapper.scroller.stop.bind(this.carouselWrapper.scroller),
420                                 onComplete: this.carouselWrapper.scroller.start.bind(this.carouselWrapper.scroller)
421                         });
422                 }
423         },
424         fillCarousel: function() {
425                 this.constructThumbnails();
426                 this.carouselInner.normalWidth = ((this.maxIter * (this.options.thumbWidth + this.options.thumbSpacing + 2))+this.options.thumbSpacing) + "px";
427                 if (this.options.carouselHorizontal)
428                         this.carouselInner.style.width = this.carouselInner.normalWidth;
429         },
430         initCarousel: function () {
431                 this.createCarousel();
432                 this.fillCarousel();
433                 if (this.options.carouselPreloader)
434                         this.preloadThumbnails();
435         },
436         flushCarousel: function() {
437                 this.thumbnailElements.each(function(myFx) {
438                         myFx.element.dispose();
439                         myFx = myFx.element = null;
440                 });
441                 this.thumbnailElements = [];
442         },
443         toggleCarousel: function() {
444                 if (this.carouselActive)
445                         this.hideCarousel();
446                 else
447                         this.showCarousel();\r
448         },
449         showCarousel: function () {
450                 this.fireEvent('onShowCarousel');
451                 this.carouselContainer.start({
452                         'opacity': this.options.carouselMaximizedOpacity,
453                         'top': 0
454                 }).chain(function() {
455                         this.carouselActive = true;
456                         this.carouselWrapper.scroller.start();
457                         this.fireEvent('onCarouselShown');
458                         this.carouselContainer.options.onComplete = null;
459                 }.bind(this));
460         },
461         hideCarousel: function () {
462                 this.fireEvent('onHideCarousel');
463                 var targetTop = this.options.carouselMinimizedHeight - this.carouselContainer.normalHeight;
464                 this.carouselContainer.start({
465                         'opacity': this.options.carouselMinimizedOpacity,
466                         'top': targetTop
467                 }).chain(function() {
468                         this.carouselActive = false;
469                         this.carouselWrapper.scroller.stop();
470                         this.fireEvent('onCarouselHidden');
471                         this.carouselContainer.options.onComplete = null;
472                 }.bind(this));
473         },
474         constructThumbnails: function () {
475                 element = this.carouselInner;
476                 for(i=0;i<this.galleryData.length;i++)
477                 {
478                         var currentImg = new Fx.Morph(new Element ('div').addClass("thumbnail").setStyles({
479                                         backgroundImage: "url('" + this.galleryData[i].thumbnail + "')",
480                                         backgroundPosition: "center center",
481                                         backgroundRepeat: 'no-repeat',
482                                         marginLeft: this.options.thumbSpacing + "px",
483                                         width: this.options.thumbWidth + "px",
484                                         height: this.options.thumbHeight + "px"
485                                 }).injectInside(element), {duration: 200}).start({
486                                         'opacity': this.options.thumbIdleOpacity
487                                 });
488                         currentImg.element.addEvents({
489                                 'mouseover': function (myself) {
490                                         myself.cancel();
491                                         myself.start({'opacity': 0.99});
492                                         if (this.options.showCarouselLabel)
493                                                 $(this.carouselLabel).set('html', '<span class="number">' + (myself.relatedImage.number + 1) + "/" + this.maxIter + ":</span> " + myself.relatedImage.title);
494                                 }.pass(currentImg, this),
495                                 'mouseout': function (myself) {
496                                         myself.cancel();
497                                         myself.start({'opacity': this.options.thumbIdleOpacity});
498                                 }.pass(currentImg, this),
499                                 'click': function (myself) {
500                                         this.goTo(myself.relatedImage.number);
501                                         if (this.options.thumbCloseCarousel&&(!this.options.useExternalCarousel))
502                                                 this.hideCarousel();
503                                 }.pass(currentImg, this)\r
504                         });
505                         
506                         currentImg.relatedImage = this.galleryData[i];
507                         this.thumbnailElements[parseInt(i)] = currentImg;
508                 }
509         },
510         log: function(value) {
511                 if(console.log)
512                         console.log(value);
513         },
514         preloadThumbnails: function() {
515                 var thumbnails = [];
516                 for(i=0;i<this.galleryData.length;i++)
517                 {
518                         thumbnails[parseInt(i)] = this.galleryData[i].thumbnail;
519                 }
520                 this.thumbnailPreloader = new Preloader();
521                 if (!this.options.useExternalCarousel)
522                         this.thumbnailPreloader.addEvent('onComplete', function() {
523                                 var textShowCarousel = formatString(this.options.textShowCarousel, this.currentIter+1, this.maxIter);
524                                 this.carouselBtn.set('html', textShowCarousel).setProperty('title', textShowCarousel);
525                         }.bind(this));
526                 this.thumbnailPreloader.load(thumbnails);
527         },
528         clearThumbnailsHighlights: function()
529         {
530                 for(i=0;i<this.galleryData.length;i++)
531                 {
532                         this.thumbnailElements[i].cancel();
533                         this.thumbnailElements[i].start(0.2);
534                 }
535         },
536         changeThumbnailsSize: function(width, height)
537         {
538                 for(i=0;i<this.galleryData.length;i++)
539                 {
540                         this.thumbnailElements[i].cancel();
541                         this.thumbnailElements[i].element.setStyles({
542                                 'width': width + "px",
543                                 'height': height + "px"
544                         });
545                 }
546         },
547         centerCarouselOn: function(num) {
548                 if (!this.carouselWallMode)
549                 {
550                         var carouselElement = this.thumbnailElements[num];
551                         var position = carouselElement.element.offsetLeft + (carouselElement.element.offsetWidth / 2);
552                         var carouselWidth = this.carouselWrapper.element.offsetWidth;
553                         var carouselInnerWidth = this.carouselInner.offsetWidth;
554                         var diffWidth = carouselWidth / 2;
555                         var scrollPos = position-diffWidth;
556                         this.carouselWrapper.elementScroller.start(scrollPos,0);
557                 }
558         },
559         initInfoSlideshow: function() {
560                 /*if (this.slideInfoZone.element)
561                         this.slideInfoZone.element.remove();*/
562                 this.slideInfoZone = new Fx.Morph(new Element('div').addClass('slideInfoZone').injectInside($(this.galleryElement))).set({'opacity':0});
563                 var slideInfoZoneTitle = new Element('h2').injectInside(this.slideInfoZone.element);
564                 var slideInfoZoneDescription = new Element('p').injectInside(this.slideInfoZone.element);
565                 this.slideInfoZone.normalHeight = this.slideInfoZone.element.offsetHeight;
566                 this.slideInfoZone.element.setStyle('opacity',0);
567         },
568         changeInfoSlideShow: function()
569         {
570                 this.hideInfoSlideShow.delay(10, this);
571                 this.showInfoSlideShow.delay(500, this);
572         },
573         showInfoSlideShow: function() {
574                 this.fireEvent('onShowInfopane');
575                 this.slideInfoZone.cancel();
576                 element = this.slideInfoZone.element;
577                 element.getElement('h2').set('html', this.galleryData[this.currentIter].title);
578                 element.getElement('p').set('html', this.galleryData[this.currentIter].description);
579                 if(this.options.slideInfoZoneSlide)
580                         this.slideInfoZone.start({'opacity': [0, this.options.slideInfoZoneOpacity], 'height': [0, this.slideInfoZone.normalHeight]});
581                 else
582                         this.slideInfoZone.start({'opacity': [0, this.options.slideInfoZoneOpacity]});
583                 if (this.options.showCarousel)
584                         this.slideInfoZone.chain(this.centerCarouselOn.pass(this.currentIter, this));
585                 return this.slideInfoZone;
586         },
587         hideInfoSlideShow: function() {
588                 this.fireEvent('onHideInfopane');
589                 this.slideInfoZone.cancel();
590                 if(this.options.slideInfoZoneSlide)
591                         this.slideInfoZone.start({'opacity': 0, 'height': 0});
592                 else
593                         this.slideInfoZone.start({'opacity': 0});
594                 return this.slideInfoZone;
595         },
596         makeLink: function(num) {
597                 this.currentLink.setProperties({
598                         href: this.galleryData[num].link,
599                         title: this.galleryData[num].linkTitle
600                 })
601                 if (!((this.options.embedLinks) && (!this.options.showArrows) && (!this.options.showCarousel)))
602                         this.currentLink.setStyle('display', 'block');
603         },
604         clearLink: function() {
605                 this.currentLink.setProperties({href: '', title: ''});
606                 if (!((this.options.embedLinks) && (!this.options.showArrows) && (!this.options.showCarousel)))
607                         this.currentLink.setStyle('display', 'none');
608         },
609         makeReMooz: function() {
610                 this.currentLink.setProperties({
611                         href: '#'
612                 });
613                 this.currentLink.setStyles({
614                         'display': 'block'
615                 });
616                 
617                 this.galleryElements[this.currentIter].element.set('title', this.galleryData[this.currentIter].title + ' :: ' + this.galleryData[this.currentIter].description);
618                 this.ReMooz = new ReMooz(this.galleryElements[this.currentIter].element, {
619                         link: this.galleryData[this.currentIter].link,
620                         shadow: false,
621                         dragging: false,
622                         addClick: false,
623                         resizeOpacity: 1
624                 });
625                 var img = this.galleryElements[this.currentIter];
626                 var coords = img.element.getCoordinates();
627                 delete coords.right;
628                 delete coords.bottom;
629                 
630                 widthDiff = coords.width - img.width;
631                 heightDiff = coords.height - img.height;
632                 
633                 coords.width = img.width;
634                 coords.height = img.height;
635                 
636                 coords.left += Math.ceil(widthDiff/2)+1;
637                 coords.top += Math.ceil(heightDiff/2)+1;
638                 
639                 this.ReMooz.getOriginCoordinates = function(coords) {
640                         return coords;
641                 }.bind(this, coords);
642                 this.currentLink.onclick = function () {
643                         this.ReMooz.open.bind(this.ReMooz)();
644                         return false;
645                 }.bind(this);
646         },
647         /* To change the gallery data, those two functions : */
648         flushGallery: function() {
649                 this.galleryElements.each(function(myFx) {
650                         myFx.element.dispose();
651                         myFx = myFx.element = null;
652                 });
653                 this.galleryElements = [];
654         },
655         changeData: function(data) {
656                 this.galleryData = data;
657                 this.clearTimer();
658                 this.flushGallery();
659                 if (this.options.showCarousel) this.flushCarousel();
660                 this.constructElements();
661                 if (this.options.showCarousel) this.fillCarousel();
662                 if (this.options.showInfopane) this.hideInfoSlideShow();
663                 this.galleryInit=1;
664                 this.lastIter=0;
665                 this.currentIter=0;
666                 this.doSlideShow(1);
667         },
668         /* Plugins: HistoryManager */
669         initHistory: function() {
670                 this.fireEvent('onHistoryInit');
671                 this.historyKey = this.galleryElement.id + '-picture';
672                 if (this.options.customHistoryKey)
673                         this.historyKey = this.options.customHistoryKey;
674                 
675                 this.history = new History.Route({
676                         defaults: [1],
677                         pattern: this.historyKey + '\\((\\d+)\\)',
678                         generate: function(values) {
679                                 return [this.historyKey, '(', values[0], ')'].join('')
680                         }.bind(this),
681                         onMatch: function(values, defaults) {
682                                 if (parseInt(values[0])-1 < this.maxIter)
683                                         this.goTo(parseInt(values[0])-1);
684                         }.bind(this)
685                 });
686                 this.addEvent('onChanged', function(){
687                         this.history.setValue(0, this.currentIter+1);
688                         this.history.defaults=[this.currentIter+1];
689                 }.bind(this));
690                 this.fireEvent('onHistoryInited');
691         }
692 };
693 gallery = new Class(gallery);
694
695 gallery.Transitions = new Hash ({
696         fade: function(oldFx, newFx, oldPos, newPos){
697                 oldFx.options.transition = newFx.options.transition = Fx.Transitions.linear;
698                 oldFx.options.duration = newFx.options.duration = this.options.fadeDuration;
699                 if (newPos > oldPos) newFx.start({opacity: 1});
700                 else
701                 {
702                         newFx.set({opacity: 1});
703                         oldFx.start({opacity: 0});
704                 }
705         },
706         crossfade: function(oldFx, newFx, oldPos, newPos){
707                 oldFx.options.transition = newFx.options.transition = Fx.Transitions.linear;
708                 oldFx.options.duration = newFx.options.duration = this.options.fadeDuration;
709                 newFx.start({opacity: 1});
710                 oldFx.start({opacity: 0});
711         },
712         fadebg: function(oldFx, newFx, oldPos, newPos){
713                 oldFx.options.transition = newFx.options.transition = Fx.Transitions.linear;
714                 oldFx.options.duration = newFx.options.duration = this.options.fadeDuration / 2;
715                 oldFx.start({opacity: 0}).chain(newFx.start.pass([{opacity: 1}], newFx));
716         }
717 });
718
719 /* All code copyright 2007 Jonathan Schemoul */
720
721 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
722  * Follows: Preloader (class)
723  * Simple class for preloading images with support for progress reporting
724  * Copyright 2007 Tomocchino.
725  * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
726
727 var Preloader = new Class({
728   
729   Implements: [Events, Options],
730
731   options: {
732     root        : '',
733     period      : 100
734   },
735   
736   initialize: function(options){
737     this.setOptions(options);
738   },
739   
740   load: function(sources) {
741     this.index = 0;
742     this.images = [];
743     this.sources = this.temps = sources;
744     this.total = this. sources.length;
745     
746     this.fireEvent('onStart', [this.index, this.total]);
747     this.timer = this.progress.periodical(this.options.period, this);
748     
749     this.sources.each(function(source, index){
750       this.images[index] = new Asset.image(this.options.root + source, {
751         'onload'  : function(){ this.index++; if(this.images[index]) this.fireEvent('onLoad', [this.images[index], index, source]); }.bind(this),
752         'onerror' : function(){ this.index++; this.fireEvent('onError', [this.images.splice(index, 1), index, source]); }.bind(this),
753         'onabort' : function(){ this.index++; this.fireEvent('onError', [this.images.splice(index, 1), index, source]); }.bind(this)
754       });
755     }, this);
756   },
757   
758   progress: function() {
759     this.fireEvent('onProgress', [Math.min(this.index, this.total), this.total]);
760     if(this.index >= this.total) this.complete();
761   },
762   
763   complete: function(){
764     $clear(this.timer);
765     this.fireEvent('onComplete', [this.images]);
766   },
767   
768   cancel: function(){
769     $clear(this.timer);
770   }
771   
772 });
773
774 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
775  * Follows: formatString (function)
776  * Original name: Yahoo.Tools.printf
777  * Copyright Yahoo.
778  * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
779
780 function formatString() {
781         var num = arguments.length;
782         var oStr = arguments[0];
783         for (var i = 1; i < num; i++) {
784                 var pattern = "\\{" + (i-1) + "\\}"; 
785                 var re = new RegExp(pattern, "g");
786                 oStr = oStr.replace(re, arguments[i]);
787         }
788         return oStr; 
789 }