(function($){

  var methods = {};
    methods.init = function(options){
      
      // check to see if we exist. if not, we create ourselves
      if(typeof $.twSlideshow != 'object'){
        $.twSlideshow = {};
          $.twSlideshow.settings = {
            'animationSpeed': 300,
            'animationType': '',
            'pauseRotationOnHover': true,
            'rotationDelay': 9000,
            'rotate': true,
            'randomize': true,
            'showNav': true,
            'navVerticalAlign':'bottom',// top bottom or middle
            'navHorizontalAlign':'right',// right left or center
            'navVerticalBuffer': 10,
            'navHorizontalBuffer': 10,
            'height':400,
            'width':600
          };
          
          $.twSlideshow.target = this;
          $.twSlideshow.currentSlideNumber = 1;
          $.twSlideshow.numberOfSlides = 0;
      }
      
      if(this.is('ul')){
        
        //Overwrite default settings, if needed
        this.each(function(){
          if (options) {
            $.extend($.twSlideshow.settings, options);
          }
        });
        
        // Create and style viewport
        this.wrap('<div class="twSlideshowViewport" />');
        $.twSlideshow.viewport = this.parent('.twSlideshowViewport');
        $.twSlideshow.viewport.css({
          'height': $.twSlideshow.settings.height,
          'overflow': 'hidden',
          'position': 'relative',
          'width': $.twSlideshow.settings.width
        });
        
        // Create and style container
        this.parent('.twSlideshowViewport').wrap('<div class="twSlideshowContainer" />');
        $.twSlideshow.container = this.parents('.twSlideshowContainer');
        $.twSlideshow.container.css({
          'width': $.twSlideshow.settings.width,
          'position':'relative'
        });
        
        //setup slides
        var slideContainerWidth = 0;
        var slides = this.children('li');
        $.twSlideshow.numberOfSlides = slides.length;
        
        // randomize LIs
        if($.twSlideshow.settings.randomize == true){
          // this logic seems to favor keeping the first one in the first position
          var $liArr = $.twSlideshow.target.children('li');
          $liArr.sort(function(a,b){
                var temp = parseInt( Math.random()*10 );
                var isOddOrEven = temp % 2;
                var isPosOrNeg = temp > 5 ? 1 : -1;
                return( isOddOrEven*isPosOrNeg );
          })
          // append list items to ul
            .appendTo(this);
        }
        
        slides.each(function(){
          $(this).css({
            'float': 'left',
            'height': $.twSlideshow.settings.height,
            'width': $.twSlideshow.settings.width,
            'overflow': 'hidden',
            'padding': 0,
            'margin': 0
          });
          // determine the total length of all ads, side by side
          slideContainerWidth += $(this).outerWidth();
        });
        
        
        //setup navigation
        if($.twSlideshow.settings.showNav == true){
          
          if($.twSlideshow.numberOfSlides > 1){
            this.parent('.twSlideshowViewport').before('<ul class="twSlideshowNav"></ul>');
            
            $.twSlideshow.nav = this.parent('.twSlideshowViewport').siblings('.twSlideshowNav');
            $.twSlideshow.nav.css({
              'list-style':'none',
              'display':'block',
              'padding':'0',
              'margin':'0',
              'float':'left',
              'position':'absolute',
              'z-index': '1'
            });
            $.twSlideshow.nav.append('<li class="prev" style="font-size:10px; padding-top:4px;">&#9668;</li>');
            // run $.each to find all children and link to showing them
            var curNum = 0;
            slides.each(function(){
              curNum += 1;
              $.twSlideshow.nav.append('<li class="jumpTo" data-slidenum="' + curNum + '">' + curNum + '</li>');
            });
            $.twSlideshow.nav.append('<li class="next" style="font-size:10px; padding-top:4px;">&#9658;</li>');
            
            //Add click listeners
            $.twSlideshow.nav.children('li.prev').click(methods.prev);
            $.twSlideshow.nav.children('li.next').click(methods.next);
            $.twSlideshow.nav.children('li.jumpTo').click(function(){
              var target = $(this).attr('data-slidenum');
              methods.jumpTo(target);
            });
            // Style nav button LIs
            $.twSlideshow.nav.children('li').css({
              'cursor': 'pointer',
              'float': 'left'
            });
            
            // SET NAV WIDTH TO ACCOMODATE ALL NAV BUTTONS
            var navWidth = 0;
            $.twSlideshow.nav.children('li').each(function(){
              navWidth += $(this).outerWidth();
            });
            // Set width
            $.twSlideshow.nav.css('width',navWidth);
            
            // Figure horizontal position
            var navLeft = 0;
            switch($.twSlideshow.settings.navHorizontalAlign){
              case 'left':
                navLeft = $.twSlideshow.settings.navHorizontalBuffer;
                break;
              case 'center':
                navLeft = ($.twSlideshow.settings.width / 2) - ($.twSlideshow.nav.outerWidth() / 2);
                break;
              default://right by default
                navLeft = $.twSlideshow.settings.width - $.twSlideshow.nav.outerWidth() - $.twSlideshow.settings.navHorizontalBuffer;
            }
            
            // Figure vertical position
            var navTop = 0;
            switch($.twSlideshow.settings.navVerticalAlign){
              case 'top':
                navTop = $.twSlideshow.settings.navVerticalBuffer;
                break;
              case 'middle':
                navTop = ($.twSlideshow.settings.height / 2) - ($.twSlideshow.nav.outerHeight() / 2);
                break;
              default:// bottom by default
                navTop = $.twSlideshow.settings.height - $.twSlideshow.nav.outerHeight() - $.twSlideshow.settings.navVerticalBuffer;
            }
            
            // Place nav based on 
            $.twSlideshow.nav.css({
              'left':navLeft,
              'top':navTop
            });
            
          }
          
          // Set length of slide container to accomodate all slides
          this.css({
            'width':slideContainerWidth,
            'list-style':'none',
            'display':'block',
            'position':'absolute',
            'padding': 0,
            'margin': 0
          });
        }
        
        
        if($.twSlideshow.settings.rotate == true){
          methods.start();
          this.mouseenter(methods.stop);
          this.mouseleave(methods.start);
        }
      }
      else{
        alert('twSlideshow can only be applied to ULs');
      }
      
      var currentSlideSelector = '[data-slidenum=' + $.twSlideshow.currentSlideNumber + ']';
      $(currentSlideSelector).addClass('selected');
    }
    
    methods.next = function(){
      // check to see if # is in range, if so, set $.twSlideshow.currentSlideNumber
      if($.twSlideshow.currentSlideNumber == $.twSlideshow.numberOfSlides){
        $.twSlideshow.currentSlideNumber = 1;
      }
      else{
        $.twSlideshow.currentSlideNumber += 1;
      }
      methods.goToCurrentSlide();
      if($.twSlideshow.settings.rotate == true){
        methods.reset();
      }
    }

    methods.prev = function(){
      // check to see if # is in range, if so, set $.twSlideshow.currentSlideNumber
      if($.twSlideshow.currentSlideNumber == 1){
        $.twSlideshow.currentSlideNumber = $.twSlideshow.numberOfSlides;
      }
      else{
        $.twSlideshow.currentSlideNumber -= 1;
      }
      methods.goToCurrentSlide();
      if($.twSlideshow.settings.rotate == true){
        methods.reset();
      }
    }
    
    methods.jumpTo = function(slideNum){
      // check to see if # is in range, if so, set $.twSlideshow.currentSlideNumber
      slideNum = parseInt(slideNum);
      if(slideNum >= 0 && slideNum <= $.twSlideshow.numberOfSlides){
        $.twSlideshow.currentSlideNumber = slideNum;
        methods.goToCurrentSlide();
        if($.twSlideshow.settings.rotate == true){
          methods.reset();
        }
      }
    }
    
    methods.goToCurrentSlide = function(){
      var targetLeft = (($.twSlideshow.currentSlideNumber * $.twSlideshow.settings.width) - $.twSlideshow.settings.width) * -1;
      $.twSlideshow.target.animate({'left': targetLeft},$.twSlideshow.settings.animationSpeed,$.twSlideshow.settings.animationType);
      // remove selected class from all jumpTo
      $('.jumpTo').removeClass('selected');
      // add selected class to the current selected slide
      var currentSlideSelector = '[data-slidenum=' + $.twSlideshow.currentSlideNumber + ']';
      $(currentSlideSelector).addClass('selected');
    }
    
    methods.stop = function(){
      clearTimeout($.twSlideshow.timer);
    }
    
    methods.start = function(){
      $.twSlideshow.timer = setTimeout('$.twSlideshow.target.twSlideshow("next");', $.twSlideshow.settings.rotationDelay);
    }
    
    methods.reset = function(){
      methods.stop();
      methods.start();
    }

  

  $.fn.twSlideshow = function(method){
    // Method calling logic
    if(methods[method]){
      return methods[ method ].apply( this, Array.prototype.slice.call( arguments,1));
    }
    else if(typeof method === 'object' || ! method){
      return methods.init.apply( this, arguments );
    }
    else {
      $.error('Method ' +  method + ' does not exist on jQuery.twSlideshow');
    }    
  };
  
  $.fx.prototype.cur = function(){ // we are overwriting this function to remove -10000 limit

    if ( this.elem[this.prop] != null && (!this.elem.style || this.elem.style[this.prop] == null) ) {
      return this.elem[ this.prop ];
    }

    var r = parseFloat( jQuery.css( this.elem, this.prop ) );
    return typeof r == 'undefined' ? 0 : r;
    
  }



})(jQuery);


