/*
mooVirtualPano - défilement panoramique à la souris
massacred by christopher wait aka virtualgadjo aka grizzly aka l'ôt fou

s'appuie sur mootools1.2 (ça fait au moins un truc qui marche...)

05/2008 - perte de cheveux

########## HOW TO ##########

--oo-- Options --oo--
- auto            : true par défaut : 
- inertie         : 20 par défaut : plus le chiffre est grand moins l'anim accélère quand la souris s'éloigne du centre,
                    utiliser un chiffre négatif pour inverser le sens de l'anim
                    ne pas utiliser 0 biscotte 0 divisé par 0 ça un petit air de la tête à toto
- tb (top bottom) : true par défaut, autorise le défilement automatique haut/bas de l'image en fonction de la position de la souris,
                    centre l'image verticalement dans le visualisateur
- loop            : true par défaut : boucle infinie, penser à soigner les bords de l'image...
- changePano      : vide par défaut : si l'option est renseignée, class appliquée à des liens permettant de changer l'image dans le visualiseur
syntaxe des liens : <a href="img/toto.jpg" rel="dim::800::300" class="ziClass">texte ou image</a>
                    le href doit contenir un lien pointant vers l'image à changer
                    le rel doit contenir un "prefixe" texte de votre choix suivi de largeur et hauteur de l'image séparées par ::
                    à cause des navigateurs non-systèmes (tous sauf ie en clair) qui récupèrent mal les dimensions d'images à la volée

--oo-- Méthodes --oo--
var ziPano = new mooVirtualPano ($('yourContainer'), $('yourPanoDiv'));

ziPano.toLeft(x);   fait défiler vers la gauche, prend un chiffre en argument, plus il est grand plus ça va vite...
ziPano.toRight(x);  fait défiler vers la droite, itou pour l'argument
ziPano.toBottom(x); fait défiler vers le bas, itou pour l'argument
ziPano.toTop(x);    fait défiler vers le haut, itou pour l'argument
ziPano.speedUp();   accélère le défilement
ziPano.speedDown(); ralentit le défilement
ziPano.stop();      arrête tout défilement
ziPano.reset();     arrête tout défilement et remet l'image dans sa position de départ
############################

Have swing
*/

