var myURL = window.location.href;
var dateiname = myURL.substr(myURL.lastIndexOf('/')+1);
var titel = dateiname.split('.');


/*
    This file is part of JonDesign's SmoothGallery v2.0.

    JonDesign's SmoothGallery is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.

    JonDesign's SmoothGallery 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 General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with JonDesign's SmoothGallery; if not, write to the Free Software
    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA

    Main Developer: Jonathan Schemoul (JonDesign: http://www.jondesign.net/)
    Contributed code by:
    - Christian Ehret (bugfix)
 - Nitrix (bugfix)
 - Valerio from Mad4Milk for his great help with the carousel scrolling and many other things.
 - Archie Cowan for helping me find a bugfix on carousel inner width problem.
 - Tomocchino from #mootools for the preloader class
 Many thanks to:
 - The mootools team for the great mootools lib, and it's help and support throughout the project.
*/

// declaring the class
var gallery = {
 initialize: function(element, options) {
  this.setOptions({
   showArrows: true,
   showCarousel: true,
   showInfopane: true,
   embedLinks: true,
   fadeDuration: 500,
   timed: false,
   delay: 7000,
   preloader: true,
   preloaderImage: true,
   preloaderErrorImage: true,
   /* Data retrieval */
   manualData: [],
   populateFrom: false,
   populateData: true,
   destroyAfterPopulate: true,
   elementSelector: "div.imageElement",
   titleSelector: "h3",
   subtitleSelector: "p",
   linkSelector: "a.open",
   imageSelector: "img.full",
   thumbnailSelector: "img.thumbnail",
   defaultTransition: "fade",
   /* InfoPane options */
   slideInfoZoneOpacity: 0.5,
   slideInfoZoneSlide: true,
   /* Carousel options */
   carouselMinimizedOpacity: 1,
   carouselMinimizedHeight: 20,
   carouselMaximizedOpacity: 0.8,
   thumbHeight: 75,
   thumbWidth: 100,
   thumbSpacing: 2,
   thumbIdleOpacity: 0.2,
   textShowCarousel: titel[0],
   showCarouselLabel: true,
   thumbCloseCarousel: true,
   useThumbGenerator: false,
   thumbGenerator: 'resizer.php',
   useExternalCarousel: false,
   carouselElement: false,
   carouselHorizontal: true,
   activateCarouselScroller: true,
   carouselPreloader: true,
   textPreloadingCarousel: 'Bilder werden geladen...',
   /* CSS Classes */
   baseClass: 'jdGallery',
   withArrowsClass: 'withArrows',
   /* Plugins: HistoryManager */
   useHistoryManager: false,
   customHistoryKey: false
  }, options);
  this.fireEvent('onInit');
  this.currentIter = 0;
  this.lastIter = 0;
  this.maxIter = 0;
  this.galleryElement = element;
  this.galleryData = this.options.manualData;
  this.galleryInit = 1;
  this.galleryElements = Array();
  this.thumbnailElements = Array();
  this.galleryElement.addClass(this.options.baseClass);

  this.populateFrom = element;
  if (this.options.populateFrom)
   this.populateFrom = this.options.populateFrom;
  if (this.options.populateData)
   this.populateData();
  element.style.display="block";

  if (this.options.useHistoryManager)
   this.initHistory();

  if (this.options.embedLinks)
  {
   this.currentLink = new Element('a').addClass('open').setProperties({
    href: '#',
    title: '',
    rel: 'lytebox[group]'
   }).injectInside(element);
   if ((!this.options.showArrows) && (!this.options.showCarousel))
    this.galleryElement = element = this.currentLink;
   else
    this.currentLink.setStyle('display', 'none');
  }

  this.constructElements();
  if ((this.galleryData.length>1)&&(this.options.showArrows))
  {
   var leftArrow = new Element('a').addClass('left').addEvent(
    'click',
    this.prevItem.bind(this)
   ).injectInside(element);
   var rightArrow = new Element('a').addClass('right').addEvent(
    'click',
    this.nextItem.bind(this)
   ).injectInside(element);
   this.galleryElement.addClass(this.options.withArrowsClass);
  }
  this.loadingElement = new Element('div').addClass('loadingElement').injectInside(element);
  if (this.options.showInfopane) this.initInfoSlideshow();
  if (this.options.showCarousel) this.initCarousel();
  this.doSlideShow(1);
 },
 populateData: function() {
  currentArrayPlace = this.galleryData.length;
  options = this.options;
  var data = $A(this.galleryData);
  data.extend(this.populateGallery(this.populateFrom, currentArrayPlace));
  this.galleryData = data;
  this.fireEvent('onPopulated');
 },
 populateGallery: function(element, startNumber) {
  var data = [];
  options = this.options;
  currentArrayPlace = startNumber;
  element.getElements(options.elementSelector).each(function(el) {
   elementDict = {
    image: el.getElement(options.imageSelector).getProperty('src'),
    number: currentArrayPlace,
    transition: this.options.defaultTransition
   };
   elementDict.extend = $extend;
   if ((options.showInfopane) | (options.showCarousel))
    elementDict.extend({
     title: el.getElement(options.titleSelector).innerHTML,
     description: el.getElement(options.subtitleSelector).innerHTML
    });
   if (options.embedLinks)
    elementDict.extend({
     link: el.getElement(options.linkSelector).href||false,
     linkTitle: el.getElement(options.linkSelector).title||false,
     linkRel: el.getElement(options.linkSelector).getAttribute('rel')||false,
     linkTarget: el.getElement(options.linkSelector).getProperty('target')||false
    });
   if ((!options.useThumbGenerator) && (options.showCarousel))
    elementDict.extend({
     thumbnail: el.getElement(options.thumbnailSelector).getProperty('src')
    });
   else if (options.useThumbGenerator)
    elementDict.extend({
     thumbnail: options.thumbGenerator + '?imgfile=' + elementDict.image + '&max_width=' + options.thumbWidth + '&max_height=' + options.thumbHeight
    });

   data.extend([elementDict]);
   currentArrayPlace++;
   if (this.options.destroyAfterPopulate)
    el.remove();
  });
  return data;
 },
 constructElements: function() {
  el = this.galleryElement;
  this.maxIter = this.galleryData.length;
  var currentImg;
  for(i=0;i<this.galleryData.length;i++)
  {
   var currentImg = new Fx.Styles(
    new Element('div').addClass('slideElement').setStyles({
     'position':'absolute',
     'left':'0px',
     'right':'0px',
     'margin':'0px',
     'padding':'0px',
     'backgroundPosition':"center center",
     'opacity':'0'

    }).injectInside(el),
    'opacity',
    {duration: this.options.fadeDuration}
   );
   if (this.options.preloader)
   {
    currentImg.source = this.galleryData[i].image;
    currentImg.loaded = false;
    currentImg.load = function(imageStyle) {
     if (!imageStyle.loaded) {
      new Asset.image(imageStyle.source, {
                              'onload'  : function(img){
             img.element.setStyle(
             'backgroundImage',
             "url('" + img.source + "')")
             img.loaded = true;
            }.bind(this, imageStyle)
      });
     }
    }.pass(currentImg, this);
   } else {
    currentImg.element.setStyle('backgroundImage',
         "url('" + this.galleryData[i].image + "')");
   }
   this.galleryElements[parseInt(i)] = currentImg;
  }
 },
 destroySlideShow: function(element) {
  var myClassName = element.className;
  var newElement = new Element('div').addClass('myClassName');
  element.parentNode.replaceChild(newElement, element);
 },
 startSlideShow: function() {
  this.fireEvent('onStart');
  this.loadingElement.style.display = "none";
  this.lastIter = this.maxIter - 1;
  this.currentIter = 0;
  this.galleryInit = 0;
  this.galleryElements[parseInt(this.currentIter)].set({opacity: 1});
  if (this.options.showInfopane)
   this.showInfoSlideShow.delay(1000, this);
  var textShowCarousel = formatString(this.options.textShowCarousel, this.currentIter+1, this.maxIter);
  if (this.options.showCarousel&&(!this.options.carouselPreloader))
   this.carouselBtn.setHTML(textShowCarousel).setProperty('title', textShowCarousel);
  this.prepareTimer();
  if (this.options.embedLinks)
   this.makeLink(this.currentIter);
 },
 nextItem: function() {
  this.fireEvent('onNextCalled');
  this.nextIter = this.currentIter+1;
  if (this.nextIter >= this.maxIter)
   this.nextIter = 0;
  this.galleryInit = 0;
  this.goTo(this.nextIter);
 },
 prevItem: function() {
  this.fireEvent('onPreviousCalled');
  this.nextIter = this.currentIter-1;
  if (this.nextIter <= -1)
   this.nextIter = this.maxIter - 1;
  this.galleryInit = 0;
  this.goTo(this.nextIter);
 },
 goTo: function(num) {
  this.clearTimer();
  if(this.options.preloader)
  {
   this.galleryElements[num].load();
   if (num==0)
    this.galleryElements[this.maxIter - 1].load();
   else
    this.galleryElements[num - 1].load();
   if (num==(this.maxIter - 1))
    this.galleryElements[0].load();
   else
    this.galleryElements[num + 1].load();

  }
  if (this.options.embedLinks)
   this.clearLink();
  if (this.options.showInfopane)
  {
   this.slideInfoZone.clearChain();
   this.hideInfoSlideShow().chain(this.changeItem.pass(num, this));
  } else
   this.currentChangeDelay = this.changeItem.delay(500, this, num);
  if (this.options.embedLinks)
   this.makeLink(num);
  this.prepareTimer();
  /*if (this.options.showCarousel)
   this.clearThumbnailsHighlights();*/
 },
 changeItem: function(num) {
  this.fireEvent('onStartChanging');
  this.galleryInit = 0;
  if (this.currentIter != num)
  {
   for(i=0;i<this.maxIter;i++)
   {
    if ((i != this.currentIter)) this.galleryElements[i].set({opacity: 0});
   }
   gallery.Transitions[this.galleryData[num].transition].pass([
    this.galleryElements[this.currentIter],
    this.galleryElements[num],
    this.currentIter,
    num], this)();
   this.currentIter = num;
  }
  var textShowCarousel = formatString(this.options.textShowCarousel, num+1, this.maxIter);
  if (this.options.showCarousel)
   this.carouselBtn.setHTML(textShowCarousel).setProperty('title', textShowCarousel);
  this.doSlideShow.bind(this)();
  this.fireEvent('onChanged');
 },
 clearTimer: function() {
  if (this.options.timed)
   $clear(this.timer);
 },
 prepareTimer: function() {
  if (this.options.timed)
   this.timer = this.nextItem.delay(this.options.delay, this);
 },
 doSlideShow: function(position) {
  if (this.galleryInit == 1)
  {
   imgPreloader = new Image();
   imgPreloader.onload=function(){
    this.startSlideShow.delay(10, this);
   }.bind(this);
   imgPreloader.src = this.galleryData[0].image;
   if(this.options.preloader)
    this.galleryElements[0].load();
  } else {
   if (this.options.showInfopane)
   {
    if (this.options.showInfopane)
    {
     this.showInfoSlideShow.delay((500 + this.options.fadeDuration), this);
    } else
     if ((this.options.showCarousel)&&(this.options.activateCarouselScroller))
      this.centerCarouselOn(position);
   }
  }
 },
 createCarousel: function() {
  var carouselElement;
  if (!this.options.useExternalCarousel)
  {
   var carouselContainerElement = new Element('div').addClass('carouselContainer').injectInside(this.galleryElement);
   this.carouselContainer = new Fx.Styles(carouselContainerElement, {transition: Fx.Transitions.expoOut});
   this.carouselContainer.normalHeight = carouselContainerElement.offsetHeight;
   this.carouselContainer.set({'opacity': this.options.carouselMinimizedOpacity, 'top': (this.options.carouselMinimizedHeight - this.carouselContainer.normalHeight)});
   this.carouselBtn = new Element('a').addClass('carouselBtn').setProperties({
    title: this.options.textShowCarousel
   }).injectInside(carouselContainerElement);
   if(this.options.carouselPreloader)
    this.carouselBtn.setHTML(this.options.textPreloadingCarousel);
   else
    this.carouselBtn.setHTML(this.options.textShowCarousel);
   this.carouselBtn.addEvent(
    'click',
    function () {
     this.carouselContainer.clearTimer();
     this.toggleCarousel();
    }.bind(this)
   );
   this.carouselActive = false;

   carouselElement = new Element('div').addClass('carousel').injectInside(carouselContainerElement);
   this.carousel = new Fx.Styles(carouselElement);
  } else {
   carouselElement = $(this.options.carouselElement).addClass('jdExtCarousel');
  }
  this.carouselElement = new Fx.Styles(carouselElement, {transition: Fx.Transitions.expoOut});
  this.carouselElement.normalHeight = carouselElement.offsetHeight;
  if (this.options.showCarouselLabel)
   this.carouselLabel = new Element('p').addClass('label').injectInside(carouselElement);
  carouselWrapper = new Element('div').addClass('carouselWrapper').injectInside(carouselElement);
  this.carouselWrapper = new Fx.Styles(carouselWrapper, {transition: Fx.Transitions.expoOut});
  this.carouselWrapper.normalHeight = carouselWrapper.offsetHeight;
  this.carouselInner = new Element('div').addClass('carouselInner').injectInside(carouselWrapper);
  if (this.options.activateCarouselScroller)
  {
   this.carouselWrapper.scroller = new Scroller(carouselWrapper, {
    area: 100,
    velocity: 0.2
   })

   this.carouselWrapper.elementScroller = new Fx.Scroll(carouselWrapper, {
    duration: 400,
    onStart: this.carouselWrapper.scroller.stop.bind(this.carouselWrapper.scroller),
    onComplete: this.carouselWrapper.scroller.start.bind(this.carouselWrapper.scroller)
   });
  }
 },
 fillCarousel: function() {
  this.constructThumbnails();
  this.carouselInner.normalWidth = ((this.maxIter * (this.options.thumbWidth + this.options.thumbSpacing + 2))+this.options.thumbSpacing) + "px";
  this.carouselInner.style.width = this.carouselInner.normalWidth;
 },
 initCarousel: function () {
  this.createCarousel();
  this.fillCarousel();
  if (this.options.carouselPreloader)
   this.preloadThumbnails();
 },
 flushCarousel: function() {
  this.thumbnailElements.each(function(myFx) {
   myFx.element.remove();
   myFx = myFx.element = null;
  });
  this.thumbnailElements = [];
 },
 toggleCarousel: function() {
  if (this.carouselActive)
   this.hideCarousel();
  else
   this.showCarousel();

 },
 showCarousel: function () {
  this.fireEvent('onShowCarousel');
  this.carouselContainer.start({
   'opacity': this.options.carouselMaximizedOpacity,
   'top': 0
  }).chain(function() {
   this.carouselActive = true;
   this.carouselWrapper.scroller.start();
   this.fireEvent('onCarouselShown');
   this.carouselContainer.options.onComplete = null;
  }.bind(this));
 },
 hideCarousel: function () {
  this.fireEvent('onHideCarousel');
  var targetTop = this.options.carouselMinimizedHeight - this.carouselContainer.normalHeight;
  this.carouselContainer.start({
   'opacity': this.options.carouselMinimizedOpacity,
   'top': targetTop
  }).chain(function() {
   this.carouselActive = false;
   this.carouselWrapper.scroller.stop();
   this.fireEvent('onCarouselHidden');
   this.carouselContainer.options.onComplete = null;
  }.bind(this));
 },
 constructThumbnails: function () {
  element = this.carouselInner;
  for(i=0;i<this.galleryData.length;i++)
  {
   var currentImg = new Fx.Style(new Element ('div').addClass("thumbnail").setStyles({
     backgroundImage: "url('" + this.galleryData[i].thumbnail + "')",
     backgroundPosition: "center center",
     backgroundRepeat: 'no-repeat',
     marginLeft: this.options.thumbSpacing + "px",
     width: this.options.thumbWidth + "px",
     height: this.options.thumbHeight + "px"
    }).injectInside(element), "opacity", {duration: 200}).set(this.options.thumbIdleOpacity);
   currentImg.element.addEvents({
    'mouseover': function (myself) {
     myself.clearTimer();
     myself.start(0.99);
     if (this.options.showCarouselLabel)
      $(this.carouselLabel).setHTML('<span class="number">' + (myself.relatedImage.number + 1) + "/" + this.maxIter + ":</span> " + myself.relatedImage.title.slice(2));
    }.pass(currentImg, this),
    'mouseout': function (myself) {
     myself.clearTimer();
     myself.start(this.options.thumbIdleOpacity);
    }.pass(currentImg, this),
    'click': function (myself) {
     this.goTo(myself.relatedImage.number);
     if (this.options.thumbCloseCarousel)
      this.hideCarousel();
    }.pass(currentImg, this)

   });

   currentImg.relatedImage = this.galleryData[i];
   this.thumbnailElements[parseInt(i)] = currentImg;
  }
 },
 log: function(value) {
  if(console.log)
   console.log(value);
 },
 preloadThumbnails: function() {
  var thumbnails = [];
  for(i=0;i<this.galleryData.length;i++)
  {
   thumbnails[parseInt(i)] = this.galleryData[i].thumbnail;
  }
  this.thumbnailPreloader = new Preloader();
  this.thumbnailPreloader.addEvent('onComplete', function() {
   var textShowCarousel = formatString(this.options.textShowCarousel, this.currentIter+1, this.maxIter);
   this.carouselBtn.setHTML(textShowCarousel).setProperty('title', textShowCarousel);
  }.bind(this));
  this.thumbnailPreloader.load(thumbnails);
 },
 clearThumbnailsHighlights: function()
 {
  for(i=0;i<this.galleryData.length;i++)
  {
   this.thumbnailElements[i].clearTimer();
   this.thumbnailElements[i].start(0.2);
  }
 },
 changeThumbnailsSize: function(width, height)
 {
  for(i=0;i<this.galleryData.length;i++)
  {
   this.thumbnailElements[i].clearTimer();
   this.thumbnailElements[i].element.setStyles({
    'width': width + "px",
    'height': height + "px"
   });
  }
 },
 centerCarouselOn: function(num) {
  if (!this.carouselWallMode)
  {
   var carouselElement = this.thumbnailElements[num];
   var position = carouselElement.element.offsetLeft + (carouselElement.element.offsetWidth / 2);
   var carouselWidth = this.carouselWrapper.element.offsetWidth;
   var carouselInnerWidth = this.carouselInner.offsetWidth;
   var diffWidth = carouselWidth / 2;
   var scrollPos = position-diffWidth;
   this.carouselWrapper.elementScroller.scrollTo(scrollPos,0);
  }
 },
 initInfoSlideshow: function() {
  this.slideInfoZone = new Fx.Styles(new Element('div').addClass('slideInfoZone').injectInside($(this.galleryElement))).set({'opacity':0});
  var slideInfoZoneTitle = new Element('h2').injectInside(this.slideInfoZone.element);
  var slideInfoZoneDescription = new Element('p').injectInside(this.slideInfoZone.element);
  this.slideInfoZone.normalHeight = this.slideInfoZone.element.offsetHeight;
  this.slideInfoZone.element.setStyle('opacity',0);
 },
 changeInfoSlideShow: function()
 {
  this.hideInfoSlideShow.delay(10, this);
  this.showInfoSlideShow.delay(500, this);
 },
 showInfoSlideShow: function() {
  this.fireEvent('onShowInfopane');
  this.slideInfoZone.clearTimer();
  element = this.slideInfoZone.element;
  element.getElement('h2').setHTML(this.galleryData[this.currentIter].title.slice(2));
  element.getElement('p').setHTML(this.galleryData[this.currentIter].description);
  if(this.options.slideInfoZoneSlide)
   this.slideInfoZone.start({'opacity': [0, this.options.slideInfoZoneOpacity], 'height': [0, this.slideInfoZone.normalHeight]});
  else
   this.slideInfoZone.start({'opacity': [0, this.options.slideInfoZoneOpacity]});
  if (this.options.showCarousel)
   this.slideInfoZone.chain(this.centerCarouselOn.pass(this.currentIter, this));
  return this.slideInfoZone;
 },
 hideInfoSlideShow: function() {
  this.fireEvent('onHideInfopane');
  this.slideInfoZone.clearTimer();
  if(this.options.slideInfoZoneSlide)
   this.slideInfoZone.start({'opacity': 0, 'height': 0});
  else
   this.slideInfoZone.start({'opacity': 0});
  return this.slideInfoZone;
 },
 makeLink: function(num) {
  this.currentLink.setProperties({
   href: this.galleryData[num].link,
   title: this.galleryData[num].linkTitle,
   rel: this.galleryData[num].linkRel
  })
  if (!((this.options.embedLinks) && (!this.options.showArrows) && (!this.options.showCarousel)))
   this.currentLink.setStyle('display', 'block');
 },
 clearLink: function() {
  this.currentLink.setProperties({href: '', title: '', rel: ''});
  if (!((this.options.embedLinks) && (!this.options.showArrows) && (!this.options.showCarousel)))
   this.currentLink.setStyle('display', 'none');
 },
 /* To change the gallery data, those two functions : */
 flushGallery: function() {
  this.galleryElements.each(function(myFx) {
   myFx.element.remove();
   myFx = myFx.element = null;
  });
  this.galleryElements = [];
 },
 changeData: function(data) {
  this.galleryData = data;
  this.clearTimer();
  this.flushGallery();
  if (this.options.showCarousel) this.flushCarousel();
  this.constructElements();
  if (this.options.showCarousel) this.fillCarousel();
  if (this.options.showInfopane) this.hideInfoSlideShow();
  this.galleryInit=1;
  this.lastIter=0;
  this.currentIter=0;
  this.doSlideShow(1);
 },
 /* Plugins: HistoryManager */
 initHistory: function() {
  this.fireEvent('onHistoryInit');
  this.historyKey = this.galleryElement.id + '-picture';
  if (this.options.customHistoryKey)
   this.historyKey = this.options.customHistoryKey();
  this.history = HistoryManager.register(
   this.historyKey,
   [1],
   function(values) {
    if (parseInt(values[0])-1 < this.maxIter)
     this.goTo(parseInt(values[0])-1);
   }.bind(this),
   function(values) {
    return [this.historyKey, '(', values[0], ')'].join('');
   }.bind(this),
   this.historyKey + '\\((\\d+)\\)');
  this.addEvent('onChanged', function(){
   this.history.setValue(0, this.currentIter+1);
  }.bind(this));
  this.fireEvent('onHistoryInited');
 }
};
gallery = new Class(gallery);
gallery.implement(new Events);
gallery.implement(new Options);

