/* manager des photos */

var khatim = {};
khatim.PhotoManager = new Class({
	Implements : [Options, Events],
	options : {
		root : null, //related to this.root
		menu : 'menu', //id of the menu (ou reference qui peut etre passée en parametre dans l'objet d'options)
		buttonsOpacity : 0.2,
		playPauseButtonOpacity : 0.4
	},
	
	photos : [],
	currentPhoto : null, //photo en cours
	root : null, //root node, container of all photos
	_fxScroll : null, //effet de scroll vers un image
	menu : null, //reference sur l'objet menu
	diapoTimer : null, //timer faisant referance au interval
	diapoInterval : 3000, //temps entre chaque photo
	playing : false, //booleen pour donner l'etat de lecture du diaporama
	leftButton:null,
	rightButton:null,
	playPauseButton:null,
	
	
	initialize : function(options) {
		this.setOptions(options);
		this.root = $(this.options.root);
		this.photos = this.root.getChildren('li');
		this.photos.each(function(photo, index){
			photo.photoObject = new khatim.Photo({root:photo, index:index});
			var a = photo.getElement('a');
			a.href='javascript:void(0);'; //for debug
			a.addEvent('click', this._photoClickHandler.bindWithEvent(this, [photo]));
		}.bind(this))
		this._initMenu();
		this._createButtons();
		this.scrollTo(this.photos[0]);
	},
	
	_photoClickHandler : function(e, photo) {
		new Event(e).stop();
		this.scrollTo(photo, true);
	},
	
	scrollTo : function(photo, userAction) {
		if (userAction) this.stopDiapo();
		if (this.currentPhoto) {
			if (this.currentPhoto==photo)
				return;
			this.currentPhoto.photoObject.unHighLight();
		}
		var p = $('page');
		if (this._fxScroll) this._fxScroll.cancel();
		this._fxScroll = new Fx.Scroll(p,{
			fps:50,
			duration:500,
			onComplete:function() {
				photo.photoObject.highLight();
				this.currentPhoto = photo;
			}.bind(this)
		});
	//	alert(document.documentElement.clientWidth);
		var xToScroll = parseInt(photo.getPosition(p).x - (document.documentElement.clientWidth-photo.offsetWidth)/2);
		this._fxScroll.start(xToScroll, 0);
	},
	
	scrollToId : function(id) {
		var photo = $(id);
		this.scrollTo(photo);
	},
	
	//menu functions
	_initMenu : function() {
		//this.menu = $(this.options.menu);
	/*	
		var links = this.menu.getElements('a');
		links.each(function(link) {
			link.addEvent('click', this._linkClickHandler.bindWithEvent(this, [link]));
		}.bind(this));
	*/
	},
	
	/* // fonction créée au départ pour gérer les ancres avec des id dans le menu
	_linkClickHandler : function(event, link) {
		new Event(event).stop();
		var href = link.href+'';
		var id = href.substring(href.lastIndexOf('#')+1, href.length);
		this.scrollToId(id);
	},
	*/
	
	//create Button
	_createButtons : function() {
		this.leftButton = new Element('a', {
			'id' : 'diapoLeftButton',
			'events' : {
				'click' : this._leftButtonClickHandler.bindWithEvent(this),
				'mouseenter' : this._buttonMouseEnter.bindWithEvent(this),
				'mouseleave' : this._buttonMouseLeave.bindWithEvent(this)
			},
			styles : {
				'opacity': this.options.buttonsOpacity
			}
		});
		this.rightButton = new Element('a', {
			'id' : 'diapoRightButton',
			'events' : {
				'click' : this._rightButtonClickHandler.bindWithEvent(this),
				'mouseenter' : this._buttonMouseEnter.bindWithEvent(this),
				'mouseleave' : this._buttonMouseLeave.bindWithEvent(this)
			},
			styles : {
				'opacity': this.options.buttonsOpacity
			}
			
		});
		this.playPauseButton = new Element('a', {
			'id' : 'diapoPlayPauseButton',
			'events' : {
				'click' : this._playPauseButtonClickHandler.bindWithEvent(this),
				'mouseenter' : this._buttonMouseEnter.bindWithEvent(this),
				'mouseleave' : this._buttonPlayPauseMouseLeave.bindWithEvent(this)
			},
			styles : {
				'opacity': this.options.playPauseButtonOpacity
			}
		});
		[this.leftButton, this.rightButton, this.playPauseButton].each(function(button){
			button.opFx = new Fx.Tween(button, {
				duration:500,
				fps:20
			});
			document.body.appendChild(button);
		});
	},
	
	_leftButtonClickHandler : function(e) {
		new Event(e).stop();
		this.previousPhoto();
	},
	_rightButtonClickHandler : function(e) {
		new Event(e).stop();
		this.nextPhoto();
	},
	_playPauseButtonClickHandler : function(e) {
		new Event(e).stop();
		this.toggleDiapo();
	},
	_buttonMouseEnter : function(e) {
		var target = new Event(e).target;
		target.opFx.cancel();
		target.opFx.start('opacity', $(target).getOpacity(), 1);
	},
	_buttonMouseLeave : function(e) {
		var target = new Event(e).target;
		target.opFx.cancel();
		target.opFx.start('opacity', $(target).getOpacity(), this.options.buttonsOpacity);
	},
	_buttonPlayPauseMouseLeave : function(e) {
		var target = new Event(e).target;
		target.opFx.cancel();
		target.opFx.start('opacity', $(target).getOpacity(), this.options.playPauseButtonOpacity);
	},
	
	
	nextPhoto : function(diapoAction) {
		if (!diapoAction) this.stopDiapo();
		var nextPhoto = this.photos[this.currentPhoto.photoObject.index+1];
		if (nextPhoto!=null) this.scrollTo(nextPhoto);
	},
	previousPhoto: function(diapoAction) {
		if (!diapoAction) this.stopDiapo();
		var previousPhoto = this.photos[this.currentPhoto.photoObject.index-1];
		if (previousPhoto!=null) this.scrollTo(previousPhoto);
	},
	toggleDiapo : function() {
		if (this.playing) {
			this.stopDiapo();
		} else {
			this.startDiapo();
		}
	},
	startDiapo : function() {
		//this.stopDiapo();
		this.nextPhoto(true);
		this.playPauseButton.addClass('diapoPauseButton');
		this.playing = true;
		this.diapoTimer = setInterval(this.diapoTimerHandler.bind(this), this.diapoInterval);
	},
	stopDiapo : function() {
		this.playing = false;
		this.playPauseButton.removeClass('diapoPauseButton');
		if (this.diapoTimer) clearInterval(this.diapoTimer);
	},
	diapoTimerHandler : function() {
		this.nextPhoto(true);
	}
	

});


