(function($){
  
  $.fn.imagecycle = function(options){
  
    return this.each(function(){
  	 
      var settings = {
        speed: 800,
        firedspeed: 500,
        interval: 5000,
        paused: false,
        textclass: 'div.image_cycle_content',
        textparent: 'div#image_cycle_back'
      };
      
      // extends settings with options
      $.extend(settings, options); 
      
      // cache this
      var $this = $(this);
      // get the images and count em
      var images = $this.find('img');
      var imagesLength = images.length;
      var $imagesFired = $('div#image_cycle_status li.fired');
      var $imagesSwitchers = $('div#image_cycle_status li:not(.fired)');
      var $textBlocks = $(settings.textclass);
      
      // fix height
      $(settings.textparent).css({
        'height': parseInt($($textBlocks[0]).height()) + 60 + 'px'
      });
      
      // only start cycling with 2 images minimum
      if(imagesLength < 2)
      {
        // hide switchers and fired for one or zero images
        $imagesFired.add($imagesSwitchers).hide();
        return false;
      }
      
      // now loop through the images and set z-index and position
      for(var i=0;i<imagesLength;i++)
      {
        $(images[i]).css({
          'z-index' : (imagesLength-i),
          'position' : 'absolute'
        });
      }
      
      // bind pause to mouseover event and unpause on onmouseout
      $this.mouseover(function(){
        settings['paused'] = true;
      }).mouseout(function(){
        settings['paused'] = false;
      });
      
      // the cycle function will be recursively calling itself
      setTimeout(function(){
        $.imagecycle.cycle(images,$textBlocks,imagesLength,settings,1,0,$imagesFired)
        $.imagecycle.move($imagesFired,1,settings);
      },settings.interval);
    });
  };
  
  $.imagecycle = function(){
    // just init
  },
  $.imagecycle.move = function($obj,to,settings){
    // if cycle isnt paused move to (to * 20)
    if(settings['paused'] === false)
    {
      $obj.animate({
        'left': (to * 20)
      },settings.firedspeed);
    }
  },
  $.imagecycle.cycle = function(images,textBlocks,imagesLength,settings,current,last,imagesfired){
    // the core function
    // if cycle isnt paused 
    // lets do some fading and math
    if(settings['paused'] === false)
    {
      // fade out the last image with his textblock and fade in the next one 
      $(images[last]).add(textBlocks[last]).fadeOut(settings.speed);
      $(images[current]).add(textBlocks[current]).fadeIn(settings.speed);
      
      // animate the height changes
      $(settings.textparent).animate({
        'height': $(textBlocks[current]).height() + 60 + 'px'
      },400);
      
      // determine the last and current index
      if((current+1) < imagesLength)
      {
        current += 1;
        last = current-1;
      } 
      else 
      {
        current = 0;
        last = imagesLength-1;
      }
    }
    
    // the core timeout which will be called in loop as the cycle function is called recursively
    setTimeout(function(){
      $.imagecycle.cycle(images,textBlocks,imagesLength,settings,current,last,imagesfired);
      $.imagecycle.move(imagesfired,current,settings);
    },settings.interval);
  };
})(jQuery);
