/*
    This file is part of JonDesign's SmoothGallery v1.0.1.

    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 2 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.
	Many thanks to:
	- The mootools team for the great mootools lib, and it's help and support throughout the project.
*/


var $removeEvents = function (object, type)
{
	if (!object.events) return object;
	if (type){
		if (!object.events[type]) return object;
		for (var fn in object.events[type]) object.removeEvent(type, fn);
		object.events[type] = null;
	} else {
		for (var evType in object.events) object.removeEvents(evType);
		object.events = null;
	}
	return object;
};
		
		
// declaring the class
var gallery = new Class({
	initialize: function(element, options) {
		this.setOptions({
			showArrows: true,
			showInfopane: false,
			embedLinks: true,
			fadeDuration: 350,
			slideDuration: 650,
			timed: true,
			delay: 6000,
			preloader: true,
			manualData: [],
			populateData: true,
			topBarSelector: "div#topBar",
			elementSelector: "div.imageElement",
			titleSelector: "h3",
			subtitleSelector: "p",  
			linkSelector: "a.open",
			imageSelector: "img.full",
			slideInfoZoneOpacity: 0.7,
			destroyAfterPopulate: true,
			baseClass: 'jdGallery',
			withArrowsClass: 'withArrows'  
		}, 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.galleryElement.addClass(this.options.baseClass);
		if (this.options.populateData)
			this.populateData();
		element.style.display="block";
		
		if (this.options.embedLinks)
		{
			this.currentLink = new Element('a').addClass('open').setProperties({
				href: '#',
				title: ''
			}).injectInside(element);
				this.currentLink.setStyle('display', 'block');
			if(this.showInfopane){
				this.currentLink.addEvent('mouseenter', function(){  //highlight the subtext
					$('imageLink').setStyle('text-decoration', 'underline');
				});
				this.currentLink.addEvent('mouseleave', function(){  //highlight the subtext
					$('imageLink').setStyle('text-decoration', 'none');
				});
			}
		
			// $$(this.options.linkSelector).addEvent('mouseenter', function(){  //highlight the subtext
			// 			$('imageLink').setStyle('text-decoration', 'underline');
			// 		});
			// 		$$(this.options.linkSelector).addEvent('mouseleave', function(){  //highlight the subtext
			// 			$('imageLink').setStyle('text-decoration', 'none');
			// 		});
		}
		
		// if (!this.options.embedLinks && this.options.timed){
		// 		this.currentLink = new Element('a').addClass('open').setProperties({
		// 			href: '#',
		// 			title: 'Pause',
		// 			id : 'aPauseResume'
		// 		}).injectInside(element);
		// 		this.currentLink.addEvent('click', function(){  //highlight the subtext
		// 			
		// 			if ($('aPauseResume').getProperty('title') == "Pause"){
		// 				myGallery.options.timed = false;
		// 				myGallery.clearTimer();
		// 				$('aPauseResume').setProperty('title',"Resume");
		// 			} else {
		// 				myGallery.options.timed = true;
		// 				myGallery.prepareTimer();
		// 				$('aPauseResume').setProperty('title',"Pause");
		// 				myGallery.nextItem();
		// 			}
		// 			
		// 			
		// 		});
		// 	}
		
		this.backToBegin = new Element('a',{
			href: '#',
			title: 'close',
			'class': 'backToBegin',
			id : 'backToBegin',
			'events': {
		        'click': function(){
						myGallery.options.timed = false;
						myGallery.clearTimer();
						myGallery.goTo(0);
						//console.log("fired click");
					}
		        }
		}).setText('close').injectInside($E(this.options.topBarSelector));
		

		this.backToBegin.fader = new Fx.Style(this.backToBegin, 'opacity', {'duration': this.options.fadeDuration*2}).set(0); //will make it immediately transparent

		this.constructElements();
		if ((data.length>1)&&(this.options.showArrows)){
			var leftArrow = new Element('a',{'title': 'Previous Image'}).addClass('left').addEvent(
				'click',
				this.prevItem.bind(this)
			).addEvent(
				'mouseenter',  //to deal with IE's crappy hover events
				function(){
					if (window.ie){
						this.addClass('leftIE');
					}
				}
			).addEvent(
				'mouseleave',
				function(){
					if (window.ie){
						this.removeClass('leftIE');
					}
				}
			).injectInside(element);
			var rightArrow = new Element('a',{'title': 'Next Image'}).addClass('right').addEvent(
				'click',
				this.nextItem.bind(this)
			).addEvent(
					'mouseenter',  //to deal with IE's crappy hover events
					function(){
						if (window.ie){
							this.addClass('rightIE');
						}
					}
				).addEvent(
					'mouseleave',
					function(){
						if (window.ie){
							this.removeClass('rightIE');
						}
					}
				).injectInside(element);
			this.galleryElement.addClass(this.options.withArrowsClass);
		}
		this.loadingElement = new Element('div').addClass('loadingElement').injectInside(element);
		if (this.options.showInfopane) this.initInfoSlideshow();
		this.doSlideShow(1);
	},
	populateData: function() {
		currentArrayPlace = this.galleryData.length;
		options = this.options;
		data = this.galleryData;
		this.galleryElement.getElements(options.elementSelector).each(function(el) {
			elementDict = {
				image: el.getElement(options.imageSelector).getProperty('src'),	
				width: el.getElement(options.imageSelector).getProperty('width'),
				height: el.getElement(options.imageSelector).getProperty('height'),		
				number: currentArrayPlace
			};
			//if ((options.showInfopane) | (options.showCarousel))
				Object.extend(elementDict, {
					title: el.getElement(options.titleSelector).innerHTML,
					description: el.getElement(options.subtitleSelector).innerHTML
				});
			//console.log(el.getElements(options.linkSelector).getProperty('href'));
			
			if (options.embedLinks)
				Object.extend(elementDict, {
				 	link: el.getElements(options.linkSelector).getProperty('href')||false,
				 	linkTitle: el.getElements(options.linkSelector).getProperty('title')||false
				});
			
			data[currentArrayPlace] = elementDict;
			currentArrayPlace++;
			if (this.options.destroyAfterPopulate)
				el.remove();
		});
		this.galleryData = data;
		this.fireEvent('onPopulated');
	},
	constructElements: function() {
		el = this.galleryElement;
		this.maxIter = this.galleryData.length;
		var currentImg;
		for(i=0;i<this.galleryData.length;i++)
		{
			var currentImg = new Fx.Style(
				new Element('div').addClass('slideElement').setStyles({
					'position':'absolute',
					'left':'0px',
					'right':'0px',
					'margin':'0px',
					'padding':'0px',
					'backgroundImage':"url('" + this.galleryData[i].image + "')",
					'backgroundPosition':"top right",
					'opacity':'0'
					}).setProperty('title',this.galleryData[i].title).injectInside(el),
				'opacity',
				{duration: this.options.fadeDuration}
			);
			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(1);
		if (this.options.showInfopane)
			this.showInfoSlideShow.delay(0, this);
		if (this.options.timed)
			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.embedLinks)
			this.clearLink();
		this.changeItem.delay(500, this, num);
		if (this.options.embedLinks)
			this.makeLink(num);
		this.prepareTimer();
	//	console.log(num);
	},
	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(0);
				
			}
			if (num > this.currentIter) this.galleryElements[num].custom(1);
			else
			{
				this.galleryElements[num].set(1);
				this.galleryElements[this.currentIter].custom(0);
			}
			this.currentIter = num;
		}
		this.doSlideShow.bind(this)();
		this.fireEvent('onChanged');

		//have to add a new image element to the document (not visible) to be able to get it's size
		//console.log(this.galleryData[num]);
		
		if (this.galleryData[num].height && !this.galleryData[num].width){
			var tImg = new Element('img', { 'src': this.galleryData[num].image}).setProperty('id', 'tImg').setStyles('position:absolute;left:-9000px').injectInside(document.body);
			tImgY = tImg.getSize().size.y;
			tImgX = tImg.getSize().size.x;
		} else {
			tImgX = this.galleryData[num].width;
			tImgY = this.galleryData[num].height;
			tImg = '';
		}
		//console.log(tImg.getSize().size);
		var sizeEffects = new Fx.Styles('myGallery', {duration: this.options.slideDuration, transition: Fx.Transitions.linear});
		
		if (this.options.showInfopane)
			var infoMove = new Fx.Styles('infoBar', {duration: this.options.slideDuration, transition: Fx.Transitions.linear});

		
		//fallback sizes if we can't get any
		if (tImgX == 0 ){
			tImgX = 810;
		}
		if (tImgY == 0 ){
			tImgY = 270;
		}
		
		sizeEffects.start({
		    'height': tImgY,
		    'width': tImgX
		}); 
		
		
		// if (tImgY > 270 && tImgX == 810){
		// 	if (this.options.showInfopane){
		// 		infoMove.start({'top': 34 + tImgY });
		// 	}
		// 	new Fx.Style('navParent', 'opacity', {duration: this.options.fadeDuration}).start(0);
		// } else if (tImgY <= 270) {
		// 	if (this.options.showInfopane){
		// 		infoMove.start({
		// 			'top': 34 + tImgY
		// 		});
		// 	}
		// 
		// 	new Fx.Style('navParent', 'opacity', {duration: this.options.fadeDuration}).start(1);
		// }

		
		if (tImgY > 270){  //fades the descriptive text if the image is a tall one and covers text
			new Fx.Style('entry', 'opacity', {duration: this.options.fadeDuration}).start(0);
			new Fx.Style('navParent', 'opacity', {duration: this.options.fadeDuration}).start(0);
			
			
			this.backToBegin.fader.start(1);
			
			//code for the return arrow fade in here
			//this.backToBegin.injectInside('myGallery');
			// var backToBeginFade = new Fx.Style(backToBegin, 'opacity', {duration: this.options.fadeDuration});
			// 			backToBeginFade.start(0,1);
		} 
		if (tImgY <= 270){
			new Fx.Style('entry', 'opacity', {duration: this.options.fadeDuration}).start(1);
			new Fx.Style('navParent', 'opacity', {duration: this.options.fadeDuration}).start(1); 
			
			this.backToBegin.fader.start(0);
			
			//code for the return arrow fade out here
			// if (backToBeginFade)
			// 				backToBeginFade.start(1,0);
			//this.backToBegin.setStyle("display","none");
			
		}
		try  {
		  tImg.remove();  //take our size temp Image out of the DOM
	 	}
		catch(err)  {
		  //Handle errors here
		}
		
		
	},
	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;
		} else {
			if (this.options.showInfopane) {
				this.showInfoSlideShow.delay((0 + this.options.fadeDuration), this); 
			}
		}
	},
	



	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(0, this);
		//this.showInfoSlideShow.delay(0, this);
	},
	showInfoSlideShow: function() {
		this.fireEvent('onShowInfopane');
		mel = $('imageLink');
		newHTML = this.galleryData[this.currentIter].title + " &nbsp;<span class='imageSubDesc'>"+this.galleryData[this.currentIter].description+"</span>";
		mel.setHTML(newHTML);
		
//		console.log('this.currentIter:');
//		console.log(this.galleryData[this.currentIter]);
		mel.setProperties({
			href: this.galleryData[this.currentIter].link,
			title: this.galleryData[this.currentIter].title
		});
		
		this.updateNumberJump();
		
	},
	hideInfoSlideShow: function() {
		this.fireEvent('onHideInfopane');
		return this.slideInfoZone;
	},
	makeLink: function(num) {
		//console.log(this.galleryData[num]);
		this.currentLink.setProperties({
			href: this.galleryData[num].link,
			title: this.galleryData[num].linkTitle
		})

	},
	clearLink: function() {
		this.currentLink.setProperties({href: '', title: ''});

	},
	updateNumberJump: function(){
		var imEl = $('imageCount');
	//	console.log(imEl);
		imEl.empty();
	//	console.log(imEl);
		//console.log(this.currentIter);
		
		newEle = '';
		for (var i = 0; i < this.maxIter; i++){
			if (i == this.currentIter){
				newEle += "<a href='#' class='currentItem'>"+(i+1)+"</a>";
			} else {
				newEle += "<a href='#' class='itemJump' onclick='myGallery.goTo("+i+");'>"+(i+1)+"</a>";
			}
		imEl.setHTML(newEle);
		}  
	}
});
gallery.implement(new Events);
gallery.implement(new Options);

/* All code copyright 2006 Jonathan Schemoul */