/**
*		
**/
khatim.Photo = new Class({
	Implements : Options,
	options : {
		root : null, //related to this.root
		defaultOpacity : 0.2,
		index:null // related to this.index
	},
	
	root : null, //the photo root node. <li>...</li>
	photo : null, //the link of the photo <a href="#" class="photo"><img src="photo.jpg" /></a>
	description : null, //the container of photo description (actually a div)
	index : 0, //numero de la photo dans la liste
	// effects
	fxPhoto : null, //effect on the entire photoContainer
	
	initialize : function(options) {
		this.setOptions(options);
		this.root = $(this.options.root);
		this.index = this.options.index;
		this.photo = this.root.getElement('.photo');
		this.description = this.root.getElement('.desc');
		this._initListeners();
		this._initEffects();
		this._tooltip = new khatim.PhotoToolTip({
			text : this.description.innerHTML,
			element:this.root
		});
	},
	
	// private methods 
	_initListeners : function() {
		this.root.addEvent('mouseenter',this._mouseEnterHandler.bind(this));
		this.root.addEvent('mouseleave',this._mouseLeaveHandler.bind(this));
	},
	_initEffects : function() {
		this.fxPhoto = new Fx.Tween(this.photo, {
			duration:400,
			fps:15
		});
		this.photo.setOpacity(this.options.defaultOpacity);
	},
	
	// listeners
	_mouseEnterHandler : function(event) {
		//this.highLight();
	},
	_mouseLeaveHandler : function(event) {
		//this.unHighLight();
	},
	
	// public methods
	highLight : function() {
		this.fxPhoto.cancel();
		this.fxPhoto.start('opacity', this.photo.getOpacity(), 1);
	},
	unHighLight : function() {
		this.fxPhoto.cancel();
		this.fxPhoto.start('opacity', this.photo.getOpacity(), this.options.defaultOpacity);
	}
})

