/**
 * +----------------------------------------------------------+
 * jQuery Presenter Plugin
 * 
 * 
 * @name jquery.presenter.js
 * @version 0.1
 * @author Leonid Lezner <leonid.lezner@shopdienst.com>
 * +----------------------------------------------------------+
 */

(function($) {
   $.fn.presenter = function(options) {
      var opts = $.extend({}, $.fn.presenter.defaults, options);
      var root = this;
      var frames = null;
      var current_frame = 0;
      var last_frame = 0;
      var max_frames = 2;
      var $parent;
      var width = height = 0;

      this.initialize = function() {
         root.$parent.hide();
         
         $presenter = $('<div />', {
            id: 'sd_presenter',
            css: {
               width: width,
               height: height,
               position: 'relative',
               overflow: 'hidden'
            }
         });
         
         root.$parent.after($presenter);
         
         var frames = [];

         for (var id=0; id<max_frames; id++) {         
            frames[id] = $('<div />', {
               id: 'sd_presenter_frame' + id,
               css: {
                  position: 'absolute',
                  width: width,
                  height: height,
                  top: 0,
                  overflow: 'hidden',
                  left: parseInt(width) * id + 'px'
               }
            });

            $presenter.append(frames[id]);
         }
         
         /*$presenter.append($('<h2 />', {
            css: {
               opacity: 0.9
            }
         }));*/
         
         root.frames = frames;
         
         // Initial Content
         frames[current_frame].html(root.$parent.find('li.trail li:first').html());
         //$('#sd_presenter h2').html(root.$parent.find('li.trail h2').html()/* + ' <span>' + root.$parent.find('li.trail li:first img').attr('title') + '</span>'*/);
                  
         /*
         $('#sd_presenter a.control').click(function(e) {
            var direction = e.button ? 'prev' : 'next';
         
            for (var i in frames)
               if(frames[i].is(':animated'))
                  return;

            return false;
         });*/
      }
      
      this.slideOver = function(next_direction) {
         if(next_direction == 'next') {
            // Bring the current frame on top
            root.frameOnTop(true);

            // Slide over
            root.frames[current_frame].css('opacity', 0).animate({
               left: 0,
               opacity: 1
            }, opts.speed, function() {
               root.frames[last_frame].css({left: width});
            });
         } else {
            root.frameOnTop(false);
            root.frames[current_frame].css({left: 0, opacity: 1});
            root.frames[last_frame].animate({
               left: -width,
               opacity: 0
            }, opts.speed, function() {
               root.frames[last_frame].css({left: width});
            });
         }
      }
      
      this.crossFade = function(next_direction) {
         root.frames[current_frame].css({opacity: 0, left: 0});
         root.frames[last_frame].css({opacity: 1, left: 0});
      
         // Bring the current frame on top
         root.frameOnTop(true);

         // Slide over
         root.frames[current_frame].animate({
            opacity: 1
         }, opts.speed, function() {
            root.frames[last_frame].css({left: width});
         });
      }
      
      this.crossSlide = function(next_direction) {
         
         if(next_direction == 'next') {
            // Bring the current frame on top
            root.frameOnTop(false);  
                   
            root.frames[current_frame].css({opacity: 1, left: 0, width: width, height: height});
            
            root.frames[last_frame].css({opacity: 1, left: 0, width: width, height: height});

            // Slide over
            root.frames[last_frame].animate({
               width: 0,
              /* height: 0,*/
               opacity: 0.3
            }, opts.speed, function() {
               root.frames[last_frame].css({left: width});
            });
         } else {
            root.frames[current_frame].css({opacity: 0, left: 0, width: 0});
            root.frames[last_frame].css({opacity: 1, left: 0});
         
            // Bring the current frame on top
            root.frameOnTop(true);

            // Slide over
            root.frames[current_frame].animate({
               width: width,
               opacity: 1
            }, opts.speed, function() {
               root.frames[last_frame].css({left: width});
            });      
         }
      }
      
      
      this.frameOnTop = function(current) {
         if(current) {
            root.frames[current_frame].css('z-index', 1000);
            root.frames[last_frame].css('z-index', 10);
         } else {
            root.frames[current_frame].css('z-index', 10);
            root.frames[last_frame].css('z-index', 1000);
         }
      }
      
      this.showNextFrame = function(next_direction, effect) {      
         switch(effect) {
            case 'slideover':
               root.slideOver(next_direction);
               break;
            
            case 'crossfade':
               root.crossFade(next_direction);
               break;
               
            case 'crossslide':
               root.crossSlide(next_direction);
               break;
            
            default:
               opts.effect(next_direction, root, current_frame, last_frame);             
         }
      }
      
      this.setNextFrame = function(next_direction) {
         last_frame = current_frame;
         
         if(next_direction == 'next')
            current_frame++;
         else
            current_frame--;

         if(current_frame == max_frames)
            current_frame = 0;
         
         if(current_frame < 0)
            current_frame = max_frames - 1;
         
         // Go to the next frame
         if(next_direction == 'next') {
            // Next active li
            $next = root.$parent.find('li.active').removeClass('active').next();

            // No more lis, go to the next parent
            if($next.length == 0){
               $next_trail = root.$parent.find('li.trail').removeClass('trail').next();
               
               if($next_trail.length == 0) {
                  $next_trail = root.$parent.find('> li:first');
               }
               
               $next_trail.addClass('trail');
               
               $next = $next_trail.find('ul > li:first');
            }
         }
         
         // Go to the previous frame
         if(next_direction == 'prev') {
            $next = root.$parent.find('li.active').removeClass('active').prev();

            // No more lis, go to the next parent
            if($next.length == 0) {
               $next_trail = root.$parent.find('li.trail').removeClass('trail').prev();
               
               if($next_trail.length == 0) {
                  $next_trail = root.$parent.find('> li:last');
               }
               
               $next_trail.addClass('trail');
               
               $next = $next_trail.find('ul > li:last');
            }
         }
         
         $next.addClass('active');
         
         root.frames[current_frame].html($next.html());
         //$('#sd_presenter h2').html(root.$parent.find('li.trail h2').html() /*+ ' <span>' + $next.find('img').attr('title') + '</span>'*/);
         
         // Show the next frame
         root.showNextFrame(next_direction, opts.effect);
      }

      return this.each(function() {
         var $$ = $(this);
         var image_count = $$.find('li.trail ul li').length;
         var timer = null;
         
         root.$parent = $$;
         
         width = $$.width()/* - parseInt($$.css('border-width'))*/;
         height = $$.height();
         
         root.initialize();
         
         var $images = $$.find('img');
         var images_to_load = $images.length;
         
         $images.each(function(){
            // Waiting for images to load...
            //console.log($(this).attr('src'));
            
            var onload = function() {
               images_to_load--;

               if(images_to_load == 0 && !timer){
                  // Set up timer
                  timer = setInterval(function(){
                     root.setNextFrame('next');
                     
                  }, opts.interval);
               }
               
               // TODO: Show the controls now
            }
            
            var src = this.src;
            this.src = src;
            
            if(this.hasOwnProperty && this.hasOwnProperty('complete') && this['complete'])
               onload();
            else
               $(this).load(onload());
             
            //.attr('src', $(this).attr('src')); // Setting the src manually for IE
            
         });
      });
   };
   
   // default options
   $.fn.presenter.defaults = {
      interval: 6000,
      speed: 1500,
      effect: 'crossfade'
   };
})(jQuery);
