/**
 * @description slideshow<br />
 * 
 * @author bKarolyi
 */


/**
 * @description slideshow handler class
 * @class
 */
var slideshow_class = function()
{
  this.cardwidth = 0;
  this.cardwidth_modifier = 0,
  this.cardwidth_total = 0, 
  this.slider_id = "";
  this.cardwrap = null;
  this.animate = false;
  this.loop = false;
  this.card_list = [];
  this.actual_counter_position = 0;
  this.leftbutton = null;
  this.rightbutton = null;
  this.inactivebutton_class = "";
}

/**
 * @description slideshow handler methods
 * @namespace
 */
slideshow_class.prototype =
{
  /**
   * @description sets up slideshow
   * @param {Object} config <b>available options: </b><br />
   * <i>cardwidth:</i> width of the card in px,<br />
   * <i>cardwidth_modifier:</i> extra pixels for the width like margin<br />
   * <i>slider_id:</i> prefix id for the necessary fields<br />
   * <i>inactivebutton_class:</i> the class name the scroller button gets when became inactive<br />
   * <i>animation_time:</i> animation duration in millisecs<br />
   * <i>animate:</i> boolean - whether the scrolling is animated or not<br />
   * <i>loop:</i> boolean - whether the scrolling restarts when it ends or not<br />
   */
  construct: function( config )
  {
    for ( i in config )
    {
      this[i] = config[i];
    }
    
    this.cardwidth_total = this.cardwidth + this.cardwidth_modifier;
    this.cardwrap = Dom.get( this.slider_id + "_cardwrap" );
    this.cards_length = this.cards_length || 1;
    
    var slideshow_counter = 1;
    while ( Dom.get( this.slider_id + "_item_" + slideshow_counter ) )
    {
      this.card_list.push( Dom.get( this.slider_id + "_item_" + slideshow_counter ) );
      slideshow_counter++;
    }
    
    this.leftbutton = Dom.get( this.slider_id + "_leftbutton" );
    this.rightbutton = Dom.get( this.slider_id + "_rightbutton" );
  },
  
  /**
   * @description gets actual left coordinate of the wrap element
   * @returns {Number} left coordinate in px
   */
  getActLeft: function()
  {
    return parseInt( Dom.getStyle( this.cardwrap, "left" ) ) || 0;
  },
  
  /**
   * @description sets left coordinate of the wrap element
   * @param {Number} new_left left coordinate in px
   */
  setLeft: function( new_left )
  {
    Dom.setStyle( this.cardwrap, "left", new_left + "px" );
    return true;
  },
  
  /**
   * @description increases or decreases the left coordinate of the wrap element
   * @param {Number} by the amount to change the left value with. in px
   */
  setLeftBy: function( by )
  {
    var act_left = this.getActLeft();
    var new_left = act_left + by;
    Dom.setStyle( this.cardwrap, "left", new_left + "px" );
    return true;
  },
  
  /**
   * @description increases actual card counter
   */
  increaseCounter: function()
  {
    if ( this.actual_counter_position == this.card_list.length - this.cards_length + 1 )
    {
      this.actual_counter_position = 0;
    }
    else
    {
      this.actual_counter_position++;
    }
    
    return true;
  },

  /**
   * @description decreases actual card counter
   */  
  decreaseCounter: function()
  {
    if ( this.actual_counter_position == 0 )
    {
      this.actual_counter_position = this.card_list.length - 1;
    }
    else
    {
      this.actual_counter_position--;
    }
    
    return true;
  },

  /**
   * @description steps left one card
   */
  stepLeft: function()
  {
    this.moveLast();
    
    Dom.removeClass( this.rightbutton, this.inactivebutton_class );
    if ( this.actual_counter_position == 0 && !this.loop )
    {
      return false;
    }
    
    if ( this.actual_counter_position == 1 && !this.loop )
    {
      Dom.addClass( this.leftbutton, this.inactivebutton_class );
    }
    this.setLeftBy( this.cardwidth_total );
    this.decreaseCounter();
    return true;
  },

  /**
   * @description validation and settings before stepping right
   */
  beforeStepRight: function()
  {
    this.moveFirst();

    Dom.removeClass( this.leftbutton, this.inactivebutton_class );
    if ( this.actual_counter_position == this.card_list.length - this.cards_length && !this.loop )
    {
      return false;
    }
    
    if ( this.actual_counter_position == this.card_list.length - 1 - this.cards_length && !this.loop )
    {
      Dom.addClass( this.rightbutton, this.inactivebutton_class );
    }
    
    return true;
  },
  
  /**
   * @description steps right one card
   */
  stepRight: function()
  {
    if ( !this.beforeStepRight() )
    {
      return false;
    }
    
    this.setLeftBy( -this.cardwidth_total );
    this.increaseCounter();
        
    return true;
  },

  /**
   * @description moves first card to the end. used when loopin set to true
   */
  moveFirst: function()
  {
    if ( !this.loop )
    {
      return false;
    }
    
    if ( this.actual_counter_position == this.card_list.length - this.cards_length )
    {
      Dom.insertAfter( this.card_list[0], this.card_list[ this.card_list.length -1 ] );
      this.card_list.push( this.card_list.shift() );
      this.setLeftBy( this.cardwidth_total );
      this.decreaseCounter();
    }
    
    return true;
  },
  
  /**
   * @description moves last card to the first place. used when loopin set to true
   */
  moveLast: function()
  {
    if ( !this.loop )
    {
      return false;
    }
    
    if ( this.actual_counter_position == 0 )
    {
      Dom.insertBefore( this.card_list[ this.card_list.length -1 ], this.card_list[0] );
      this.card_list.unshift( this.card_list.pop() );
      this.setLeftBy( -this.cardwidth_total );
      this.increaseCounter();
    }
    
    return true;
  },
  
  
  
  
  //animation
  /**
   * @description whether the animation is running
   * @type {Boolean}
   */
  is_animating: false,
  
  /**
   * @description if animation is running stores the animation object
   * @type {Object}
   */
  animation_obj: null,

  /**
   * @description animation object to the left
   * @type {Object}
   */  
  left_anim: null,
  
  /**
   * @description steps left one card animated
   */
  stepLeftAnim: function()
  {
    if ( this.is_animating )
    {
      return false;
    }

    this.moveLast();

    Dom.removeClass( this.rightbutton, this.inactivebutton_class );
    
    if ( this.actual_counter_position == 1 && !this.loop )
    {
      Dom.addClass( this.leftbutton, this.inactivebutton_class );
    }
    
    if ( this.actual_counter_position == 0 && !this.loop )
    {
      return false;
    }
    
    if ( !this.left_anim )
    {
      var new_left = this.cardwidth_total;
      this.left_anim = this.left_anim || new YAHOO.util.Anim( this.cardwrap, 
                                                                {
                                                                  left: { by: new_left } 
                                                                },
                                                                this.animation_time / 1000
                                                              );
  
      this.left_anim.onComplete.subscribe( this.stepLeftAnimCallback, this, true );
    }
    this.is_animating = true;
    this.animation_obj = this.left_anim;
    this.left_anim.animate();
    
    return true;
  },

  /**
   * @description callback function for left animation. runs when it ends
   */   
  stepLeftAnimCallback: function()
  {
    this.decreaseCounter();
    this.animation_obj = null;
    this.is_animating = false;
    return true;
  },
  
  /**
   * @description animation object to the left
   * @type {Object}
   */
  right_anim: null,
  
  /**
   * @description steps right one card animated
   */
  stepRightAnim: function()
  {
    if ( this.is_animating )
    {
      return false;
    }

    this.moveFirst();

    Dom.removeClass( this.leftbutton, this.inactivebutton_class );
    if ( this.actual_counter_position == this.card_list.length - 4 - this.cards_length && !this.loop )
    {
      return false;
    }
    
    if ( this.actual_counter_position == this.card_list.length - 5 - this.cards_length && !this.loop )
    {
      Dom.addClass( this.rightbutton, this.inactivebutton_class );
    }
    
    if ( !this.right_anim )
    {
      var new_left = - this.cardwidth_total;
      this.right_anim = this.right_anim || new YAHOO.util.Anim( this.cardwrap, 
                                                                {
                                                                  left: { by: new_left } 
                                                                },
                                                                this.animation_time / 1000
                                                              );
  
      this.right_anim.onComplete.subscribe( this.stepRightAnimCallback, this, true );
    }
    this.is_animating = true;
    this.animation_obj = this.right_anim;
    this.right_anim.animate();
    return true;
  },
  
  /**
   * @description callback function for right animation. runs when it ends
   */
  stepRightAnimCallback: function()
  {
    this.increaseCounter();
    this.animation_obj = null;
    this.is_animating = false;
    return true;
  }
}