khatim.PhotoToolTip = new Class({
	Implements : [Options],
	
	options : {
		//template : 	'', //code HTML qui pourra representer le template à l].join('');
		element : null, // HTMLElement sur lequel les evenements souris sont faits
		text : '', //texte qui est mis dans le tooltip, peut être du HTML
		className : 'photoTooltip',
		maxWidth:300
	},
	
	element : null, //element sur lequel se fait le rollover
	tip : null, //element HTML qiu représente le tooltip,
	
	initialize : function(options) {
		this.setOptions(options);
		this.element = $(this.options.element);
		if (this.options.text.trim()=='')
			return;
		this.tip = new Element('div', {
			'class' : this.options.className
		});
		this.tip.innerHTML = this.options.text;
		this._initListeners();
	},
	
	_initListeners : function() {
		this.element.addEvent('mouseenter', this._elementMouseEnterHandler.bind(this));
		this.element.addEvent('mouseleave', this._elementMouseLeaveHandler.bind(this));
		this.element.addEvent('mousemove', this._elementMouseMoveHandler.bind(this));
	},
	
	// listeners
	_elementMouseEnterHandler : function(e) {
		this.show();
	},
	_elementMouseLeaveHandler : function(e) {
		this.hide();
	},
	_elementMouseMoveHandler : function(e) {
		this._setSize();
		this._setPosition(e);
	},
	
	//private
	_setPosition : function(e) {
		var e = new Event(e);
		var mx = e.page.x;
		var my = e.page.y;
		
		this.tip.setStyles({
		    top : my + 10,
			left: mx + 10
		});
	},
	
	_setSize : function() {
		if (!this.sized) {
			if (this.tip.offsetWidth>this.options.maxWidth)
				this.tip.setStyle('width', this.options.maxWidth);
			else 
				this.tip.setStyle('width', this.tip.offsetWidth);
			this.sized = true;
		}
	},
	
	//public
	show : function() {
		document.body.appendChild(this.tip);
	},
	
	hide : function() {
		this.tip.dispose();
	},
	
	updateText : function(text) {
		this.options.text = text;
	}
});

khatim.LayoutManager = new Class({
	Implements : Options,
	options : {
		photos : 'photos', //related to this.photos
		footer : 'footer', //related to footer
		checkInterval : 50, //interval en ms pour redimensionner automatiquement le layout
		maxPhotosHeight : 470,
	},
	
	photos : null, // conteneur des photos
	footer : null, //footer
	lastViewHeight : 0, //derniere height enregistree
	layoutTimer : null, //timer reference au setInterval
	lis : [], //liste des LI (conteneurs des photos)
	imgs : [], //liste des tags IMG
	
	initialize:function(options) {
		this.setOptions(options);
		this.photos = $(this.options.photos);
		this.photosTop = this.photos.offsetTop;
		this.footer = $(this.options.footer);
		
		this.lis = this.photos.getElements('li');
		this.imgs = this.photos.getElements('a.photo img');
		this.imgs.each(function(img, index){
			$(img).addEvent('load', this._photoLoadHandler.bindWithEvent(this, [this.lis[index], img]));
		}.bind(this));
		setTimeout(function(){
			this.layoutTimer = setInterval(this.updateLayout.bind(this), this.options.checkInterval);
		}.bind(this),150)
	},
	
	updateLayout : function() {
		var viewHeight = document.documentElement.clientHeight;
		var photosTop = this.photosTop;
		if (viewHeight!=this.lastViewHeight) {
			var newHeight = (this.footer.offsetTop - this.photos.offsetTop-70);
			if (newHeight>this.options.maxPhotosHeight) {
				photosTop = (newHeight-this.options.maxPhotosHeight)/2+photosTop;
				newHeight = this.options.maxPhotosHeight;
			}
			this.photos.style.top = photosTop + 'px';
			this.photos.style.height = newHeight + 'px';
			this.lastViewHeight = viewHeight;
			this.refreshLIWidth();
		}
	},
	
	_photoLoadHandler : function(e, li, photo) {
		li.style.width = photo.offsetWidth + 'px'
	},
	
	refreshLIWidth : function() {
		this.lis.each(function(li, index) {
			li.style.width = this.imgs[index].offsetWidth + 'px'
		}.bind(this));
	}
})