var mooVirtualPano = new Class({

	Implements: [Events, Options],

	options: {
		auto        : true,
		inertie     : 60,
		tb          : true,
		loop        : true,
		changePano  : ''
	},

	initialize: function(container, pano, options){

		this.setOptions(options);
		this.container  = container;
		this.pano       = pano;

		this.changeLink = [];
		if (this.options.changePano != ''){
			$$('a').each(function(el){
				if (el.hasClass(this.options.changePano)) this.changeLink.push(el);
			}.bind(this));
			this.gallery();
		}
		else this.init();

		if (this.options.auto == true){
			this.mousePlay();
		}
	},

	init: function(){
		this.ziLeft     = this.container.getPosition().x;
		this.ziTop      = this.container.getPosition().y;
		this.ziWidth    = this.container.getCoordinates().width;
		this.ziHeight   = this.container.getCoordinates().height;
		this.ziRight    = this.ziLeft + this.ziWidth;
		this.ziBottom   = this.ziTop + this.ziHeight;
		this.ziCenter   = this.ziLeft + (this.ziWidth / 2);
		this.vCenter    = this.ziTop + (this.ziHeight / 2);
		this.imgWidth   = this.pano.getFirst().getSize().x;
		this.imgHeight  = this.pano.getFirst().getSize().y;
		this.initX      = (this.imgWidth - this.ziWidth) / 2;
		this.initY      = (this.imgHeight - this.ziHeight) / 2;
		this.imgMid     = (this.imgWidth * .5).round(0);
		this.move       = 0;
		this.tbMove     = 0;
		this.speed      = - 1 / this.options.inertie;

		if (this.options.loop == true){
			this.rightImg = this.pano.getFirst().clone();
			this.rightImg.inject(this.pano, 'bottom').setProperties({'height': this.imgHeight, 'width': this.imgWidth}); //à cause de cette caille d'ie...
			this.pano.setStyles({'left': '-' + this.initX + 'px', 'width': this.imgWidth * 2});
		}
		else {
			this.pano.setStyles({'left': '-' + this.initX + 'px', 'width': this.imgWidth});
		}
		if (this.options.tb == true){
			this.pano.setStyles({'top': '-' + this.initY + 'px'});
		}
	},

	mousePlay: function(){
		this.container.addEvents({
			'mouseenter'    : function(){
				if (this.options.loop == true) this.defil();
				else this.lrOnly();
				if (this.options.tb == true) this.tbDefil();
			}.bind(this),
			'mousemove'     : function(e){
				this.mouseX = e.client.x;
				this.mouseY = e.client.y;
				this.diff   = (this.mouseX - (this.ziLeft - window.getScroll().x)) - (this.ziWidth / 2);
				this.tbDiff = (this.mouseY -(this.ziTop - window.getScroll().y)) - (this.ziHeight / 2);
				this.move   = Math.round(this.diff * this.speed);
				this.tbMove = Math.round(this.tbDiff * (this.speed));
			}.bind(this),
			'mouseleave'    : function(){
				this.stop();
			}.bind(this)
		});
	},

	defil: function(){
		this.panoLeft = this.pano.getCoordinates(this.container).left;
		this.pano.setStyle('left', this.panoLeft + this.move);

		if (this.panoLeft >= - (this.imgWidth / 10)) {
			this.pano.setStyle('left', - (this.imgWidth + this.imgWidth / 10));
		}
		if (this.panoLeft <= (- (this.imgWidth + this.imgMid))) {
			this.pano.setStyle('left', - this.imgMid);
		}
		this.enRoute = this.defil.delay(15, this);
	},

	toLeft: function(ziSpeed){
		if (this.move >= 0){
			this.move = - ziSpeed;
			this.options.loop == true ? this.defil() : this.lrOnly();
		}
	},

	toRight: function(ziSpeed){
		if (this.move <= 0){
			this.move = ziSpeed;
			this.options.loop == true ? this.defil() : this.lrOnly();
		}
	},

	toTop: function(ziSpeed){
		if (this.tbMove >= 0){
			this.tbMove = - ziSpeed;
			this.tbDefil();
		}
	},

	toBottom: function(ziSpeed){
		if (this.move <= 0){
			this.tbMove = ziSpeed;
			this.tbDefil();
		}
	},

	speedUp: function(){
		if (this.move != 0){
			this.move > 0 ? this.move ++ : this.move -- ;
		}
	},

	speedDown: function(){
		if (this.move != 0){
			this.move > 0 ? this.move -- : this.move ++ ;
		}
	},

	stop: function(){
		this.move	= 0;
		this.tbMove	= 0;
		if (this.enRoute) $clear(this.enRoute);
		if (this.tbEnRoute) $clear(this.tbEnRoute);
	},

	reset: function(){
		this.stop();
		this.pano.setStyle('left', '-' + this.initX + 'px');
		if (this.options.tb == true) this.pano.setStyles({'top': '-' + this.initY + 'px'});
	},

	lrOnly: function(){
		this.panoLeft = this.pano.getCoordinates(this.container).left;
		if( (this.panoLeft < - this.move) && (this.move > 0) ){
			this.pano.setStyle('left', this.panoLeft + this.move);
		}
		if( (this.panoLeft > (this.ziWidth - this.imgWidth - this.move) ) && (this.move < 0) ){
			this.pano.setStyle('left', this.panoLeft + this.move);
		}
		this.enRoute = this.lrOnly.delay(15, this);
	},

	tbDefil: function(){
		this.panoTop = this.pano.getCoordinates(this.container).top;
		if( (this.panoTop < - this.tbMove) && (this.tbMove > 0) ){
			this.pano.setStyle('top', this.panoTop + this.tbMove);
		}
		if( (this.panoTop > (this.ziHeight - this.imgHeight - this.tbMove) ) && (this.tbMove < 0) ){
			this.pano.setStyle('top', this.panoTop + this.tbMove);
		}
		this.tbEnRoute = this.tbDefil.delay(15, this);
	},

	gallery: function(){
		this.feedPano(this.changeLink[0]);
		this.changeLink.each(function(el){
			el.addEvent('click', function(e){
				e.stop();
				this.feedPano(el);
			}.bind(this));
		}.bind(this));
	},

	feedPano: function(el){
		this.newImg       = el.getProperty('href');
		this.newImgWidth  = el.getProperty('rel').split('::')[1];
		this.newImgHeight = el.getProperty('rel').split('::')[2];

		this.newPano = new Element('img',{
			'src'     : this.newImg,
			'width'   : this.newImgWidth,
			'height'  : this.newImgHeight
		});

		this.pano.empty();
		this.newPano.inject(this.pano);
		this.init();
	}
});