/**
 * @description class for advanced slideshow<br />
 * contains automatic slideshow and jumping to a specified page<br />
 * @extends slideshow_class
 * @class
 * @param {Object} config <b> available options:</b><br />
 * <i>slider_id:</i> "slideshow_top",<br />
 * <i>slide_startclass:</i> the class name the animation toggler button gets when it is stopped<br />
 * <i>slide_stopclass:</i> the class name the animation toggler button gets when it is started<br />
 * <i>slide_is_animated:</i> boolean - whether the slideshow is animated or not<br />
 * <i>delay_time:</i> delay time between sliding in millisecs<br />
 */
var slideshow_advanced_class = function( config )
{
  slideshow_class.call( this, config );
  this.is_during_delay = false;
  this.delay_obj = null;
  this.slide_is_running = false;
}

/**
 * @description advanced slideshow methods
 * @namespace
 */
slideshow_advanced_class.prototype = new slideshow_class();
slideshow_advanced_class.prototype.constructor = slideshow_class;
slideshow_advanced_class.prototype.stepRight = function()
{
  if ( !this.beforeStepRight() )
  {
    return false;
  }
  
  this.setLeftBy( -this.cardwidth_total );
  this.increaseCounter();
  
  if ( this.slide_is_running )
  {
    var act_scope = this;
    this.delay_obj = window.setTimeout( function() 
                                       {
                                         act_scope.stepRight.call( act_scope );
                                       },
                                       this.delay_time
    );
  }
  
  return true;
};
slideshow_advanced_class.prototype.stepRightAnimCallback = function()
{
  this.increaseCounter();
  this.animation_obj = null;
  this.is_animating = false;
  if ( this.slide_is_running )
  {
    var act_scope = this;
    this.delay_obj = window.setTimeout( function() 
                                       {
                                         act_scope.stepRightAnim.call( act_scope );
                                       },
                                       this.delay_time
    );
  }
  return true;
};
/**
 * @description starts or stops slideshow
 */
