/*
                     __                      ___                           __                    
         __         /\ \__                  /\_ \                         /\ \     __            
 __  __ /\_\   _ __ \ \ ,_\  __  __     __  \//\ \       __       __      \_\ \   /\_\     ___   
/\ \/\ \\/\ \ /\`'__\\ \ \/ /\ \/\ \  /'__`\  \ \ \    /'_ `\   /'__`\    /'_` \  \/\ \   / __`\ 
\ \ \_/ |\ \ \\ \ \/  \ \ \_\ \ \_\ \/\ \L\.\_ \_\ \_ /\ \L\ \ /\ \L\.\_ /\ \L\ \  \ \ \ /\ \L\ \
 \ \___/  \ \_\\ \_\   \ \__\\ \____/\ \__/.\_\/\____\\ \____ \\ \__/.\_\\ \___,_\ _\ \ \\ \____/
  \/__/    \/_/ \/_/    \/__/ \/___/  \/__/\/_/\/____/ \/___L\ \\/__/\/_/ \/__,_ //\ \_\ \\/___/ 
                                                         /\____/                  \ \____/       
                                                         \_/__/                    \/___/        

massacred by christopher wait aka virtualgadjo aka grizzly aka l'Ă´t fou

s'appuie sur mootools (c'te blague...)

05/2008 - un tonneau de single malt plus loin, j'y suis presque !
08/2008 - ajoĂťt de l'option reset pour faire plus propre... :) + petites amĂŠliorations de perf Ă  droite Ă  gauche
04/2010 - l'initialisation des coordonnĂŠes passe dans une mĂŠthode pour pouvoir la relancer en cas de rezise de la page
10/2010 - tourne avec mootools 1.3 sans layer de compatibilitĂŠ
04/2011 - ajoĂťt des callbacks sur l'entrĂŠe et la sortie du container principal, Ă§a ne sert Ă  rien mais il n'y a pas de raison
          pour que je ne le fasse qu'avec cette daube de jQuery
        - joue avec la taille de la typo
        - possibilitĂŠ de centrer verticalement un mot/une ligne (achtung pas de retour Ă  la ligne ce serait vilain... dans les ĂŠlĂŠments tournants)
        - ajoĂťt de l'option slowdown Ă  l'arrĂŞt du menu, nice isn't it ?
        - ajoĂťt de l'option permettant de dĂŠmarrer avec un radius plutĂ´t qu'Ă  plat

########## HOW TO ##########
oo -- les Options -- oo
- maxWidth         : la largeur maxi que prennent les ĂŠlĂŠments
- maxHeight        : devinez...
- topZ             : le z-index de l'ĂŠlĂŠment du dessus (utile Ă  pas mal de titre, entre autres si vous avez des fenĂŞtre modales histoire)
- hPad, vPad       : attention, dĂŠlicat, pseudo padding horizontal (hPad) et vertical (vPad).
                     Plus vos ĂŠlĂŠments sont larges et haut par rapport Ă  la taille du conteneur d'origine, plus le chiffre doit ĂŞtre grand
                     pour ne pas qu'ils dĂŠpassent des bords du conteneur. Un ĂŠlĂŠment de placement important
- inertie          : plus le nombre est grand moins forte est l'accelĂŠration quand on s'ĂŠloigne du centre
- opacity          : bon, ben Ă§a, inutile de vous faire un dessin... concerne les ĂŠlĂŠments oeuf corse
- fontMax          : la taille maxi que la typo peut prendre
- vCenter          : sur true, aligne le texte verticalement en hauteur
- reset            : true       : le menu revient Ă  sa position initiale quand la souris sort de la zone active
                     false      : le menu reste exactement ou il est au moment oĂš l'on en sort
                     'slowdown' : achtung, chaĂŽne (string) ouh c'est y pas mimi, il ralentit tranquillement jusqu'Ă  l'arrĂŞt en conservant son radius, si, si
- onStart, onLeave : functions, callbacks sur l'entrĂŠe et la sortie du container gĂŠnĂŠral
- initRad          : false : dĂŠmarre Ă  plat
                     number: dĂŠmarre avec un radius, faites des essais en fonction du nombre d'ĂŠlements, de leur taille et de la place dans le container
                     mais c'est intĂŠressant entre 120 et 180/200 en-deĂ§a on voit pas trop le radius, au-delĂ  c'est trĂ¨s ouvert et moyennement beau, up to you
############################

Have swing
*/

