function animateCover(
  viewportClass,
  currentObject,
  startingOffset,
  stepDirection,
  stepWidth,
  step,
  maxStep,
  currentPreview,
  futurPreview
){
  jQuery('>a>img',currentPreview)
      .css({'width': Math.round(86-32*step/maxStep)});
  jQuery('>a>img',futurPreview)
      .css({'width':Math.round(54+32*step/maxStep)});

  futurPreview
    .css({'padding-top':Math.round(22-22*step/maxStep)+'px'});
  currentPreview
    .css({'padding-top':Math.round(22*step/maxStep)+'px'});

  jQuery('>.carousel_viewport', jQuery(currentObject))
    .scrollLeft(startingOffset+stepDirection*Math.round(stepWidth*step/maxStep));
}

function coverInitialization(currentObject, numberOfItem) {
  jQuery('>.carousel_viewport',jQuery(currentObject))[0].scrollLeft = 62 * (numberOfItem - 1);
}
function postAnimationCover(currentHighlight,currentObject){

  var kiosk_link = jQuery('.kiosk_link',jQuery(currentObject));

  jQuery('>ul>li.summary,>ul>li.numeric_edition',kiosk_link).remove();

  if(jQuery('>a.numeric_edition',currentHighlight).length > 0)
  {
    jQuery(document.createElement('li'))
      .append(
        jQuery('>a.numeric_edition',currentHighlight).clone()
      )
      .addClass('numeric_edition')
      .insertBefore(
        jQuery('>ul>li:first-child',kiosk_link)
      );
  }
  if(jQuery('>a.summary',currentHighlight).length > 0)
  {
    jQuery(document.createElement('li')).
      append(
        jQuery('>a.summary',currentHighlight).clone()
      )
      .addClass('summary')
      .insertBefore(
        jQuery('>ul>li:first-child',kiosk_link)
      );
  }

  jQuery(
    '>.carousel_control>.current_title',
    jQuery(currentObject)
  )
    .html(
      jQuery('>a>img',currentHighlight).attr('alt')
    );


}


function animateSimple(
  viewportClass,
  currentObject,
  startingOffset,
  stepDirection,
  stepWidth,
  step,
  maxStep,
  currentPreview,
  futurPreview
){
  jQuery('>.'+viewportClass, jQuery(currentObject))[0]
    .scrollLeft= startingOffset+stepDirection*Math.round(stepWidth*step/maxStep);
}

/**
  * Carousel is a base object used to display multiple information on
  * the same place using an animation function to show hidden information
  * in this place.
  *
  * @constructor
  */