gallery.Transitions = new Abstract ({
 fade: function(oldFx, newFx, oldPos, newPos){
  oldFx.options.transition = newFx.options.transition = Fx.Transitions.linear;
  oldFx.options.duration = newFx.options.duration = this.options.fadeDuration;
  if (newPos > oldPos) newFx.start({opacity: 1});
  else
  {
   newFx.set({opacity: 1});
   oldFx.start({opacity: 0});
  }
 },
 crossfade: function(oldFx, newFx, oldPos, newPos){
  oldFx.options.transition = newFx.options.transition = Fx.Transitions.linear;
  oldFx.options.duration = newFx.options.duration = this.options.fadeDuration;
  newFx.start({opacity: 1});
  oldFx.start({opacity: 0});
 },
 fadebg: function(oldFx, newFx, oldPos, newPos){
  oldFx.options.transition = newFx.options.transition = Fx.Transitions.linear;
  oldFx.options.duration = newFx.options.duration = this.options.fadeDuration / 2;
  oldFx.start({opacity: 0}).chain(newFx.start.pass([{opacity: 1}], newFx));
 }
});

/* All code copyright 2007 Jonathan Schemoul */

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 * Follows: Preloader (class)
 * Simple class for preloading images with support for progress reporting
 * Copyright 2007 Tomocchino.
 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