var mooVRotatingMenu = new Class ({

	Implements: [Options, Events],

	options: {
		maxWidth    : 200,
		maxHeight   : 100,
		topZ        : 500,
		mode        : 'horizontal',
		hPad        : 1.6,
		vPad        : 2,
		inertie     : 30,
		opacity     : 1,
		fontMax     : 40,
		vCenter     : true, //true, false
		reset       : 'slowdown', //true/false/'slowdown'
		onStart     : function(){},
		onLeave     : function(){},
		initRad     : 120 //false ou un nombre entre 120 et 180/200
	},

	initialize: function(container, elems, options){

		this.setOptions(options);
		this.container  = container;
		this.getCoord();
		this.elems      = elems;
		this.num        = this.elems.length;
		this.move       = 0;
		this.tbMove     = 0; //top bottom move
		this.speed      = - 1 / this.options.inertie;
		this.deg        = [];
		this.diff       = this.options.initRad == false ? 0 : - this.options.initRad;
		this.tbDiff     = this.options.initRad == false ? 0 : - this.options.initRad;

		this.firstPlace();

		this.container.addEvents({
			'mouseenter'    : function(){
				if (this.enRoute) clearTimeout(this.enRoute);
				if (this.slowdown) clearTimeout(this.slowdown);
				this.moveAll();
				this.fireEvent('onStart');
			}.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.ch);
				this.tbDiff = (this.mouseY - (this.ziTop - window.getScroll().y)) - (this.cv);
				this.move   = this.diff * this.speed;
				this.tbMove = this.tbDiff * this.speed;
				//console.log (this.ziTop +' '+ window.getScroll().y+' '+this.tbDiff);
			}.bind(this),
			'mouseleave'    : function(){
				if (this.options.reset == 'slowdown') this.unspeed();
				else
				{
					this.move   = 0;
					this.tbMove = 0;
					clearTimeout(this.enRoute);
					if (this.options.reset == true) {
						this.deg = [];
						this.diff = 0;
						this.tbDiff = 0;
						this.firstPlace();
					}
				}
				this.fireEvent('onLeave');
			}.bind(this)
		});
		window.addEvents({
			'resize': this.getCoord.bind(this),
			'load'  : this.getCoord.bind(this)
		});
	},

	getCoord: function(){
		this.contCoord  = this.container.getCoordinates();
		this.ziLeft     = this.contCoord.left;
		this.ziTop      = this.contCoord.top;
		this.ziWidth    = this.contCoord.width;
		this.ziHeight   = this.contCoord.height;
		this.ch         = this.ziWidth / 2; //centre horizontal
		this.cv         = this.ziHeight / 2; //centre vertical
	},

	firstPlace: function(){
		this.elems.each(function(el, i){
			this.deg.push(360 * i / this.num);
			el.setStyles({
				'display'  : 'block',
				'float'    : 'none',
				'position' : 'absolute',
				'opacity'  : this.options.opacity,
			});
			this.place(el, i);
		}.bind(this));
	},

	place: function(el, i){
		var coef;
		this.deg[i] = this.options.mode == "horizontal" ? this.deg[i] + this.move : this.deg[i] + this.tbMove;

		if (this.deg[i] > 360) { this.deg[i] = this.deg[i] % 360; }
		if (this.deg[i] < 0 ) { this.deg[i] = 360 + this.deg[i]; }
		var rad = (this.deg[i] * Math.PI / 180);
		coef = this.deg[i] < 180 ? ((360 - this.deg[i]) / 360) : (this.deg[i]/360);
		//console.log(rad);

		if (this.options.mode == "horizontal"){
			this.yMove = this.tbDiff ? this.tbDiff * (Math.cos(rad)) : 0;

			var ziW  = (this.options.maxWidth * coef).toInt();
			var cx   = (this.ch + (this.ch * (Math.sin(rad) / this.options.hPad))).toInt();
			var _x   = cx - (ziW / 2).toInt();
			var ziH  = (this.options.maxHeight * coef).toInt();
			var _y   = ((this.ziHeight - ziH) / 2).toInt() - this.yMove / this.options.vPad;
		}

		else if (this.options.mode == "vertical"){
			this.xMove = this.diff ? this.diff * (Math.cos(rad)) : 0;

			var ziW  = (this.options.maxWidth * coef).toInt();
			var _x   = ((this.ziWidth - ziW) / 2).toInt() - this.xMove / this.options.hPad;
			var ziH  = (this.options.maxHeight * coef).toInt();
			var cy   = (this.cv + (this.cv * (Math.sin(rad) / this.options.vPad))).toInt();
			var _y   = cy - (ziH / 2).toInt();
		}

		el.setStyles({
			'top'      : _y,
			'left'     : _x,
			'width'    : ziW,
			'height'   : ziH,
			'z-index'  : (this.options.topZ * coef).toInt(),
			'font-size': (this.options.fontMax * coef).toInt()
		});
		if ( this.options.vCenter == true ) el.setStyle('line-height', ziH);
	},

	moveAll: function(){
		this.elems.each(function(el, i){
			this.place(el, i);
		}.bind(this));
		this.enRoute = this.moveAll.delay(15, this);
	},

	unspeed: function(){
		this.move = this.move * 0.98;
		this.tbMove = this.tbMove * 0.98;
		if( ( this.options.mode == 'vertical' && Math.abs(this.tbMove) < 0.4 ) || ( this.options.mode == 'horizontal' && Math.abs(this.move) < 0.4 ) )
		{
			this.move = 0;
			this.tbMove = 0;
			clearTimeout(this.enRoute);
			clearTimeout(this.slowdown);
		}
		this.slowdown = this.unspeed.delay(15, this);
	}
});
