vanilla.namespace('campagnepublique.news');

$.extend
(
    $.fx.step,
    {
	zIndex : function(fx)
	{
	    jQuery.attr(fx.elem.style, "zIndex", Math.floor(fx.now));
	}
    }
);

campagnepublique.news.carrousel = 
{
    time	: 5000,
    speed	: 400,
    sens	: 1,
    view	: null,
    items	: null,
    carrousel	: null,
    interval	: null,
    positions	: [],

    init : function(properties)
    {
	var self = this;
	var view = this.view = $("#view-" + properties.viewId);
	this.items = view.find("ul.newsList li.news");

	if ( this.items.length <= 0 )
	{
	    return;
	}

	/*
	   On génère le carrousel d'images
	*/

	this._generateCarrousel();

	/*
	   On initialise les positions
	*/

	this._initPositions();

	/*
	    Met à jour la taille de la liste de news comme la taille
	    de la plus grande news
	*/
	this._updateNewslistHeight();

	/*
	   Sélection de la première item
	*/

	this.selectByIndex(0);
    },

    select : function(item, clearInterval)
    {
	item = $(item);

	if ( clearInterval && this.interval != null )
	{
	    window.clearInterval(this.interval);
	    this.interval = null;
	}

	var current = this.getCurrent();
	if ( current.get(0) == item.get(0) )
	{
	    return;
	}

	var self = this;

	// unselect
	current.toggleClass("selected", false).animate
	(
	    {opacity:0}, this.speed
	)
	.queue
	(
	    // on enque la fonction plutôt que d'utiliser la fonction 
	    // de fin d'animation, car elle ne s'insère dans la queue dès le départ
	    // ce qui cause des comportements non voulus
	    function(next)
	    {
		$(this).hide();
		next();
	    }
	);

	// gestion de la description
	if ( current.length > 0 )
	{
	    item.toggleClass("selected", true)
	    .queue
	    (
		function(next)
		{
		    $(this).css({opacity:0}).show()
		    next();
		}
	    )
	    .animate({opacity:1}, this.speed);
	}
	else
	{
	    // la première fois pas d'animation
	    item.toggleClass("selected", true).css({opacity:1}).show();
	}

	// animation du carrousel
	var index = this.items.index(item);
	this.carrousel.find("img").each
	(
	    function(i)
	    {
		$(this).animate
		(
		    self.getPositionFor(i, index).css, 
		    {
			duration : self.speed
		    }
		);
	    }
	)

	// on redétermine le sens
	var currIdx = this.items.index(current);
	if ( currIdx >= 0 )
	{
	    this.sens = this.getPositionFor(index, currIdx).angle > Math.PI/2 ? -1 : 1;
	}

	if ( this.interval == null && this.items.length > 1 )
	{
	    this.interval = window.setInterval
	    (
	        function()
	        {
		    self.next();
	            //if ( self.sens > 0 )
		    //{
		    //    self.next()
		    //}
		    //else
		    //{
		    //    self.previous();
		    //}
	        },
	        this.time
	    );
	}
    },

    getCurrent : function()
    {
	return this.items.filter(".selected");
    },

    getPositionFor : function(index, topIndex)
    {
	var j = (index + (this.items.length - topIndex)) % this.items.length;
	return this.positions[j];
    },

    selectByIndex : function(index, clearInterval)
    {
	index %= this.items.length;

	var self = this;
	this.carrousel.synchronize
	(
	    function()
	    {
		self.select(self.items[index], clearInterval);
	    }
	)
    },

    next : function(clearInterval)
    {
	if ( this.items.length <= 0 )
	{
	    return;
	}

	var self = this;
	this.carrousel.synchronize
	(
	    function()
	    {
		var i = self.items.index(self.getCurrent()) + 1;
		i %= self.items.length;

		self.selectByIndex(i, clearInterval);
	    }
	);
    },

    previous : function(clearInterval)
    {
	if ( this.items.length <= 0 )
	{
	    return;
	}

	var self = this;
	this.carrousel.synchronize
	(
	    function()
	    {
		var i = self.items.index(self.getCurrent()) - 1;
		if ( i < 0 )
		{
		    i = self.items.length - 1;
		}

		self.selectByIndex(i, clearInterval);
	    }
	);
    },

    _generateCarrousel : function()
    {
	this.carrousel	= $("<div class=\"carrousel\"></div>");
	var images	= $("<div class=\"inner\"></div>").appendTo(this.carrousel);
	var self	= this;

	this.items.each 
	(
	    function(i)
	    {
		var it = $(this);
		var img = it.find("a.img img").clone().appendTo(images).click
		(
		    function(e)
		    {
			self.select(it, true);
			e.stopPropagation();
			e.preventDefault();
		    }
		)
		.dblclick
		(
		    function(e)
		    {
			e.stopPropagation();
			e.preventDefault();
		    }
		);
	    }
	);

	this.carrousel.insertBefore(this.items.parent("ul"));
    },

    _initPositions : function()
    {
	var imgs	= this.carrousel.find("img");
	var self	= this;
	var l		= imgs.length;

	var carrouselW	= this.carrousel.find("div.inner").width() / 2;
	var deep	= 3;
	var itemW	= imgs.width();
	var itemH	= imgs.height();
	var angle	= Math.PI/2;
	var step	= imgs.length > 3 ? Math.PI/4 : Math.PI/3;

	this.positions.length = l;

	for ( var j = 0 ; j < l ; j++ )
	{
	    // on parcours le cercle 
	    // en dispatchant de part-et d'autre
	    var i = Math.ceil(j/2);
	    if ( j%2 )
	    {
		i = l - i;
	    }

	    // récupération de l'item
	    var it = imgs.eq(i);

	    // au delà des 5 images visibles on cache les autres
	    var a = angle;// = angle < 0 ? -Math.PI/2 : angle;
	    if ( angle < 0 )
	    {
		a = -Math.PI/2;
	    }
	    else if ( j%2 > 0 )
	    {
		a = Math.PI - a;
	    }

	    var d = 1;//j%2 > 0 ? -1 : 1;

	    // calcul des positions sur le cercle
	    var x = d * Math.round(carrouselW * Math.cos(a));
	    var y = Math.round(deep * Math.sin(a));

	    // on repositionne les dimensions dans le repère
	    x += carrouselW;
	    y += deep;
	    y /= 2;

	    // calcul de la nouvelle hauter et largeur
	    var r = y/deep;
	    var w = itemW*r;
	    var h = itemH*r;

	    var left = x;
	    if ( j == 0 || angle < 0 )
	    {
		left -= w/2;
	    }
	    else if ( j%2 == 0 )
	    {
		left -= w;
	    }

	    var pos = 
	    {
		css : 
		{
		    left	: left,
		    top	: (itemH - h) / 2,
		    zIndex  : y*10,
		    width	: w,
		    height	: h
		},
		angle : a
	    }

	    it.css(pos.css);

	    this.positions[i] = pos;

	    // on avance l'angle
	    if ( j%2 == 0 )
	    {
	        angle -= step;
	    }
	}
    },

    _updateNewslistHeight : function()
    {
	var max = 0;
	this.items.each
	(
	    function()
	    {
		max = Math.max(max, $(this).height());
	    }
	)

	this.items.parent("ul").height(max);
    }
};