(function(jQuery) {
  function Carousel(options, currentObject){
    var innerObject = this;
    var step = 0;
    var maxStep = 20;
    var stepWidth = 231;
    var isloopable = false;
    var params = {
      min: [54,86],
      current: [86,54],
      scrollLeft: [0,46]
    };
    var beginAtEnd = false;
    var stepDuration = 20;
    var startingOffset = 0;
    var stepDirection = -1;
    var groupScroll = 1;
    var withSeparator = false;
    var viewportClass = 'viewport';

    var previousAnchorClass = 'previous';
    var previousAnchorSelector = '>.' + previousAnchorClass;

    var nextAnchorClass = 'next';
    var nextAnchorSelector = '>.' + nextAnchorClass;

    var incrementTimeOut = 0;
    /*var currentObject;*/
    var animationMethod = function(){};
    var postAnimation = function(){};
    var animationInitialization = function(){};

    function disableSimpleControlClick(){
      disableAnchor(previousAnchorClass, previousAnchorSelector);
      disableAnchor(nextAnchorClass, nextAnchorSelector);
    }
    function enableAnchor(Anchor, AnchorSelector,binding){
      jQuery(AnchorSelector+'_inactive', jQuery(currentObject))
        .removeClass(Anchor+'_inactive')
        .addClass(Anchor+'_active')
        .click(binding);
    }
    function disableAnchor(Anchor, AnchorSelector){
      jQuery(AnchorSelector+'_active', jQuery(currentObject))
        .removeClass(Anchor+'_active')
        .addClass(Anchor+'_inactive')
        .unbind();
    }
    this.buildSimpleAction = function (options){
      return function (){
        disableSimpleControlClick();
        switch(options.stepDirection){
          case -1:
            stepDirection = options.stepDirection;
            break;
          case 1:
            stepDirection = options.stepDirection;
            break;
          default:
            stepDirection = 0;
            break;
        }
        incrementTimeOut = setTimeout(incrementalStep, stepDuration);
        return false;
      };
    }
    function incrementalStep(){
      var currentPreview = jQuery('>.'+viewportClass+'>ul>.current', jQuery(currentObject));
      var futurPreview = currentPreview;
      if (1 == stepDirection){
        for (var i = 0; i < groupScroll; i++){
          futurPreview = futurPreview.next('li');
        }
      }
      else{
        for (var i = 0; i < groupScroll; i++){
          futurPreview = futurPreview.prev('li');
        }
      }
      if (step == 0){
        startingOffset = jQuery('>.'+viewportClass, jQuery(currentObject)).scrollLeft();
      }
      if (step < maxStep){
        step ++;
        animationMethod(
          viewportClass,
          currentObject,
          startingOffset,
          stepDirection,
          stepWidth,
          step,
          maxStep,
          currentPreview,
          futurPreview
        );
        incrementTimeOut = setTimeout(incrementalStep, stepDuration);
      }
      else{
        currentPreview.removeClass('current');
        futurPreview.addClass('current');
        /*jQuery('>.'+viewportClass, jQuery(currentObject))[0]
          .scrollLeft = futurPreview[0].offsetLeft;*/

        if (isloopable){
          if ('endingLoop' == futurPreview.attr('class').match(/\bendingLoop\b/)){
            futurPreview.removeClass('current');
            futurPreview = jQuery('>.'+viewportClass+'>ul>.endingLoopRange', jQuery(currentObject));
            futurPreview.addClass('current');
          }
          if ('startingLoop' == futurPreview.attr('class').match(/\bstartingLoop\b/)){
            futurPreview.removeClass('current');
            futurPreview = jQuery('>.'+viewportClass+'>ul>.startingLoopRange', jQuery(currentObject));
            futurPreview.addClass('current');
          }
          jQuery('>.'+viewportClass, jQuery(currentObject))[0]
            .scrollLeft = futurPreview[0].offsetLeft;
        }
        postAnimation(futurPreview, currentObject);

        switch(stepDirection){
          case -1:
            enableAnchor(nextAnchorClass, nextAnchorSelector, innerObject.buildSimpleAction({stepDirection:1}));
            if(0 != futurPreview.prev('li').length){
              enableAnchor(previousAnchorClass, previousAnchorSelector, innerObject.buildSimpleAction({stepDirection:-1}));
            }
            break;
          case 1:
            enableAnchor(previousAnchorClass, previousAnchorSelector, innerObject.buildSimpleAction({stepDirection:-1}));
            if(0 != futurPreview.next('li').length){
              enableAnchor(nextAnchorClass, nextAnchorSelector, innerObject.buildSimpleAction({stepDirection:1}));
            }
            break;
        }
        step = 0;
        clearTimeout(incrementTimeOut);
      }
    };
    //initialisation du carousel
    if ('number' == typeof options.maxStep)
    {
      maxStep = options.maxStep;
    }
    if ('function' == typeof options.initialization){
      animationInitialization = options.initialization;
    }
    if ('function' == typeof options.postAnimation)
    {
      postAnimation = options.postAnimation;
    }
    if ('number' == typeof options.stepDuration )
    {
      stepDuration = options.stepDuration;
    }
    if ('number' == typeof options.startingOffset )
    {
      startingOffset = options.startingOffset;
    }
    if ('boolean' == typeof options.beginAtEnd){
      beginAtEnd = options.beginAtEnd;
    }
    if ('number' == typeof options.groupScroll)
    {
      groupScroll = options.groupScroll;
    }
    if ((groupScroll > 1) &&('boolean' == typeof options.withSeparator))
    {
      withSeparator = options.withSeparator;
    }

    if ('boolean' == typeof options.isloopable)
    {
      isloopable = options.isloopable;
    }


    if ("function" == typeof options.animationCallback){
      animationMethod = options.animationCallback;
    }

    if ('string' == typeof options.viewport)
    {
      viewportClass = options.viewport;
    }
    if ('string' == typeof options.previous.baseClass)
    {
      previousAnchorClass = options.previous.baseClass;
      if ('string' == typeof options.previous.selectorClass){
        previousAnchorSelector = options.previous.selectorClass;
      }
      else
      {
        previousAnchorSelector = '>.'+previousAnchorClass;
      }
    }
    if ('string' == typeof options.next.baseClass)
    {
      nextAnchorClass = options.next.baseClass;
      if ('string' == typeof options.next.selectorClass){
        nextAnchorSelector = options.next.selectorClass;
      }
      else
      {
        nextAnchorSelector = '>.'+nextAnchorClass;
      }
    }
    jQuery('>.'+viewportClass, jQuery(currentObject)).scrollLeft(0);
    if ('number' == typeof options.stepWidth)
    {
      stepWidth = options.stepWidth;
    }
    else{
      //i don't know why, but offsetWidth is not a reliable method in webkit browsers ...
      //stepWidth = jQuery('>.'+viewportClass, jQuery(this)).outerWidth() + (withSeparator?(groupScroll-1):0);
    }
    if(beginAtEnd){

      jQuery('>.'+viewportClass+'>ul>li.current', jQuery(currentObject)).removeClass('current');
      jQuery('>.'+viewportClass+'>ul>li:last', jQuery(currentObject)).addClass('current');

      jQuery('>.'+viewportClass, jQuery(currentObject))
        .scrollLeft(
          jQuery('>.'+viewportClass+'>ul>li.current', jQuery(currentObject))[0]
            .offsetLeft +
          jQuery('>.'+viewportClass+'>ul>li.current', jQuery(currentObject))[0]
            .offsetWidth -
          jQuery('>.'+viewportClass, jQuery(currentObject))[0].offsetWidth
        );
    }
    if (isloopable){
      var LastItem = jQuery('>.'+viewportClass+'>ul>li:last-child', jQuery(currentObject));
      var FirstItem = jQuery('>.'+viewportClass+'>ul>li:first-child', jQuery(currentObject));
      for (var j = 0; j < groupScroll; j++)
      {
        jQuery('>.'+viewportClass+'>ul>li:first-child', jQuery(currentObject)).before(LastItem.clone());
        jQuery('>.'+viewportClass+'>ul>li:last-child', jQuery(currentObject)).after(FirstItem.clone());

        switch (j){
          case 0:
            FirstItem.addClass('startingLoopRange');
            jQuery('>.'+viewportClass+'>ul>li:last-child', jQuery(currentObject)).addClass('startingLoop');
            break;
          case groupScroll - 1:
            LastItem.addClass('endingLoopRange');
            jQuery('>.'+viewportClass+'>ul>li:first-child', jQuery(currentObject)).addClass('endingLoop');
            break;
        }

        LastItem = LastItem.prev('li');
        FirstItem = FirstItem.next('li');
      }
      jQuery('>.'+viewportClass, jQuery(this)).scrollLeft(jQuery('>.'+viewportClass+'>ul>li.current', jQuery(this))[0].offsetLeft);
    }
    animationInitialization(currentObject, jQuery('>.'+viewportClass+'>ul>li', jQuery(currentObject)).length)
    jQuery(options.previous.selectorClass,currentObject).removeClass(previousAnchorClass).addClass(previousAnchorClass+'_active');
    jQuery(options.next.selectorClass,currentObject).removeClass(nextAnchorClass).addClass(nextAnchorClass+'_active');
  }

  $.fn.Carousel = function(options){
    //encapsulation du comportement du carousel dans un objet
    var CurrentCarousel = new Carousel(options,this);
    jQuery(options.previous.selectorClass+'_active', jQuery(this))
      .click(CurrentCarousel.buildSimpleAction({
        stepDirection: -1,
        carouselObject: CurrentCarousel
      }));
    jQuery(options.next.selectorClass+'_active', jQuery(this))
      .click(CurrentCarousel.buildSimpleAction({
        stepDirection: 1,
        carouselObject: CurrentCarousel
      }));
  };
  /*$.Carousel = function(obj) {
  };*/
})(jQuery);


