
//requires jQuery
$.log = function(message)
{
  if (typeof window.console.log == 'function') window.console.log(message);
};
var Slider = function(element, options)
{
  if ( $(element).hasClass('activated') ) return false;
  $.extend(this.options, options);
  this.shell = $(element);
  this.init();
}
Slider.prototype = {
  options:{
    auto:true,
    repeat:-1,
    endRepeatOn:1,
    wrap:true,
    navType:'thumbnail',
    interval:3500,
    easeFunc:"easeInOutExpo",
    easeTime:750,
    navItemCount:5,
    navItemHeight:60,
    navPadding:10,
    navItemSpacing:4
  },
  shell:null,
  container:null,
  slides:null,
  navContainer:null,
  nav:null,
  navItems:null,
  navItemWidth:null,
  slideWidth:null,
  slideHeight:null,
  fullWidth:null,
  timeout:null,
  repeatCount:0,
  currentIndex:null,
  init:function()
  {
    this.shell.addClass('slider-shell');
    this.container = this.shell.children().first().addClass('container');
    this.slides = this.container.children().css(
      {
        display:'block',
        float:'left'
      }
    ).addClass('slide');
    this.slideWidth = this.slides.first().width();
    this.slideHeight = this.slides.first().height();
    this.fullWidth = this.slides.length * this.slideWidth;
    this.shell.addClass('activated').css(
      {
        overflow:'hidden',
        position:'relative',
        width:this.slides.first().width() + 'px',
        height:( this.slideHeight + this.options.navItemHeight + this.options.navPadding * 2 ) + 'px'
      }
    );
    this.container.css(
      {
        position:'absolute',
        width:(this.fullWidth * 2) + 'px'
      }
    );
    this.createNav();
    this.show(0, true);
  },
  createNav:function()
  {
    var y = this;
    y.navContainer = $('<div/>').addClass('nav-container').css(
      {
        overflow:'hidden',
        position:'absolute',
        height:(y.options.navItemHeight + y.options.navPadding * 2) + 'px',
        padding:y.options.navPadding + 'px 0',
        width:y.slideWidth + 'px',
        top:y.slideHeight + 'px'
      }
    );
    y.nav = $('<ul/>').addClass('nav');
    var navWidth = 0;
    y.slides.each(
      function(index, element)
      {
        var navItem = $('<li/>').css(
          {
            'float':'left',
            'list-style':'none',
            'margin':0,
            'padding':0
          }
        );
        var navLink = $('<a/>');
        navLink.click(
          function(event)
          {
            event.preventDefault();
            y.show( $(event.currentTarget).parents('li').index() );
          }
        );
        y.navItemWidth = Math.round( ( y.slideWidth - y.options.navItemSpacing * (y.options.navItemCount - 1) ) / y.options.navItemCount );
        if ('thumbnail' == y.options.navType)
        {
          navItem.css(
            {
              width:y.navItemWidth + 'px',
              height:y.options.navItemHeight + 'px',
              'padding-left':index && y.options.navItemSpacing + 'px'
            }
          );
          navLink.css(
            {
              display:'block',
              overflow:'hidden',
              width:y.navItemWidth + 'px',
              height:y.options.navItemHeight + 'px',
              position:'relative',
            }
          );
          var img = $(element).find('img').first();
          var thumbnailWidth = Math.round(
            y.slideWidth / y.slideHeight * y.options.navItemHeight
          );
          navWidth += y.navItemWidth + (index && y.options.navItemSpacing);
          navLink.append(
            img.clone().css(
              {
                position:'absolute',
                left:Math.floor( (y.navItemWidth - thumbnailWidth) / 2 ) + 'px',
                height:y.options.navItemHeight + 'px',
                width:thumbnailWidth + 'px'
              }
            )
          );
        }
        else
        {
          navLink.text( typeof $(element).attr('title') != 'undefined'? $(element).attr('title'): index + 1);
        }
        navItem.append(navLink);
        y.nav.append(navItem);
      }
    );
    y.nav.css(
      {
        position:'absolute',
        left:0,
        'list-style':'none',
        margin:0,
        padding:0,
        height:y.options.navItemHeight + 'px',
        width:navWidth + 'px'
      }
    );
    y.navItems = y.nav.children();
    y.navContainer.append(y.nav);
    y.shell.append(y.navContainer);
  },
  show:function(index, sudden)
  {
    var y = this;
    while (index > y.slides.length - 1)
    {
      index -= y.slides.length;
    }
    y.currentIndex = index;
    var target = -index * y.slideWidth;
    if (sudden)
    {
      y.container.css( {left:target });
      y.autoAdvance();
    }
    else
    {
      var left = y.container.position().left;
      var distance = target - left;
      if ( y.options.wrap && Math.abs( distance ) > y.fullWidth / 2 ) {
        var clones = y.slides.clone().addClass('clone');
        y.container.append( clones );
        if ( distance > 0 ) {
          target -= y.fullWidth;
        } else {
          y.container.css( {'left':left - y.fullWidth} );
        }
      }
      clearTimeout(this.timeout);
      y.container.animate(
        {left:target},
        y.options.easeTime,
        y.options.easeFunc,
        function()
        {
          y.container.find('.clone').remove();
          if (target <= -y.fullWidth) y.container.css( {'left':target + y.fullWidth} );
          y.autoAdvance();
        }
      );
    }
    y.selectNavItem(index, sudden);
  },
  autoAdvance:function()
  {
    var y = this;
    if(
      !y.options.auto
      || ( y.options.repeat > -1 && y.repeatCount >= y.options.repeat && y.currentIndex == y.options.endRepeatOn )
    ) return false;
    clearTimeout(this.timeout);
    this.timeout = setTimeout(
      function()
      {
        y.show(y.currentIndex+1);
        if (y.currentIndex == 0) y.repeatCount++;
      },
      y.options.interval
    );
  },
  selectNavItem:function(index, sudden)
  {
    var y = this;
    y.navItems.removeClass('active');
    y.navItems.eq(index).addClass('active');
    var navLeft = y.nav.position().left;
    var itemLeft = y.navItems.eq(index).position().left;
    var navTarget = navLeft;
    if (navLeft + itemLeft - y.navItemWidth < 0)
    {
      navTarget = -itemLeft + y.navItemWidth;
    }
    else if (navLeft + itemLeft + y.navItemWidth * 2 > y.slideWidth)
    {
      navTarget = -itemLeft + y.slideWidth - (y.navItemWidth + y.options.navItemSpacing) * 2;
    }
    if (navTarget > 0) navTarget = 0;
    if (navTarget < -y.nav.width() + y.slideWidth) navTarget = -y.nav.width() + y.slideWidth;
    if (navTarget != navLeft)
    {
      y.nav.animate(
        {left:navTarget},
        y.options.easeTime,
        y.options.easeFunc,
        function()
        {
          y.nav.find('.clone').remove();
          if (navTarget <= -y.nav.width()) y.container.css( {'left':navTarget + y.nav.width()} );
        }
      );
    }
  }
};