var Preloader = new Class({

  Implements: [Events, Options],

  options: {
    root        : '',
    period      : 100
  },

  initialize: function(options){
    this.setOptions(options);
  },

  load: function(sources) {
    this.index = 0;
    this.images = [];
    this.sources = this.temps = sources;
    this.total = this. sources.length;

    this.fireEvent('onStart', [this.index, this.total]);
    this.timer = this.progress.periodical(this.options.period, this);

    this.sources.each(function(source, index){
      this.images[index] = new Asset.image(this.options.root + source, {
        'onload'  : function(){ this.index++; if(this.images[index]) this.fireEvent('onLoad', [this.images[index], index, source]); }.bind(this),
        'onerror' : function(){ this.index++; this.fireEvent('onError', [this.images.splice(index, 1), index, source]); }.bind(this),
        'onabort' : function(){ this.index++; this.fireEvent('onError', [this.images.splice(index, 1), index, source]); }.bind(this)
      });
    }, this);
  },

  progress: function() {
    this.fireEvent('onProgress', [Math.min(this.index, this.total), this.total]);
    if(this.index >= this.total) this.complete();
  },

  complete: function(){
    $clear(this.timer);
    this.fireEvent('onComplete', [this.images]);
  },

  cancel: function(){
    $clear(this.timer);
  }

});

Preloader.implement(new Events, new Options);

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 * Follows: formatString (function)
 * Original name: Yahoo.Tools.printf
 * Copyright Yahoo.
 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

function formatString() {
 var num = arguments.length;
 var oStr = arguments[0];
 for (var i = 1; i < num; i++) {
  var pattern = "\\{" + (i-1) + "\\}";
  var re = new RegExp(pattern, "g");
  oStr = oStr.replace(re, arguments[i]);
 }
 return oStr;
}


