(function($) {
  
  var ICastSlider = function(element, options) {
    
    var settings = $.extend({}, $.fn.icastSlider.defaults, options);
    
    var vars = {
      currentSlide: 0,
      currentImg: '',
      totalSlides: 0,
      running: false,
      paused: false,
      stop: false
    }
    
    var slider = $(element);
    slider
      .data('icastSlider:vars', vars)
      .addClass('icast_slider');
    
    var icastSliderDescription = $('<div class="icast_slider_description"><div class="icast_slider_description_close">X</div><div class="icast_slider_description_cwrapper"></div></div>').css({ display: 'none' });
    var icastSliderTitle       = $('<div class="icast_slider_title"></div>').css({ display: 'none' });
    var icastSliderController  = $('<div class="icast_slider_controller"></div>');
    
    slider
      .append(icastSliderController)
      .append(icastSliderDescription)
      .after(icastSliderTitle);
    
    var images = slider.find('img');
    images.each(function() {
      var img = $(this);
      imgWidth = (img.width() != 0) ? img.width() : img.attr('width');
      slider.width(imgWidth);
      imgHeight = (img.height() != 0) ? img.height() : img.attr('height');
      slider.height(imgHeight);
      img.css('display', 'none');
      icastSliderController.append('<a class="icast_slider_control" rel="' + vars.totalSlides + '">' + vars.totalSlides + '</a>');
      vars.totalSlides++;
    });
    
    if (settings.startSlide > 0) {
      if (settings.startSlide >= vars.totalSlides) {
        settings.startSlide = vars.totalSlides - 1;
        vars.currentSlide = settings.startSlide;
      }
    }
    
    vars.currentImage = $(images[vars.currentSlide]);
    
    slider.css('background', 'url("' + vars.currentImage.attr('src') + '") no-repeat');
    icastSliderController.find('a:eq(' + vars.currentSlide + ')').addClass('active');
    
    var processTitle = function(settings) {
      var iTitle = $('.icast_slider_title');
      if (vars.currentImage.attr('title') != '') {
        var title = vars.currentImage.attr('title');
        if (iTitle.css('display') == 'block') {
          iTitle.fadeOut(settings.animSpeed, function() {
            $(this).html(title);
            $(this).fadeIn(settings.animSpeed);
          });
        } else {
          iTitle.html(title);
        }
        iTitle.fadeIn(settings.animSpeed);
      } else {
        iTitle.fadeOut(settings.animSpeed);
      }
    }
    
    var processDescription = function(settings) {
      var iDescription = $('.icast_slider_description');
      if (vars.currentImage.attr('rel') != '') {
        var description = $('#' + vars.currentImage.attr('rel')).html();
        iDescription.find('.icast_slider_description_cwrapper').html(description);
        iDescription.fadeIn(settings.animSpeed);
      }
    }
    
    if (settings.processTitle) {
      processTitle(settings);
    }
    
    if (settings.processDescription) {
      processDescription(settings);
    }
    
    var timer = 0;
    if (!settings.manualAdvance && (images.length > 1)) {
      timer = setInterval(function() {
        icastSliderRun(slider, images, settings, false);
      }, settings.pauseTime);
    }
    
    $('.icast_slider_control').live('click', function() {
      if (vars.running || $(this).hasClass('active')) {
        return false;
      }
      clearInterval(timer);
      timer = '';
      slider.css('background','url("'+ vars.currentImage.attr('src') +'") no-repeat');
      vars.currentSlide = $(this).attr('rel') - 1;
      icastSliderRun(slider, images, settings, 'control');
    });
    
    $(window).keypress(function(event) {
      if (event.keyCode == '37') {
        if (vars.running) {
          return false;
        }
        clearInterval(timer);
        timer = '';
        vars.currentSlide -= 2;
        icastSliderRun(slider, images, settings, 'prev');
      }
      if (event.keyCode == '39') {
        if (vars.running) {
          return false;
        }
        clearInterval(timer);
        timer = '';
        icastSliderRun(slider, images, settings, 'next');
      }
    });
    
    if (settings.pauseOnHover) {
      slider.hover(function() {
        vars.paused = true;
        clearInterval(timer);
        timer = '';
      }, function() {
        vars.paused = false;
        if (timer == '' && !settings.manualAdvance) {
          timer = setInterval(function() {
            icastSliderRun(slider, images, settings, false);
          }, settings.pauseTime);
        }
      });
    }
    
    slider.bind('icastSlider:animFinished', function() {
      vars.running = false;
      if (timer == '' && !vars.paused && !settings.manualAdvance) {
        timer = setInterval(function() {
          icastSliderRun(slider, images, settings, false);
        }, settings.pauseTime);
      }
      settings.afterChange.call(this);
    });
    
    $('.icast_slider_description').live({
      mouseover: function() {
        if ($(this).hasClass('active')) {
          return false;
        }
        $(this).css('background-position', '0 -28px');
      },
      mouseout: function() {
        if ($(this).hasClass('active')) {
          return false;
        }
        $(this).css('background-position', '0 0');
      },
      click: function() {
        if ($(this).hasClass('active')) {
          return false;
        }
        $(this)
          .addClass('active')
          .animate({ width: '400px', height: '200px' }, settings.animSpeed*2, function() {
            $(this)
              .find('.icast_slider_description_cwrapper, .icast_slider_description_close')
              .fadeIn(settings.animSpeed);
          });
        return false;
      }
    });
    
    $('.icast_slider_description_close').live({
      mouseover: function() {
        $(this).css({ 'cursor': 'pointer' });
      },
      mouseout: function() {
        $(this).css({ 'cursor': 'default' });
      },
      click: function() {
        var cwrapper = $(this).parent().find('.icast_slider_description_cwrapper');
        $(this).fadeOut(settings.animSpeed);
        cwrapper.fadeOut(settings.animSpeed).parent().animate({ width: '32px', height: '28px'}, settings.animSpeed*2, function() {
          $(this).removeClass('active').css({ 'background-position': '0 0' });
        });
        return false;
      }
    });
    
    var createSlices = function(slider, settings, vars){
      $('.icast_slider_slice').remove();
      for (var i = 0; i < settings.slices; i++) {
        var sliceWidth = Math.round(slider.width()/settings.slices);
        if (i == settings.slices-1) {
          slider.append(
            $('<div class="icast_slider_slice"></div>').css({ 
              left: (sliceWidth*i)+'px',
              width: (slider.width()-sliceWidth*i)+'px',
              height: '0px', 
              opacity: '0', 
              background: 'url("'+ vars.currentImage.attr('src') +'") no-repeat -'+ ((sliceWidth + (i * sliceWidth)) - sliceWidth) +'px 0%'
            })
          );
        } else {
          slider.append(
            $('<div class="icast_slide_slice"></div>').css({ 
              left: (sliceWidth*i)+'px',
              width: sliceWidth+'px',
              height: '0px', 
              opacity: '0', 
              background: 'url("'+ vars.currentImage.attr('src') +'") no-repeat -'+ ((sliceWidth + (i * sliceWidth)) - sliceWidth) +'px 0%'
            })
          );
        }
      }
    }
    
    var icastSliderRun = function(slider, images, settings, nudge) {
      var vars = slider.data('icastSlider:vars');
      if (vars && (vars.currentSlide == vars.totalSlides - 1)) {
        settings.lastSlide.call(this);
      }
      if ((!vars || vars.stop) && !nudge) {
        return false;
      }
      settings.beforeChange.call(this);
      if(!nudge){
        slider.css('background','url("'+ vars.currentImage.attr('src') +'") no-repeat');
      } else {
        if(nudge == 'prev'){
          slider.css('background','url("'+ vars.currentImage.attr('src') +'") no-repeat');
        }
        if(nudge == 'next'){
          slider.css('background','url("'+ vars.currentImage.attr('src') +'") no-repeat');
        }
      }
      vars.currentSlide++;
      if (vars.currentSlide == vars.totalSlides) {
        vars.currentSlide = 0;
        settings.slideshowEnd.call(this);
      }
      if (vars.currentSlide < 0) {
        vars.currentSlide = vars.totalSlides - 1;
      }
      vars.currentImage = $(images[vars.currentSlide]);
      icastSliderController.find('a').removeClass('active');
      icastSliderController.find('a:eq(' + vars.currentSlide + ')').addClass('active');
      
      processTitle(settings);
      processDescription(settings);
      
      vars.running = true;
      if (settings.effect == 'fade') {
        createSlices(slider, settings, vars);
        $('.icast_slider_slice:first')
          .css({ 'height': '100%', 'width': slider.width() + 'px' })
          .animate({ 'opacity': '1.0' }, settings.animSpeed*2, '', function() {slider.trigger('icastSlider:animFinished')});
      } else if (settings.effect == 'slideInRight') {
        createSlices(slider, settings, vars);
        $('.icast_slider_slice:first')
          .css({ 'height': '100%', 'width': '0px', 'opacity': '1' })
          .animate({ width: slider.width() + 'px' }, settings.animSpeed*2, '', function() {slider.trigger('icastSlider:animFinished')});
      } else if (settings.effect == 'slideInLeft') {
        createSlices(slider, settings, vars);
        $('.icast_slider_slice:first')
          .css({ 'height': '100%', 'width': '0px', 'opacity': '1', 'left': '', 'right': '0px' })
          .animate({ width: slider.width() + 'px' }, settings.animSpeed*2, '', function() {$(this).css({'left': '0px', 'right': ''}); slider.trigger('icastSlider:animFinished')});
      }
    }
    
    settings.afterLoad.call(this);
    
    return this;
    
  }
  
  $.fn.icastSlider = function(options) {
    return this.each(function(key, value){
      if ($(this).data('icastSlider')) return $(this).data('icastSlider');
      $(this).data('icastSlider', new ICastSlider(this, options));
    });
  };
  
  //Default settings
  $.fn.icastSlider.defaults = {
    effect: 'fade',
    slices: 1,
    animSpeed: 500,
    pauseTime: 3000,
    startSlide: 0,
    keyboardNav: true,
    pauseOnHover: true,
    manualAdvance: false,
    processTitle: true,
    processDescription: true,
    beforeChange: function(){},
    afterChange: function(){},
    slideshowEnd: function(){},
        lastSlide: function(){},
        afterLoad: function(){}
  };
  
})(jQuery);