slideshow_advanced_class.prototype.toggleSlide = function()
{
    if ( this.slide_is_running )
    {
      Dom.replaceClass( Dom.get( this.slider_id + "_startbtn" ), "stop", "start" );
      this.slide_is_running = false;
      if ( this.delay_obj )
      {
        window.clearTimeout( this.delay_obj );
      }
    }
    else if ( this.is_animating )
    {
      return false;
    }
    else 
    {
      Dom.replaceClass( Dom.get( this.slider_id + "_startbtn" ), "start", "stop" );
      this.slide_is_running = true;
      if ( this.slide_is_animated )
      {
        this.stepRightAnim();
      }
      else
      {
        this.stepRight();
      }
    }
}
/**
 * @description jumps to a specified card
 * @param {Number} num number of the card to jump
 */
slideshow_advanced_class.prototype.goToPic = function( num )
{
  if ( this.slide_is_running )
  {
    this.toggleSlide();
  }
  else if ( this.is_animating )
  {
    this.animation_obj.stop();
    this.is_animating = false;
  }
  
  if ( this.animation_obj )
  {
    this.animation_obj.stop();
    this.is_animating = false;
  }

  var place_in_list = 0;
  for ( i_cards = 0; i_cards < this.card_list.length; i_cards++ )
  {
    var act_card = this.card_list[i_cards];
    if ( act_card.id.split( "_" )[3] == num )
    {
      place_in_list = i_cards;
      break;
    }
  }
  
  this.actual_counter_position = place_in_list 
  this.setLeft( -1 * place_in_list * this.cardwidth_total );
  return true;
}


