/**
 * Auto scroller script
 *
 *
 * The script is freely distributable under the terms of an MIT license.
 *
 *
 * @author Hristo Drumev
 * @license MIT license
 * @copyright Hristo Drumev [www.hdrumev.com]
 * @version 0.12 / 05.04.2010
 *
 *
 * >>> Do not needed any libraries or frameworks
 * 
 * Usage : Include this script file and setup the configuration
 *
 */


( function() {

// Configuration
var options =
{
  containerId  : 'autoscroller',   // Id of element which is a container 
  restArea     : 10,               // Width of rest area [px] 
  speed        : 20,               // Maximal speed of motion
  stopOnExit   : false,            // To stop motion when mouse leave scroll area
  initPosition : 'left',           // Initial position of scroller - left, center or right
  autoSpeed    : 4                 // Speed of auto scroll when script loaded
};

// ----------------------------------------------------------------------------

function addEvent( element, type, fn )
{
  if( element.addEventListener )
  {
    switch( type )
    {
      case 'mouseenter': element.addEventListener( 'mouseover', mouseInOut( fn ), false ); break;
      case 'mouseleave': element.addEventListener( 'mouseout',  mouseInOut( fn ), false ); break;
      default: element.addEventListener( type, fn, false ); break;
    }
  }
  else if( element.attachEvent )
    element.attachEvent( 'on' + type, function(){ fn.call( element, window.event ); } );
}

function mouseInOut( fn )
{
  return function( event )
  {
    var element = event.relatedTarget;
    while( element && element !== this )
      element = element.parentNode;
    if( element !== this )
      fn.call( this, event );
  };
}

// ----------------------------------------------------------------------------

/**
 * Auto scroller constructor
 *
 * @param {Object} options - Script options
 */
function AutoScroller( options )
{
  this.options = options;
  this.container = document.getElementById( options.containerId );
  if( !this.container )
    return ;//window.alert( 'Autoscroller: Container not found.' );
  var containerWidth = this.container.offsetWidth;
  this.slider = this.container.getElementsByTagName( '*' )[0];
  if( !this.slider )
    return window.alert( 'Autoscroller: Slider not found.' );
  
  var sliderWidth = 0;
  var elements = this.slider.getElementsByTagName( '*' );
  var computed = document.defaultView;
  for( var i = 0; i < elements.length; i++ )
  {
    var element = elements[i];
    if( element.parentNode !== this.slider )
      continue;
    var offset =  element.offsetLeft + element.offsetWidth;
    if( offset > sliderWidth )
      sliderWidth = offset;
  }
  if( sliderWidth < containerWidth )
    return;
  
  
  var self = this;
  var eventOver = function( event ) { self.mouseOver.call( self, event || window.event ); };
  var eventOut = function( event ) { self.mouseOut.call( self, event || window.event ); };
  addEvent( this.container, 'mousemove', eventOver );
  if( options.stopOnExit )
    addEvent( this.container, 'mouseleave', eventOut );
  this.centerPos = containerWidth >>> 1;
  this.maxPos = -( sliderWidth - containerWidth );
  this.pos = 0;
  switch( options.initPosition )
  {
    case 'left'  : this.pos = 0; break;
    case 'center': this.pos = parseInt( this.maxPos / 2 ); break;
    case 'right' : this.pos = this.maxPos; this.direction = 'left'; break;
  }
  this.slider.style.left = this.pos + 'px';
  this.timer = null;
  var element = this.container;
  var parent = element.offsetParent;
  var containerOffsetLeft = element.offsetLeft;
  while( parent )
  {
    containerOffsetLeft += parent.offsetLeft;
    parent = parent.offsetParent;
  }
  this.baseOffset = containerOffsetLeft + this.centerPos;
  this.moveFn = function() { self.move.call( self ); };
  if( options.autoSpeed > 0 )
  {
    this.step = options.autoSpeed;
    this.timer = window.setInterval( this.moveFn, 40 );
  }
}

AutoScroller.prototype.mouseOver = function( event )
{
  var offset = ( event.pageX || event.clientX + document.documentElement.scrollLeft ) - this.baseOffset;
  if( Math.abs( offset ) < this.options.restArea )
  {
    this.mouseOut( event );
    return;
  }
  if( !this.timer )
    this.timer = window.setInterval( this.moveFn, 40 );
  this.direction = offset > 0 ? 'right' : 'left';
  this.step = parseInt( Math.abs( offset ) / this.centerPos * this.options.speed );
};

AutoScroller.prototype.mouseOut = function( event )
{
  if( this.timer )
  {
    window.clearInterval( this.timer );
    this.timer = null;
  }
}

AutoScroller.prototype.move = function()
{
  this.pos = this.direction === 'left'
           ? Math.min( this.pos + this.step, 0 )
           : Math.max( this.pos - this.step, this.maxPos );
  this.slider.style.left = this.pos + 'px';  
  if( this.pos >= 0 || this.pos <= this.maxPos )  
  {
    window.clearInterval( this.timer );
    this.timer = null;
  }
}

// ----------------------------------------------------------------------------

/**
 * DOM ready event listener
 *
 * @param {Function} fn - listener
 */
var domReady = function( fn )
{
  [,].length === 2
  ? window.attachEvent( 'onload', fn )
  : document.addEventListener( 'DOMContentLoaded', fn, false );
}

// ----------------------------------------------------------------------------

domReady( function() { new AutoScroller( options ) } );

} )();


